{"id":"d6a209e6-3cb3-4640-adc3-4b65c5a9342e","entityType":"agent","slug":"clawhub-roelbroersma-marktplaats-publisher","name":"Marktplaats","canonicalUrl":"https://www.xpersona.co/agent/clawhub-roelbroersma-marktplaats-publisher","canonicalPath":"/agent/clawhub-roelbroersma-marktplaats-publisher","generatedAt":"2026-10-10T08:53:01.571Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T04:19:36.738Z","emptyReason":null},"description":"Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register. Skill: Marktplaats Owner: roelbroersma Summary: Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register. Tags: latest:0.6.3 Version history: v0.6.3 | 2026-07-09T10:16:48.409Z | user Improve GPT-4.5 mini setup gates and add background-safe Safari probing. v0.6.2 | 2026-07-08T23:55:29.396Z | user Correct 0.6.1 workshop-body publish and ship the actual Marktplaats pipel","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.7K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s179htxd8rt3fvp5g4qqbbbbrh882z0p:marktplaats-publisher","sourceUrl":"https://clawhub.ai/roelbroersma/marktplaats-publisher","homepage":"https://clawhub.ai/roelbroersma/skills/marktplaats-publisher","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/roelbroersma/marktplaats-publisher","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/roelbroersma/skills/marktplaats-publisher","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":65,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register. Skill: Marktplaats Owner: roelbroersma Summary: Mark"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T04:19:36.738Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T04:19:36.738Z","emptyReason":null},"stars":null,"forks":null,"downloads":1693,"packageName":null,"latestVersion":"0.6.3","tractionLabel":"1.7K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T04:19:36.738Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T04:19:36.738Z","lastCrawledAt":"2026-10-10T04:19:36.738Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T04:19:36.738Z","lastVerifiedAt":null,"highlights":[{"version":"0.6.3","createdAt":"2026-07-09T10:16:48.409Z","changelog":"Improve GPT-4.5 mini setup gates and add background-safe Safari probing.","fileCount":19,"zipByteSize":56151},{"version":"0.6.2","createdAt":"2026-07-08T23:55:29.396Z","changelog":"Correct 0.6.1 workshop-body publish and ship the actual Marktplaats pipeline: mini-model-safe gates, packaged references, background Safari probe, stricter live/register verification, and safer probe defaults.","fileCount":17,"zipByteSize":51342},{"version":"0.6.1","createdAt":"2026-07-08T23:53:26.812Z","changelog":"Tighten Marktplaats publish gates for smaller models: validator-clean frontmatter, packaged references, background Safari probe, stricter live/register verification, safer curl probe defaults, and clearer README/workflow guidance.","fileCount":17,"zipByteSize":48886},{"version":"0.6.0","createdAt":"2026-06-08T17:59:11.440Z","changelog":"Maak workflow scriptmatig: kortere SKILL.md, correcte skill identity, preflight/live-verify/register-update gates, copy-QA hashes en register lock.","fileCount":17,"zipByteSize":45810},{"version":"0.5.1","createdAt":"2026-06-08T16:04:05.077Z","changelog":"README herschreven in gewone mensentaal; pakketomschrijving verduidelijkt.","fileCount":14,"zipByteSize":43710},{"version":"0.5.0","createdAt":"2026-06-08T15:32:23.019Z","changelog":"Add hard Copy Quality Gate: enforce 3200-3500 character SEO descriptions, block keyword dumps, require natural product terms and typo/search variant, store copyQuality evidence in ad.json, sanitize form probe snapshots, and update docs/tests.","fileCount":14,"zipByteSize":43558},{"version":"0.4.4","createdAt":"2026-06-05T23:10:41.755Z","changelog":"Rename public slug/package from marktplaats-nl-publisher to marktplaats-publisher and update import examples.","fileCount":10,"zipByteSize":29647}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s179htxd8rt3fvp5g4qqbbbbrh882z0p:marktplaats-publisher","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T08:53:01.567Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-roelbroersma-marktplaats-publisher/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T04:19:36.738Z","emptyReason":null},"readme":"Skill: Marktplaats\n\nOwner: roelbroersma\n\nSummary: Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register.\n\nTags: latest:0.6.3\n\nVersion history:\n\nv0.6.3 | 2026-07-09T10:16:48.409Z | user\n\nImprove GPT-4.5 mini setup gates and add background-safe Safari probing.\n\nv0.6.2 | 2026-07-08T23:55:29.396Z | user\n\nCorrect 0.6.1 workshop-body publish and ship the actual Marktplaats pipeline: mini-model-safe gates, packaged references, background Safari probe, stricter live/register verification, and safer probe defaults.\n\nv0.6.1 | 2026-07-08T23:53:26.812Z | user\n\nTighten Marktplaats publish gates for smaller models: validator-clean frontmatter, packaged references, background Safari probe, stricter live/register verification, safer curl probe defaults, and clearer README/workflow guidance.\n\nv0.6.0 | 2026-06-08T17:59:11.440Z | user\n\nMaak workflow scriptmatig: kortere SKILL.md, correcte skill identity, preflight/live-verify/register-update gates, copy-QA hashes en register lock.\n\nv0.5.1 | 2026-06-08T16:04:05.077Z | user\n\nREADME herschreven in gewone mensentaal; pakketomschrijving verduidelijkt.\n\nv0.5.0 | 2026-06-08T15:32:23.019Z | user\n\nAdd hard Copy Quality Gate: enforce 3200-3500 character SEO descriptions, block keyword dumps, require natural product terms and typo/search variant, store copyQuality evidence in ad.json, sanitize form probe snapshots, and update docs/tests.\n\nv0.4.4 | 2026-06-05T23:10:41.755Z | user\n\nRename public slug/package from marktplaats-nl-publisher to marktplaats-publisher and update import examples.\n\nArchive index:\n\nArchive v0.6.3: 19 files, 56151 bytes\n\nFiles: _meta.json (140b), bin/marktplaats-categories.js (2982b), bin/marktplaats-search.js (8020b), package.json (1504b), README.md (8420b), references/background-safari-nl.md (2125b), references/guide-en.md (10445b), references/handleiding-nl.md (11603b), references/robust-posting-checklist.md (1214b), references/setup-small-model-nl.md (3302b), scripts/marktplaats-ad-preflight.js (12971b), scripts/marktplaats-copy-qa.js (14188b), scripts/marktplaats-live-verify.js (17066b), scripts/marktplaats-place-probe.js (21905b), scripts/marktplaats-register-update.js (9233b), skill-card.md (2236b), SKILL.md (11256b), src/api.js (14739b), src/index.js (160b)\n\nFile v0.6.3:SKILL.md\n\n---\nname: \"marktplaats-publisher\"\ndescription: \"Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register.\"\nmetadata: {\"clawdbot\":{\"emoji\":\"🇳🇱\",\"requires\":{\"bins\":[\"node\"]}}}\n---\n\n# Marktplaats Publisher\n\nGebruik deze skill voor normale Marktplaats-advertenties: voorbereiden, plaatsen, bewerken, live controleren en lokaal registreren.\n\nDe workflow is command-first. Proceduretekst is alleen toelichting. Als een gate faalt, stop je.\n\nVoor kleinere modellen: doe steeds een fase, lees de output, en ga pas door als de vorige fase aantoonbaar geslaagd is. De scripts zijn harde gates; publiceren en UI-invulwerk blijven browserwerk met verificatie, geen blinde submit-flow.\n\n## Setup En Modelmodus\n\nAls de taak installatie, eerste setup of herstel van de skill is, laad `references/setup-small-model-nl.md`.\n\nPackage-identiteit:\n\n- correcte skill/package: `marktplaats-publisher`;\n- oude namen zoals `marktplaats`, `marktplaats-nl-publisher` of `pvoo/marktplaats` zijn niet de doel-skill;\n- vereiste runtime: Node.js 18 of nieuwer;\n- vereiste smoke-test: `npm test` vanuit de skillmap.\n\nVoor lichte modellen zoals GPT-4.5 mini of de lokaal beschikbare mini-route geldt dit contract:\n\n- voer steeds precies een gate uit;\n- lees de output volledig;\n- ga alleen door bij expliciet `PASS`, `self-test ok` of exitcode 0 met verwachte output;\n- bij failure: repareer een oorzaak, draai dezelfde gate opnieuw, maximaal twee herstelpogingen per foutklasse;\n- publiceer, bewerk of submit niets als setup, copy-QA, preflight of probe niet aantoonbaar groen is;\n- houd per advertentie een klein statusblok bij met `adDir`, `adJson`, `description`, `currentGate`, `lastCommand`, `result` en `nextStep`.\n\nAls globale CLI-commando's ontbreken, gebruik vanaf de skillmap de directe fallback:\n\n```bash\nnode ./scripts/marktplaats-place-probe.js --self-test\nnode ./scripts/marktplaats-copy-qa.js --self-test\nnode ./scripts/marktplaats-ad-preflight.js --self-test\nnode ./scripts/marktplaats-live-verify.js --self-test\nnode ./scripts/marktplaats-register-update.js --self-test\n```\n\n## Harde Regels\n\n- Geen publicatie of inhoudelijke bewerking zonder expliciete opdracht voor die advertentie.\n- Geen betaalde opties, bundels, promoties of betaalflow zonder expliciet akkoord.\n- Geen cookies, sessietokens, XSRF/auth-waarden, klantdata of lokale privepaden loggen of publiceren.\n- Geen captcha, MFA, login challenge, WAF of accountbeveiliging omzeilen.\n- Geen tekst plaatsen als copy-QA of preflight faalt.\n- Gebruik `--allow-*` opties alleen bij expliciete, taak-specifieke uitzondering van de gebruiker.\n- Publiceerbare advertentietekst mag nooit websiteadressen of domeinachtige tekst bevatten. Verboden zijn onder andere `http://`, `https://`, `www.`, e-mailadressen en woorden met bekende domeinextensies zoals `.com`, `.nl`, `.eu`, `.org`, `.net`, `.de`, `.be` en `.io`. Merknamen met een domeinextensie, zoals `StarTech.com`, moeten worden herschreven naar een gewone merknaam zonder punt, bijvoorbeeld `StarTech`.\n- Publiceer of accepteer geen advertentie waarvan de live omschrijving als een grote lap tekst verschijnt. De lokaal geschreven alinea's moeten live aantoonbaar bewaard blijven via alinea's, `<br>`-achtige regelovergangen of Marktplaats-blokken.\n- Na opslaan altijd live verifieren en het lokale register bijwerken.\n- Bij UI-drift, browser-hang of onduidelijke formulierstatus: stop, maak een snapshot en rapporteer de blokkade.\n\n## Safari Rustig Gebruiken\n\nLaad `references/background-safari-nl.md` bij plaats-/bewerkwerk met Safari.\n\nVoorkeursvolgorde:\n\n1. Gebruik gewone HTTP/API/zoek-CLI waar geen login nodig is.\n2. Gebruik `marktplaats-place-probe --browser-fetch --url ...` voor authenticated inspectie zonder zichtbare navigatie.\n3. Gebruik `marktplaats-place-probe --browser --open-background ...` om een pagina in Safari te openen zonder Safari actief te maken.\n4. Gebruik zichtbare UI alleen als foto-upload, contenteditable tekst of expliciete controle dat vereist.\n\nRegels:\n\n- activeer Safari niet onnodig en open geen extra schermen bovenop het werk van de gebruiker;\n- gebruik een bestaande of dedicated Marktplaats-tab; kies tabs op URL/ad-id, niet op schermpositie;\n- herstel of laat de actieve gebruikerscontext ongemoeid waar mogelijk;\n- log geen cookies, tokens, XSRF-waarden, contactgegevens of browserprofielinformatie;\n- bij login/captcha/MFA/WAF, betaalroute, UI-drift of onduidelijke status: stop, schrijf een snapshot en rapporteer.\n\n## Lokale Bestanden\n\nWerk per advertentie in:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<slug>/photos/\n```\n\nCentraal register:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\n`ad.json` moet minimaal bevatten: titel, prijs, conditie, levering, categorie/categoryIds, `biddingAllowed`, `descriptionFile`, `imageDir` of foto's, URL/adId zodra live, en `copyQuality`.\n\n## Verplichte Pipeline\n\n### 1. Schrijf De Omschrijving\n\nSchrijf een feitelijke Nederlandse tekst van ongeveer 3200-3500 tekens.\n\nMoet bevatten:\n\n- merk/model of herkenbare productnaam;\n- productsoort;\n- staat/conditie en wat wel/niet getest is;\n- concrete zichtbare kenmerken;\n- toepassing en compatibiliteit;\n- ophalen/verzenden, prijs en bieden;\n- natuurlijke zoekvarianten in gewone zinnen;\n- minimaal een, en bij voorkeur niet meer dan twee, subtiele productrelevante typefout-/schrijfvarianten in gewone zinnen. Voorbeeld: `buiten antenne` naast `buitenantenne`.\n\nNiet doen:\n\n- geen websiteadressen, domeinachtige merknamen, `www.`-tekst, URL's of e-mailadressen;\n- geen `Zoektermen:`, `Keywords:` of `SEO:` footer;\n- geen lange comma-keyworddump;\n- geen claims over werking, garantie of compleetheid zonder bewijs.\n\n### 2. Copy-QA\n\nAltijd draaien voordat Marktplaats wordt ingevuld of opgeslagen:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<merk-of-model>\" \\\n  --require \"<productsoort>\" \\\n  --variant \"<natuurlijke zoekvariant>\" \\\n  --ad-json ./ad.json\n```\n\nStop als dit geen `PASS` geeft. De command schrijft `copyQuality` inclusief `descriptionSha256` naar `ad.json`.\n\nHerhaal `--variant` alleen voor een tweede minimale variant als die natuurlijk in de omschrijving past. Gebruik geen losse typefoutenlijst.\n\nCopy-QA faalt bij URL's, `www.`-tekst, e-mailadressen en domeinachtige tekst zoals `startech.com`, ook als er geen protocol voor staat.\n\n### 3. Preflight\n\nAltijd draaien na copy-QA en voor browser/UI-werk:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nGebruik `--require-bidding-allowed` wanneer bieden aan moet staan. Stop bij failure.\n\nPreflight controleert onder andere:\n\n- verplichte advertentievelden;\n- omschrijving bestaat en is niet gewijzigd na copy-QA;\n- copy-QA is geslaagd;\n- publiceerbare advertentietekst bevat geen URL's, `www.`-tekst, e-mailadressen of domeinachtige tekst;\n- foto's bestaan;\n- biedeninstelling indien vereist.\n\n### 4. Formulier Probe\n\nInspecteer Marktplaats voordat je invult. Kies de minst storende route die genoeg bewijs geeft.\n\nMet browser-fetch:\n\n```bash\nmarktplaats-place-probe --browser-fetch --url \"https://www.marktplaats.nl/plaats/...\" --save ./snapshot-place.json\n```\n\nAls Safari niet de actieve app hoeft te worden, open de plaatsingspagina op de achtergrond en probe daarna dezelfde Safari-context:\n\n```bash\nmarktplaats-place-probe --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save ./snapshot-place.json\n```\n\nAls de juiste Marktplaats-tab al open staat:\n\n```bash\nmarktplaats-place-probe --browser --save ./snapshot-place.json\n```\n\nStop als:\n\n- login/captcha/MFA/WAF verschijnt;\n- betaalde route verplicht lijkt;\n- formulierstructuur onduidelijk is;\n- foto-upload of bundelkeuze niet te verifieren is;\n- `security.challengeSignals` login, captcha, MFA, WAF of betaal-/promotiesignalen toont.\n\n### 5. Plaats Of Bewerk\n\nVul Marktplaats pas na groene copy-QA en preflight.\n\nControleer voor submit/save:\n\n- titel;\n- prijs;\n- bieden toegestaan indien gevraagd;\n- conditie;\n- levering;\n- foto-aantal;\n- gratis/basic route;\n- laatste zin van de omschrijving zichtbaar in het formulier;\n- alinea's zichtbaar in het omschrijvingsveld; gebruik bij voorkeur het zichtbare rich-text/contenteditable veld en geen directe hidden-field submit voor de omschrijving.\n\nGebruik geen blinde coordinate-clicks. Gebruik DOM/events of een expliciet UI-element met verificatie voor en na.\n\nGebruik geen directe hidden-field submit of platte `URLSearchParams`-post voor de omschrijving tenzij live-verificatie daarna bewijst dat alinea's bewaard zijn. Als Marktplaats de tekst ondanks correcte inhoud als een doorlopende lap toont, is de advertentie niet klaar.\n\n### 6. Live Verify\n\nNa opslaan of plaatsen moet de live advertentie gecontroleerd worden.\n\nAls fetch genoeg tekst bevat:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --url \"https://www.marktplaats.nl/seller/view/...\" --update-ad-json\n```\n\nAls de pagina dynamisch is, sla eerst zichtbare/live tekst op en verifieer die:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --text ./live-text.txt --update-ad-json\n```\n\nStop als:\n\n- begin van de omschrijving ontbreekt;\n- laatste zin ontbreekt;\n- omschrijving dubbel staat;\n- `Zoektermen:` of keyworddump live zichtbaar is;\n- live advertentietekst alsnog websiteadressen of domeinachtige tekst bevat;\n- live omschrijving geen aantoonbare alinea-/regelstructuur heeft.\n\n### 7. Register Update\n\nWerk na live verificatie het centrale register bij:\n\n```bash\nmarktplaats-register-update \\\n  --ad-json ./ad.json \\\n  --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json \\\n  --note \"Live gecontroleerd na plaatsing/bewerking.\"\n```\n\nRun register-updates sequentieel. Het script gebruikt een lock en faalt als een tweede update tegelijk hetzelfde centrale register probeert te schrijven.\n\nDe register-update hoort standaard te falen als live-verificatie ontbreekt of faalde. Gebruik `--allow-unverified` alleen voor niet-gepubliceerde conceptadministratie en vermeld waarom in `--note`.\n\n## Bestaande Advertentie Bewerken\n\nVoor elke inhoudelijke tekstbewerking geldt dezelfde pipeline:\n\n```bash\nmarktplaats-copy-qa ./description.md --require \"<term1>\" --require \"<term2>\" --variant \"<variant>\" --ad-json ./ad.json\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n# bewerk via Marktplaats UI/DOM\nmarktplaats-live-verify --ad-json ./ad.json --url \"<live-url>\" --update-ad-json\nmarktplaats-register-update --ad-json ./ad.json --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nAls live fetch de tekst niet ziet, gebruik `--text ./live-text.txt` met tekst uit de browser/accessibility snapshot.\n\n## Test De Skill\n\n```bash\nnpm test\n```\n\nDeze test moet groen zijn voordat je publiceert naar ClawHub.\n\n## Naslag\n\n- Publieke uitleg: `README.md`\n- Langere handleiding: `references/handleiding-nl.md`\n- Engelse guide: `references/guide-en.md`\n- Robuuste checklist: `references/robust-posting-checklist.md`\n- Setup voor kleine modellen: `references/setup-small-model-nl.md`\n- Rustige Safari/background-flow: `references/background-safari-nl.md`\n\nFile v0.6.3:README.md\n\n# Marktplaats.nl Verkoopassistent\n\nDeze skill helpt je om een Marktplaats-advertentie netjes voor te bereiden, te plaatsen en achteraf te controleren.\n\nHet belangrijkste doel is simpel: een goede advertentie maken zonder half werk, zonder betaalde opties per ongeluk aan te zetten en zonder dat de tekst weer te kort, kaal of spammerig wordt.\n\nVanaf versie 0.6.0 is dit vooral een scriptmatige pipeline. De assistent krijgt dus niet alleen lange instructies, maar moet door harde checks heen: copy-QA, preflight, live-verificatie en register-update.\n\n## Wat doet deze skill?\n\n- Zoekt mee naar categorieën en vergelijkbare advertenties.\n- Helpt productinformatie te verwerken zonder dingen te verzinnen.\n- Schrijft een volle Nederlandse advertentietekst van ongeveer 3200 tot 3500 tekens.\n- Controleert de tekst voordat Marktplaats wordt ingevuld.\n- Werkt met een bestaande ingelogde Safari-sessie op macOS.\n- Begeleidt en controleert foto-upload via de normale Marktplaats-flow.\n- Houdt betaalde promoties standaard uit.\n- Controleert na het plaatsen of de advertentie echt live goed staat.\n- Bewaart lokaal wat er geplaatst is, inclusief tekstcheck en live controle.\n\nDeze skill is bedoeld voor normale verkoopadvertenties. Niet voor bulkposten, omzeilen van beveiliging, captcha's, loginproblemen of betaalflows.\n\n## Waarom is die tekstcheck zo streng?\n\nOmdat korte advertenties steeds terugkwamen als probleem.\n\nEen advertentie van een paar regels is snel gemaakt, maar meestal slecht vindbaar. Daarom zit er een harde controle in: de tekst moet lang genoeg zijn, genoeg inhoud hebben, natuurlijke zoekwoorden bevatten en geen los blok met `Zoektermen:` of keywordspam onderaan zetten.\n\nDe standaard is:\n\n- ongeveer 3200 tot 3500 tekens;\n- minimaal 7 duidelijke alinea's of onderdelen;\n- merk/model en productsoort moeten erin staan;\n- minimaal één kleine natuurlijke typefout/schrijfvariant in context, zoals `deur slot` of `buiten antenne`;\n- geen losse zoekwoordenlijst;\n- de laatste zin moet ook live zichtbaar zijn na opslaan.\n\nAls die check faalt, moet de advertentie eerst beter worden. Niet toch maar plaatsen.\n\n## Copy check draaien\n\nGebruik dit voordat je Marktplaats opent of een bestaande advertentie opslaat:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"KFV\" \\\n  --require \"motorslot\" \\\n  --variant \"deur slot\" \\\n  --ad-json ./ad.json\n```\n\nDe check schrijft het resultaat in `ad.json`. Alleen als `copyQuality.passed` op `true` staat, mag de tekst door naar Marktplaats.\nWil je twee minimale varianten afdwingen, herhaal dan `--variant` en gebruik `--min-variants 2`.\n\nVoor een snelle test van de tool zelf:\n\n```bash\nmarktplaats-copy-qa --self-test\n```\n\n## Preflight voor het plaatsen\n\nNa de copy check moet de advertentie door preflight:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nDeze check kijkt of `ad.json`, de omschrijving, foto's, bieden-instelling en copy-QA bij elkaar passen. Als de omschrijving na de copy check nog is aangepast, faalt preflight op de tekst-hash.\n\n## Live controleren na opslaan\n\nNa plaatsen of bewerken moet de live advertentie worden gecontroleerd:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --url \"https://www.marktplaats.nl/seller/view/...\" --update-ad-json\n```\n\nAls Marktplaats de tekst niet goed in de HTML meestuurt, gebruik je tekst uit de browser:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --text ./live-text.txt --update-ad-json\n```\n\nDeze check faalt als het begin van de omschrijving ontbreekt, de laatste zin ontbreekt, de tekst dubbel staat, alinea's live niet herkenbaar zijn, er toch een `Zoektermen:` blok zichtbaar is, of de live omschrijvingswindow domeinachtige tekst bevat.\n\n## Register bijwerken\n\nDaarna werk je het centrale register bij:\n\n```bash\nmarktplaats-register-update \\\n  --ad-json ./ad.json \\\n  --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json \\\n  --note \"Live gecontroleerd.\"\n```\n\nVoer register-updates niet parallel uit op hetzelfde bestand. De tool gebruikt een lock en stopt als er al een update loopt.\nStandaard weigert deze stap advertenties zonder geslaagde live-verificatie. Gebruik `--allow-unverified` alleen voor conceptadministratie.\n\n## Advertentie voorbereiden\n\nEen praktische map per advertentie werkt het prettigst:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/photos/\n```\n\nZet in `ad.json` in elk geval titel, prijs, categorie, foto's, status, live URL en het resultaat van de copy check. Zo kun je later terugvinden wat er is geplaatst en wanneer het live gecontroleerd is.\n\n## Plaatsen of bewerken\n\nDe normale volgorde:\n\n1. Maak lokaal titel, prijs, foto's en omschrijving klaar.\n2. Zoek productinformatie op als merk of model bekend is.\n3. Schrijf de omschrijving rijk, feitelijk en verkoopbaar.\n4. Draai `marktplaats-copy-qa`.\n5. Draai `marktplaats-ad-preflight`.\n6. Stop als een van de checks niet slaagt.\n7. Open pas daarna de Marktplaats plaats- of bewerkpagina.\n8. Controleer dat de gratis/basic route actief is.\n9. Upload foto's en controleer de fototeller.\n10. Controleer titel, prijs, bieden, foto's en laatste zin van de omschrijving.\n11. Sla op of plaats pas als de gebruiker daar opdracht voor gaf.\n12. Draai `marktplaats-live-verify`.\n13. Draai `marktplaats-register-update`.\n\nVoor kleinere modellen geldt: één stap uitvoeren, output lezen, dan pas de volgende stap. Geen coördinatenkliks, geen verborgen submit en geen betaal-/promotieroute zonder expliciet akkoord.\n\n## Gratis blijft gratis\n\nDeze skill kiest standaard geen betaalde opties.\n\nAls Marktplaats een betaalde promotie, topadvertentie, urgent-optie, bundel of betaalpagina toont, is dat een stopmoment. Alleen doorgaan als de gebruiker voor die specifieke advertentie expliciet zegt dat een betaalde optie mag.\n\n## Safari en privacy\n\nVoor echt plaatsen of bewerken gebruikt de skill een bestaande ingelogde Safari-sessie. Dat is handig, maar privacygevoelig.\n\nDaarom:\n\n- geen cookies printen;\n- geen sessietokens opslaan;\n- geen XSRF/auth-waarden loggen;\n- geen lokale privébestanden of advertentie-id's in voorbeelden zetten;\n- geen koperberichten sturen zonder aparte toestemming.\n\nDe browser mag als veilige sessiecontext gebruikt worden. De sessie zelf mag niet worden gelekt.\n\nWerk background-first: browser-fetch en `--open-background` gaan voor zichtbare UI. Safari mag als sessiedrager dienen, maar de gebruiker mag niet onnodig uit de actieve app of tab worden getrokken.\n\n## Zoek- en categoriehulpen\n\nZoeken:\n\n```bash\nmarktplaats-search \"4G antenne\"\n```\n\nCategorieën:\n\n```bash\nmarktplaats-categories\nmarktplaats-categories <parent-id>\n```\n\nFormulier inspecteren via de ingelogde browsercontext:\n\n```bash\nmarktplaats-place-probe --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nPlaatsingspagina rustig in Safari op de achtergrond openen en daarna proben:\n\n```bash\nmarktplaats-place-probe --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\n## Installeren en testen\n\nNode.js 18 of nieuwer is nodig.\n\nControleer eerst dat je de juiste package hebt:\n\n```bash\nnode -p \"require('./package.json').name + '@' + require('./package.json').version\"\n```\n\nVerwachte package: `marktplaats-publisher`.\n\nInstalleer de CLI's vanuit de skillmap:\n\n```bash\nnpm install -g .\nnpm test\n```\n\nAls globale commands niet beschikbaar zijn, gebruik de directe fallback vanuit de skillmap:\n\n```bash\nnode ./bin/marktplaats-search.js --help\nnode ./bin/marktplaats-categories.js --help\nnode ./scripts/marktplaats-place-probe.js --self-test\nnode ./scripts/marktplaats-copy-qa.js --self-test\nnode ./scripts/marktplaats-ad-preflight.js --self-test\nnode ./scripts/marktplaats-live-verify.js --self-test\nnode ./scripts/marktplaats-register-update.js --self-test\n```\n\nEen licht model mag setup pas als geslaagd zien wanneer `npm test` groen is of alle directe self-tests groen zijn.\n\n## Wat deze skill niet doet\n\n- Geen bulkplaatsingen.\n- Geen captcha's of loginbeveiliging omzeilen.\n- Geen betaalde opties stil aanzetten.\n- Geen garanties verzinnen over werking, compleetheid of accessoires.\n- Geen privédata publiceren.\n- Geen berichten naar kopers sturen zonder expliciete toestemming.\n\n## Licentie\n\nMIT\n\nFile v0.6.3:_meta.json\n\n{\n  \"ownerId\": \"kn7ewt9n4xqy7yhf2bnykj7ssh882qa4\",\n  \"slug\": \"marktplaats-publisher\",\n  \"version\": \"0.6.3\",\n  \"publishedAt\": 1783592208409\n}\n\nFile v0.6.3:references/background-safari-nl.md\n\n# Rustige Safari En Background-Flow\n\nGebruik deze reference wanneer `marktplaats-publisher` een ingelogde Safari-context nodig heeft voor formulierinspectie, foto-upload of live controle.\n\n## Doel\n\nGebruik Safari als sessiedrager zonder de gebruiker onnodig te storen. Background-first betekent: geen vensters naar voren halen, geen coordinate-clicks en geen zichtbare UI tenzij de Marktplaats-flow dat echt vereist.\n\n## Voorkeursvolgorde\n\n1. Gebruik gewone HTTP/API/zoek-CLI voor publieke informatie.\n2. Gebruik `marktplaats-place-probe --browser-fetch --url ...` voor authenticated HTML/formulierinspectie vanuit Safari-context.\n3. Gebruik `marktplaats-place-probe --browser --open-background ...` om een plaatsings- of bewerkpagina in Safari te openen zonder Safari te activeren.\n4. Gebruik zichtbare UI alleen voor stappen die niet betrouwbaar via DOM/fetch kunnen: foto-upload, contenteditable tekstcontrole of expliciete visuele bevestiging.\n\n## Niet Storen-Regels\n\n- Activeer Safari niet wanneer background-probe of browser-fetch voldoende is.\n- Open geen extra vensters of schermen bovenop het werk van de gebruiker.\n- Kies Safari-tabs/documenten op URL, categoriepad of advertentie-id, niet op schermpositie.\n- Laat de gebruiker zijn actieve app en tab houden waar dat kan.\n- Gebruik snapshots in `housekeeping/marktplaats-snapshots/` voor bewijs en debugging.\n- Bij foreground UI: meld kort waarom foreground nodig is en doe zo weinig mogelijk.\n\n## Privacyregels\n\n- Cookies, sessietokens, XSRF/auth-waarden, contactgegevens en browserprofielinformatie nooit printen of opslaan.\n- Safari mag credentials gebruiken via normale browsercontext, maar de skill mag die credentials niet exporteren.\n- Geen Marktplaats-wachtwoorden vragen of opslaan.\n\n## Stopmomenten\n\nStop en rapporteer bij:\n\n- login/captcha/MFA/WAF;\n- betaalpagina of promotieroute;\n- onduidelijke formulierstructuur;\n- foto-upload of fototeller die niet te verifieren is;\n- Safari-hang of browser-UI die niet betrouwbaar te herstellen is.\n\nBij een vastgelopen automationproces: stop alleen het vastzittende helperproces waar mogelijk, niet heel Safari.\n\nFile v0.6.3:references/guide-en.md\n\n# Marktplaats Seller Assistant - English Guide\n\n## Name\n\n**Marktplaats Seller Assistant**\n\nTechnical skill key: `marktplaats-publisher`.\n\nThe name is intentionally broader than search. The skill supports the selling workflow: category selection, live field inspection, photo preparation/upload, local ad tracking, repost preparation, dry-run review, and publishing only after explicit confirmation.\n\n## Purpose\n\nThis skill helps an agent prepare, place, track and later repost Marktplaats advertisements safely and reliably. Its main value is that it inspects the current category-specific placement form before filling or submitting anything, then stores enough local metadata to revisit the ad later.\n\n## Capabilities\n\n- Search Marktplaats listings.\n- Fetch category and subcategory information.\n- Suggest the best category for an item.\n- Inspect the live placement form in a logged-in browser session.\n- Extract category-specific fields such as condition, brand, type, delivery, price and options.\n- Prepare resized, metadata-reduced photo copies where possible.\n- Guide and verify photo upload through the logged-in browser context.\n- Fill advertisement fields conservatively.\n- Keep paid features disabled by default.\n- Present a dry-run summary.\n- Publish only after explicit approval for that exact advertisement.\n- Report the success URL or validation errors after submission.\n- Track posted advertisements locally.\n- Mark expired or removed advertisements for reposting.\n- Use photos and short item descriptions from WhatsApp/iMessage as ad intake when the user asks.\n- Validate listing descriptions with the hard Copy Quality Gate before filling or publishing Marktplaats.\n\n## What The Skill Must Not Do\n\n- Do not publish or repost without explicit per-ad approval.\n- Do not enable paid options without separate approval.\n- Do not invent price, condition, or uncertain required fields.\n- Do not bypass login, captcha, WAF, or security checks.\n- Do not reply to buyers without separate permission.\n- Do not expose cookies, XSRF tokens, or session data.\n\n## Required Permissions\n\nFor search:\n\n- Network access to Marktplaats.\n- Node.js for the existing CLI tools.\n\nFor preparation:\n\n- Read access to local photo files provided by the user.\n- Read access to relevant WhatsApp/iMessage attachments when the user asks to use them.\n- Write access for ad records, photos and snapshots, preferably:\n  - `~/Documents/OpenClaw/Data/marktplaats/`\n  - `housekeeping/marktplaats-snapshots/`\n  - `housekeeping/marktplaats-test/`\n\nFor publishing:\n\n- A browser session where the user is already logged in to Marktplaats.\n- macOS automation through AppleScript or Peekaboo to use that browser context.\n- Access to the Marktplaats placement page.\n\nThe skill does not need the user's Marktplaats password. Authentication stays inside the browser.\n\n## Local Ad Register\n\nCentral register:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nOptional per-ad directory:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/\n```\n\nRecommended contents:\n\n- `ad.json`: ad id, URL, status, price, category, source and repost metadata.\n- `description.md`: latest listing description.\n- `photos/originals/`: source photos.\n- `photos/processed/`: resized/metadata-reduced publish photos.\n- `snapshots/`: form or submit snapshots.\n\nImportant statuses:\n\n- `draft`\n- `pending_approval`\n- `active`\n- `removed`\n- `expired`\n- `needs_repost`\n- `reposted`\n- `test`\n\nUpdate the register after every placement, validation error, removal, status check or repost.\n\n## Reposting After Expiry\n\nMarktplaats can change its rules. Check the current listing duration or ad status before relying on dates.\n\nStandard flow:\n\n1. Read `advertenties.json`.\n2. Find active ads with past `renewAfter`/`expiresAt` values, or ads that no longer appear active.\n3. Verify the ad status.\n4. Set `needs_repost` when reposting makes sense.\n5. Build a fresh dry-run from the existing text/photos, with current category and form checks.\n6. Publish only after explicit user approval.\n7. Add the new ad id to the register and keep the old ad in `repostHistory`.\n\nA cron/heartbeat may report that ads need reposting, but it must not publish automatically.\n\n## Intake From WhatsApp Or iMessage\n\nWhen the user sends photos and says what the item is:\n\n1. Read only the relevant messages/attachments.\n2. Store photos in the ad directory.\n3. Create safe publishing copies.\n4. Record the source, such as channel, chat id, message id and timestamp.\n5. Identify the item, brand/model and visible details.\n6. Ask for missing essentials: price, condition, pickup/shipping, defects, missing parts.\n7. Research product information online.\n8. Choose a category and inspect the current form.\n9. Write a strong SEO listing of roughly 3200-3500 characters.\n10. Run `marktplaats-copy-qa` with product terms and a natural search variant.\n11. Present a dry-run.\n12. Publish only after explicit approval.\n\nFor WhatsApp/iMessage: reading/analyzing is allowed when the user asks for this task; sending replies to other people or buyers requires separate permission.\n\n## Standard Workflow\n\n### 1. Understand The Item\n\nDetermine:\n\n- item type;\n- brand/model/type;\n- condition;\n- asking price;\n- pickup/shipping preference;\n- included accessories;\n- defects or important notes;\n- available photos.\n\nAsk the user if essential information is missing.\n\n### 2. Find Candidate Categories\n\nUse:\n\n```bash\nmarktplaats-categories --json\nmarktplaats-categories <parent-id> --json\nmarktplaats-search \"<product name>\" --json -n 10\n```\n\nChoose based on:\n\n- comparable listings;\n- suitable category attributes;\n- free listing availability;\n- buyer discoverability.\n\nExplain the chosen category in the dry-run.\n\n### 3. Copy Quality Gate\n\nBefore filling Marktplaats, run:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<brand-or-type>\" \\\n  --require \"<product-kind>\" \\\n  --variant \"<natural search variant>\" \\\n  --ad-json ./ad.json\n```\n\nStop if the command fails or if `ad.json.copyQuality.passed` is not `true`.\n\nHard requirements:\n\n- default length 3200-3500 characters;\n- hard lower stop at 2800 characters;\n- at least 7 substantial sections/paragraphs;\n- no `Zoektermen:`, `Keywords:`, `SEO:` or keyword dump;\n- natural SEO terms in prose;\n- at least one subtle product-relevant typo/spelling/search variant in context.\n\n### 4. Inspect The Live Form\n\nOpen the placement page for the chosen category and capture a fresh snapshot with the probe:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nOr open the placement page in Safari in the background before probing the same session:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\nInspect:\n\n- `form.action` (usually `https://www.marktplaats.nl/plaats/ads`);\n- category identifiers;\n- presence of an XSRF token, not the value;\n- hidden form values;\n- title and description fields;\n- price fields;\n- condition fields;\n- category attributes;\n- delivery fields;\n- postcode/contact fields;\n- paid feature fields;\n- selected bundle.\n- `security.challengeSignals` for login, captcha, MFA, WAF, or payment/promotion signals.\n\nA `curl` probe on `/plaats` may return `401` without a session cookie. That is expected. In that case, use the logged-in browser DOM as the source of truth instead of manual UI clicking.\n\nPrefer background-safe inspection before visible UI: use `--browser-fetch --url ...` or `--browser --open-background ...` where possible. Safari may carry the logged-in session, but the workflow should not unnecessarily activate Safari or steal the user's current tab.\n\n### 4. Fill Fields Conservatively\n\n- Keep the title short and specific.\n- Keep the description factual.\n- Fill condition only when reasonably certain.\n- Use the user's price or ask for one.\n- Select multi-value attributes only when clearly applicable.\n- Default delivery to pickup unless shipping is requested.\n\n### 5. Enforce Free Listing\n\nBefore publishing, verify:\n\n- free bundle selected;\n- no urgent/homepage/promoted features enabled;\n- no paid bundle selected;\n- no payment page shown.\n\nStop if Marktplaats asks for payment unexpectedly.\n\n### 6. Prepare Photos\n\nCreate temporary resized copies when possible:\n\n```bash\nmkdir -p housekeeping/marktplaats-test\nsips -Z 1600 -s format jpeg input.jpg --out housekeeping/marktplaats-test/photo-1.jpg\n```\n\nCheck for obvious EXIF/GPS metadata where possible.\n\n### 7. Upload Photos\n\nThe proven browser-context upload uses:\n\n- endpoint: `/plaats/api/image/upload`\n- method: `POST`\n- FormData fields:\n  - `name`\n  - `imageData`\n- header:\n  - `x-mp-xsrf`\n\nPreferred local helper:\n\nUpload the photos in the live flow and then read back the generated `images.ids` / hidden fields through the probe. Use the browser only as a session carrier, not to guess an upload path by hand. If upload or photo count cannot be verified, stop.\n\n### 8. Dry-Run Summary\n\nAlways show before publishing:\n\n```text\nCategory: ...\nReason: ...\nTitle: ...\nPrice: ...\nCondition: ...\nDelivery: ...\nPhotos: ...\nFree listing: yes/no\nPaid options: none\nUncertain fields: ...\nAfter approval: publish to Marktplaats\n```\n\n### 9. Publish\n\nPublish only after explicit approval. After submission:\n\n- report the success URL;\n- report the advertisement id/link;\n- summarize validation errors if any;\n- stop if a payment page appears;\n- run live verification;\n- update the local ad register.\n\n## Testing Protocol\n\nRecommended test period:\n\n1. Start with one dummy/test advertisement.\n2. Try 2-3 low-risk real ads.\n3. Check category, price, photos and free options.\n4. Confirm that ads can be removed easily.\n5. Note problematic categories/fields.\n6. Test reposting from the local register.\n7. Test intake from WhatsApp/iMessage photos.\n8. Consider ClawHub publication only after testing.\n\n## ClawHub Publication Notes\n\nA public listing should clearly state:\n\n- publishing and reposting require explicit approval;\n- the user must be logged in themselves;\n- the skill does not bypass login/captcha/security checks;\n- paid options are off by default;\n- local ad tracking may contain personal photos/data and must be treated as private;\n- required local tools and permissions;\n- Marktplaats flows may change;\n- users remain responsible for ad content and platform compliance.\n\nFile v0.6.3:references/handleiding-nl.md\n\n# Marktplaats Verkoopassistent - Nederlandse Handleiding\n\n## Naam\n\n**Marktplaats Verkoopassistent**\n\nTechnische skill-key: `marktplaats-publisher`.\n\nDeze naam is bewust breder dan alleen zoeken. De skill helpt bij het volledige verkoopproces: categorie kiezen, velden bepalen, foto's voorbereiden/uploaden, lokaal bijhouden, herplaatsing voorbereiden, dry-run maken en pas na akkoord publiceren.\n\n## Doel\n\nDe skill helpt een gebruiker of agent om Marktplaats-advertenties betrouwbaar en veilig voor te bereiden, te plaatsen en later terug te vinden voor controle of herplaatsing. De belangrijkste verbetering ten opzichte van handmatig werken is dat de agent eerst de actuele categorievelden uitleest en daarna pas een advertentie invult. Daarnaast houdt de skill lokaal bij wat geplaatst is, met welke foto's en tekst, zodat verlopen advertenties later opnieuw voorbereid kunnen worden.\n\n## Wat De Skill Kan\n\n- Marktplaats doorzoeken op vergelijkbare advertenties.\n- Categorieën en subcategorieën ophalen.\n- Een beste categorie voorstellen voor een item.\n- Een live plaatsingsformulier uitlezen via de browser.\n- Categorie-specifieke velden verzamelen, zoals conditie, merk, type, maat, levering, prijs en extra opties.\n- Foto's verkleinen en metadata-arm maken waar mogelijk.\n- Foto-upload begeleiden en controleren via de ingelogde Marktplaats-browsercontext.\n- Advertentiedata invullen in het formulier.\n- Betaalde opties standaard uitschakelen.\n- Een dry-run samenvatting tonen.\n- Na expliciet akkoord een advertentie publiceren.\n- Na publicatie de success-URL of foutmelding rapporteren.\n- Geplaatste advertenties lokaal administreren.\n- Verlopen of verwijderde advertenties markeren voor herplaatsing.\n- Foto's en korte omschrijvingen uit WhatsApp/iMessage als advertentie-intake gebruiken wanneer de gebruiker daarom vraagt.\n- Advertentieteksten vóór publicatie verplicht controleren met de Copy Quality Gate.\n\n## Wat De Skill Niet Zelfstandig Mag\n\n- Geen advertentie publiceren of herplaatsen zonder expliciet akkoord per advertentie.\n- Geen betaalde plaatsing of promotie inschakelen zonder apart akkoord.\n- Geen prijs verzinnen als de gebruiker geen prijs heeft gegeven.\n- Geen conditie kiezen als die onzeker is.\n- Geen captcha, login, WAF of beveiligingscontrole omzeilen.\n- Geen berichten beantwoorden aan kopers zonder aparte toestemming.\n- Geen cookies, XSRF-tokens of sessiegegevens delen.\n\n## Benodigde Rechten\n\nVoor zoeken:\n\n- Netwerktoegang naar Marktplaats.\n- Node.js voor de CLI-tools.\n\nVoor advertentievoorbereiding:\n\n- Leesrechten op lokale fotobestanden.\n- Leesrechten op relevante WhatsApp/iMessage-bijlagen wanneer de gebruiker vraagt die te gebruiken.\n- Schrijfrechten voor advertentiegegevens, foto's en snapshots, bij voorkeur:\n  - `~/Documents/OpenClaw/Data/marktplaats/`\n  - `housekeeping/marktplaats-snapshots/`\n  - `housekeeping/marktplaats-test/`\n\nVoor plaatsen:\n\n- Een browser waarin de gebruiker al is ingelogd op Marktplaats.\n- macOS automation via AppleScript of Peekaboo om de browsercontext te gebruiken.\n- Toegang tot de Marktplaats plaatsingspagina.\n\nBelangrijk: de skill heeft geen Marktplaats-wachtwoord nodig. Login blijft bij de gebruiker/browser.\n\n## Lokale Advertentieadministratie\n\nCentrale administratie:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nPer advertentie kan een eigen map worden gebruikt:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/\n```\n\nAanbevolen inhoud:\n\n- `ad.json`: advertentie-id, URL, status, prijs, categorie, bron en herplaatsinformatie.\n- `description.md`: laatst gebruikte advertentietekst.\n- `photos/originals/`: bronfoto's.\n- `photos/processed/`: verkleinde/metadata-arme publicatiefoto's.\n- `snapshots/`: formulier- of submit-snapshots.\n\nBelangrijke statussen:\n\n- `draft`\n- `pending_approval`\n- `active`\n- `removed`\n- `expired`\n- `needs_repost`\n- `reposted`\n- `test`\n\nNa elke plaatsing, foutmelding, verwijdering, statuscheck of herplaatsing wordt het register bijgewerkt.\n\n## Herplaatsing Na Verlopen\n\nMarktplaats kan regels wijzigen. Controleer daarom de actuele looptijd of advertentiestatus voordat je automatisch conclusies trekt.\n\nStandaardflow:\n\n1. Lees `advertenties.json`.\n2. Zoek actieve advertenties met verlopen `renewAfter`/`expiresAt` of advertenties die niet meer zichtbaar lijken.\n3. Controleer de advertentiestatus.\n4. Zet ze op `needs_repost` als herplaatsing zinvol is.\n5. Maak een nieuwe dry-run op basis van de bestaande tekst/foto's, met verse categorie- en formuliercheck.\n6. Publiceer pas na expliciet akkoord van de gebruiker.\n7. Voeg de nieuwe advertentie-id toe aan het register en bewaar de oude in `repostHistory`.\n\nEen cron/heartbeat mag melden dat advertenties herplaatst moeten worden, maar mag niet zelfstandig publiceren.\n\n## Intake Vanuit WhatsApp Of iMessage\n\nWanneer de gebruiker foto's stuurt en zegt wat het is:\n\n1. Lees alleen de relevante berichten/bijlagen.\n2. Sla de foto's lokaal op in de advertentiemap.\n3. Maak veilige publicatiekopieën.\n4. Leg de bron vast, zoals kanaal, chat-id, message-id en tijdstip.\n5. Herken item, merk/model en zichtbare details.\n6. Vraag ontbrekende kerngegevens: prijs, conditie, ophalen/verzenden, gebreken, missende onderdelen.\n7. Zoek productinformatie online.\n8. Kies categorie en inspecteer het actuele formulier.\n9. Schrijf een sterke SEO-advertentie van circa 3200-3500 tekens.\n10. Draai `marktplaats-copy-qa` met producttermen en een natuurlijke zoekvariant.\n11. Toon dry-run.\n12. Plaats alleen na expliciet akkoord.\n\nVoor WhatsApp/iMessage geldt: lezen/analyseren mag als de gebruiker daarom vraagt; antwoorden naar anderen of kopers sturen alleen na aparte toestemming.\n\n## Standaard Stappenplan\n\n### 1. Item Begrijpen\n\nBepaal:\n\n- wat het item is;\n- merk/type/model;\n- conditie;\n- gewenste prijs;\n- ophalen/verzenden;\n- meegeleverde onderdelen;\n- gebreken of bijzonderheden;\n- beschikbare foto's.\n\nAls prijs, conditie of essentieel detail ontbreekt: vraag de gebruiker.\n\n### 2. Categorie-Kandidaten Zoeken\n\nGebruik:\n\n```bash\nmarktplaats-categories --json\nmarktplaats-categories <parent-id> --json\nmarktplaats-search \"<productnaam>\" --json -n 10\n```\n\nKies de categorie op basis van:\n\n- bestaande vergelijkbare advertenties;\n- passende attributen;\n- gratis plaatsingsmogelijkheid;\n- logische vindbaarheid voor kopers.\n\nMotiveer de keuze in de dry-run.\n\n### 3. Copy Quality Gate\n\nVoordat Marktplaats wordt ingevuld:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<merk-of-type>\" \\\n  --require \"<productsoort>\" \\\n  --variant \"<natuurlijke zoekvariant>\" \\\n  --ad-json ./ad.json\n```\n\nStop als de command faalt of als `ad.json.copyQuality.passed` niet `true` is.\n\nHarde eisen:\n\n- standaard 3200-3500 tekens;\n- absolute ondergrens 2800 tekens;\n- minimaal 7 substantiële secties/alinea's;\n- geen `Zoektermen:`, `Keywords:` of keyworddump;\n- natuurlijke SEO-termen in lopende tekst;\n- minimaal één subtiele, productrelevante spelfout/schrijfvariant in context.\n\n### 4. Live Plaatsingsformulier Inspecteren\n\nOpen de plaatsingspagina voor de gekozen categorie en maak een snapshot met de probe:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nOf open de plaatsingspagina in Safari op de achtergrond en probe daarna dezelfde sessie:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\nControleer:\n\n- `form.action` (meestal `https://www.marktplaats.nl/plaats/ads`);\n- categorievelden (`l1`, `l2`, `bucket`);\n- aanwezigheid van een XSRF-token, niet de waarde;\n- hidden formulierwaarden;\n- titel/omschrijving;\n- prijsvelden;\n- conditievelden;\n- categorie-attributen;\n- leveringsvelden;\n- postcode/contact;\n- betaalde opties;\n- geselecteerde bundle.\n- `security.challengeSignals` voor login, captcha, MFA, WAF of betaal-/promotiesignalen.\n\nEen `curl`-probe op `/plaats` kan `401` geven als er geen sessiecookie wordt meegegeven. Dat is normaal: gebruik in dat geval de ingelogde browser-DOM als bron van waarheid, niet handmatige UI-kliks.\n\nGebruik voor authenticated requests zonder cookies te exporteren:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser-fetch --url https://www.marktplaats.nl/plaats\n```\n\nDeze route gebruikt Safari's bestaande sessie via `XMLHttpRequest` met credentials. Cookies en sessietokens blijven in Safari en worden niet gelogd.\n\nWerk background-first. Gebruik `--browser-fetch` of `--open-background` voordat je zichtbare UI inzet. Safari mag sessiedrager zijn, maar mag de gebruiker niet onnodig naar voren trekken of van actieve tab wisselen.\n\n### 5. Velden Invullen\n\nGebruik conservatieve mapping:\n\n- Titel kort en specifiek.\n- Beschrijving feitelijk, geen overdreven verkooppraat.\n- Conditie alleen invullen als redelijk zeker.\n- Prijs alleen van de gebruiker of expliciet akkoord.\n- Multi-selects alleen aanvinken als zeker passend.\n- Levering standaard ophalen, tenzij de gebruiker verzending wil.\n\n### 6. Gratis Advertentie Afdwingen\n\nControleer vóór publicatie:\n\n- gratis bundle geselecteerd;\n- geen urgent/etalage/homepage/promotie;\n- geen betaalpagina;\n- geen onverwachte kosten.\n\nAls Marktplaats toch kosten toont: stoppen en rapporteren.\n\n### 7. Foto's Voorbereiden\n\nMaak bij voorkeur tijdelijke kopieën:\n\n```bash\nmkdir -p housekeeping/marktplaats-test\nsips -Z 1600 -s format jpeg input.jpg --out housekeeping/marktplaats-test/photo-1.jpg\n```\n\nControleer waar mogelijk of GPS/EXIF niet meer zichtbaar is.\n\n### 8. Foto's Uploaden\n\nGebruik de bewezen browsercontext-route. De Marktplaats frontend verwacht:\n\n- endpoint: `/plaats/api/image/upload`\n- method: `POST`\n- FormData velden:\n  - `name`\n  - `imageData`\n- header:\n  - `x-mp-xsrf`\n\nUpload de foto's in de live flow en lees daarna de gegenereerde `images.ids`/hidden fields terug uit de probe. Gebruik de browser alleen als sessiedrager, niet om handmatig een uploadpad te raden. Als upload of fototeller niet te verifieren is, stoppen.\n\n### 9. Dry-Run Tonen\n\nAltijd tonen vóór publiceren:\n\n```text\nCategorie: ...\nWaarom deze categorie: ...\nTitel: ...\nPrijs: ...\nConditie: ...\nLevering: ...\nFoto's: ...\nGratis advertentie: ja/nee\nBetaalde opties: geen\nOnzekere velden: ...\nNa akkoord: publiceren op Marktplaats\n```\n\n### 9. Publiceren\n\nAlleen na expliciet akkoord. Na submit:\n\n- success-redirect rapporteren;\n- advertentie-id/link rapporteren;\n- validatiefouten kort samenvatten;\n- bij betaalpagina stoppen;\n- daarna live-verificatie draaien;\n- lokale advertentieadministratie bijwerken.\n\n## Testprotocol\n\nAanbevolen testperiode:\n\n1. Begin met 1 dummy/testadvertentie.\n2. Test daarna 2-3 echte goedkope advertenties.\n3. Controleer of categorie, prijs, foto's en gratis opties kloppen.\n4. Controleer of advertenties makkelijk te verwijderen zijn.\n5. Noteer welke categorieën/velden lastig zijn.\n6. Test daarna herplaatsing vanuit het lokale register.\n7. Test daarna intake vanuit WhatsApp/iMessage-foto's.\n8. Pas daarna publicatie op ClawHub overwegen.\n\n## Publicatie Op ClawHub\n\nVoor publicatie moet de skill duidelijk vermelden:\n\n- dat publiceren en herplaatsen alleen na expliciet akkoord mag;\n- dat de gebruiker zelf ingelogd moet zijn;\n- dat de skill geen login/captcha omzeilt;\n- dat betaalde opties standaard uit staan;\n- dat lokaal advertentiebeheer persoonsgegevens/foto's kan bevatten en dus privé behandeld moet worden;\n- welke lokale tools nodig zijn;\n- dat Marktplaats-flows kunnen wijzigen;\n- dat de gebruiker verantwoordelijk blijft voor advertentie-inhoud en platformregels.\n\nFile v0.6.3:references/robust-posting-checklist.md\n\n- Work linearly and deterministically.\n- Run `marktplaats-copy-qa` before touching Marktplaats; stop if it fails.\n- Keep descriptions around 3200-3500 characters, with a hard stop below 2800.\n- Use natural SEO in prose; never publish `Zoektermen:` or keyword-dump footers.\n- Include one subtle product-relevant typo/search variant in context.\n- Prefer one dedicated browser window/tab for a single ad flow.\n- Avoid extra screens, helper windows, and parallel UI actions.\n- Rotate photos only when preview/orientation shows it is needed.\n- Use ASCII-safe text if live rendering shows mojibake.\n- Verify live seller-view as source of truth.\n- Keep the flow understandable for light/mini models such as GPT-4.5 mini or the local mini route: one command, one proof, one next step.\n- Prefer background-safe probes before visible UI: `--browser-fetch --url ...` or `--browser --open-background ...`.\n- Do not activate Safari, move windows, or use coordinate clicks unless a foreground UI check is truly required.\n- Select Safari tabs/documents by Marktplaats URL or ad id, never by screen position.\n- Register update only after successful live verification, unless explicitly tracking a draft with `--allow-unverified`.\n\nFile v0.6.3:references/setup-small-model-nl.md\n\n# Setup Voor Kleine Modellen\n\nGebruik deze reference wanneer een licht model, zoals GPT-4.5 mini of de lokaal beschikbare mini-route, `marktplaats-publisher` moet installeren, herstellen of klaarzetten.\n\n## Doel\n\nSetup is pas klaar wanneer de juiste package is gevonden en de CLI-gates aantoonbaar werken. Een geslaagde setup plaatst of bewerkt nog geen advertentie.\n\n## Identiteit\n\nVerwachte skill/package:\n\n```text\nmarktplaats-publisher\n```\n\nNiet verwarren met:\n\n- `marktplaats`\n- `marktplaats-nl-publisher`\n- `pvoo/marktplaats`\n- alleen een losse Marktplaats zoekskill\n\nControle:\n\n```bash\nnode -p \"require('./package.json').name + '@' + require('./package.json').version\"\n```\n\nStop als de package-naam niet `marktplaats-publisher` is.\n\n## Vereisten\n\n- Node.js 18 of nieuwer.\n- Toegang tot de skillmap.\n- Schrijfrechten in `~/Documents/OpenClaw/Data/marktplaats/` voor advertentiedata.\n- Voor publiceren/bewerken later: een bestaande ingelogde Safari-sessie. Setup zelf vraagt nooit om Marktplaats-wachtwoorden.\n\nControle:\n\n```bash\nnode --version\nnpm --version\n```\n\n## Installatie En Smoke-Test\n\nVanuit de skillmap:\n\n```bash\nnpm install -g .\nnpm test\n```\n\n`npm test` moet groen zijn. Als globale commands niet beschikbaar zijn, gebruik directe scriptcalls vanuit de skillmap:\n\n```bash\nnode ./bin/marktplaats-search.js --help\nnode ./bin/marktplaats-categories.js --help\nnode ./scripts/marktplaats-place-probe.js --self-test\nnode ./scripts/marktplaats-copy-qa.js --self-test\nnode ./scripts/marktplaats-ad-preflight.js --self-test\nnode ./scripts/marktplaats-live-verify.js --self-test\nnode ./scripts/marktplaats-register-update.js --self-test\n```\n\nEen licht model mag setup alleen als geslaagd rapporteren wanneer deze tests slagen.\n\n## Data-Mappen\n\nGebruik voor advertentiedata:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<slug>/photos/\n```\n\nGebruik voor tijdelijke snapshots:\n\n```text\nhousekeeping/marktplaats-snapshots/\n```\n\nLaat geen advertentiedata los in de workspace-root achter.\n\n## Mini-Model Contract\n\nWerk altijd lineair:\n\n1. bepaal de huidige gate;\n2. draai precies een command;\n3. lees output en exitstatus;\n4. noteer `PASS` of `FAIL`;\n5. ga alleen door bij bewijs;\n6. bij failure: herstel een concrete oorzaak en draai dezelfde gate opnieuw;\n7. na twee mislukte herstelpogingen per foutklasse stoppen en rapporteren.\n\nStatusblok per advertentie:\n\n```text\nadDir: ...\nadJson: ...\ndescription: ...\ncurrentGate: setup | copy-qa | preflight | probe | ui-fill | live-verify | register\nlastCommand: ...\nresult: PASS | FAIL | blocked\nnextStep: ...\n```\n\n## Stopmomenten\n\nStop bij:\n\n- verkeerde package-naam;\n- Node.js ouder dan 18;\n- falende self-test;\n- ontbrekende globale CLI zonder werkende directe scriptfallback;\n- login, captcha, MFA, WAF of betaalpagina;\n- verzoek om cookies, sessietokens of wachtwoorden te exporteren;\n- onduidelijke formulierstatus of UI-drift.\n\n## Wat Setup Niet Doet\n\n- Geen echte advertentie publiceren.\n- Geen bestaande advertentie bewerken.\n- Geen betaalde optie kiezen.\n- Geen Marktplaats-login automatiseren.\n- Geen koperberichten sturen.\n\nSetup eindigt met een korte status: package, versie, tests, beschikbare commando's en eventuele blokkade.\n\nFile v0.6.3:skill-card.md\n\n## Description:\n\nMarktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[roelbroersma](https://clawhub.ai/user/roelbroersma)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use this skill to prepare, check, place or update normal Marktplaats sale advertisements with script-gated copy QA, preflight checks, live verification and a local register.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill may use a local agent with the user's logged-in Safari Marktplaats session and write ad snapshots or registers.\n\nMitigation: Use only when comfortable with that local access pattern, keep snapshots private, and inspect logs or snapshots for sensitive data before sharing.\n\nRisk: The probe workflow can read authenticated browser forms and may forward user-supplied cookies or headers if misused.\n\nMitigation: Do not pass cookies, cookie files, Authorization headers, or non-Marktplaats URLs to the probe tool.\n\n## Reference(s):\n\n- [Marktplaats Skill Page](https://clawhub.ai/roelbroersma/skills/marktplaats-publisher)\n- [README](README.md)\n- [Nederlandse handleiding](references/handleiding-nl.md)\n- [English guide](references/guide-en.md)\n- [Robust posting checklist](references/robust-posting-checklist.md)\n- [Setup for small models](references/setup-small-model-nl.md)\n- [Background Safari flow](references/background-safari-nl.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and local JSON file updates]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires Node.js and may use a logged-in Safari Marktplaats session for authenticated checks.]\n\n## Skill Version(s):\n\n0.6.3 (source: server release metadata and package.json)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.6.3:package.json\n\n{\n  \"name\": \"marktplaats-publisher\",\n  \"version\": \"0.6.3\",\n  \"description\": \"Maak en controleer Marktplaats-advertenties met scriptmatige preflight, live-verificatie en register-update.\",\n  \"type\": \"module\",\n  \"bin\": {\n    \"marktplaats-search\": \"./bin/marktplaats-search.js\",\n    \"marktplaats-categories\": \"./bin/marktplaats-categories.js\",\n    \"marktplaats-place-probe\": \"./scripts/marktplaats-place-probe.js\",\n    \"marktplaats-copy-qa\": \"./scripts/marktplaats-copy-qa.js\",\n    \"marktplaats-ad-preflight\": \"./scripts/marktplaats-ad-preflight.js\",\n    \"marktplaats-live-verify\": \"./scripts/marktplaats-live-verify.js\",\n    \"marktplaats-register-update\": \"./scripts/marktplaats-register-update.js\"\n  },\n  \"exports\": \"./src/index.js\",\n  \"files\": [\n    \"bin\",\n    \"src\",\n    \"scripts\",\n    \"references\",\n    \"README.md\",\n    \"LICENSE\",\n    \"SKILL.md\"\n  ],\n  \"scripts\": {\n    \"test\": \"node ./bin/marktplaats-search.js --help && node ./bin/marktplaats-categories.js --help && node ./scripts/marktplaats-place-probe.js --self-test && node ./scripts/marktplaats-copy-qa.js --self-test && node ./scripts/marktplaats-ad-preflight.js --self-test && node ./scripts/marktplaats-live-verify.js --self-test && node ./scripts/marktplaats-register-update.js --self-test\"\n  },\n  \"keywords\": [\n    \"marktplaats\",\n    \"classifieds\",\n    \"publisher\",\n    \"posting\",\n    \"search\",\n    \"cli\",\n    \"copy-qa\",\n    \"self-healing\"\n  ],\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"license\": \"MIT\",\n  \"author\": \"OpenClaw community\"\n}\n\nArchive v0.6.2: 17 files, 51342 bytes\n\nFiles: _meta.json (140b), bin/marktplaats-categories.js (2982b), bin/marktplaats-search.js (8020b), package.json (1504b), README.md (7412b), references/guide-en.md (10165b), references/handleiding-nl.md (11376b), references/robust-posting-checklist.md (981b), scripts/marktplaats-ad-preflight.js (12971b), scripts/marktplaats-copy-qa.js (14188b), scripts/marktplaats-live-verify.js (17066b), scripts/marktplaats-place-probe.js (20555b), scripts/marktplaats-register-update.js (9233b), skill-card.md (2483b), SKILL.md (8604b), src/api.js (14739b), src/index.js (160b)\n\nFile v0.6.2:SKILL.md\n\n---\nname: \"marktplaats-publisher\"\ndescription: \"Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register.\"\nmetadata: {\"clawdbot\":{\"emoji\":\"🇳🇱\",\"requires\":{\"bins\":[\"node\"]}}}\n---\n\n# Marktplaats Publisher\n\nGebruik deze skill voor normale Marktplaats-advertenties: voorbereiden, plaatsen, bewerken, live controleren en lokaal registreren.\n\nDe workflow is command-first. Proceduretekst is alleen toelichting. Als een gate faalt, stop je.\n\nVoor kleinere modellen: doe steeds een fase, lees de output, en ga pas door als de vorige fase aantoonbaar geslaagd is. De scripts zijn harde gates; publiceren en UI-invulwerk blijven browserwerk met verificatie, geen blinde submit-flow.\n\n## Harde Regels\n\n- Geen publicatie of inhoudelijke bewerking zonder expliciete opdracht voor die advertentie.\n- Geen betaalde opties, bundels, promoties of betaalflow zonder expliciet akkoord.\n- Geen cookies, sessietokens, XSRF/auth-waarden, klantdata of lokale privepaden loggen of publiceren.\n- Geen captcha, MFA, login challenge, WAF of accountbeveiliging omzeilen.\n- Geen tekst plaatsen als copy-QA of preflight faalt.\n- Gebruik `--allow-*` opties alleen bij expliciete, taak-specifieke uitzondering van de gebruiker.\n- Publiceerbare advertentietekst mag nooit websiteadressen of domeinachtige tekst bevatten. Verboden zijn onder andere `http://`, `https://`, `www.`, e-mailadressen en woorden met bekende domeinextensies zoals `.com`, `.nl`, `.eu`, `.org`, `.net`, `.de`, `.be` en `.io`. Merknamen met een domeinextensie, zoals `StarTech.com`, moeten worden herschreven naar een gewone merknaam zonder punt, bijvoorbeeld `StarTech`.\n- Publiceer of accepteer geen advertentie waarvan de live omschrijving als een grote lap tekst verschijnt. De lokaal geschreven alinea's moeten live aantoonbaar bewaard blijven via alinea's, `<br>`-achtige regelovergangen of Marktplaats-blokken.\n- Na opslaan altijd live verifieren en het lokale register bijwerken.\n- Bij UI-drift, browser-hang of onduidelijke formulierstatus: stop, maak een snapshot en rapporteer de blokkade.\n\n## Lokale Bestanden\n\nWerk per advertentie in:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<slug>/photos/\n```\n\nCentraal register:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\n`ad.json` moet minimaal bevatten: titel, prijs, conditie, levering, categorie/categoryIds, `biddingAllowed`, `descriptionFile`, `imageDir` of foto's, URL/adId zodra live, en `copyQuality`.\n\n## Verplichte Pipeline\n\n### 1. Schrijf De Omschrijving\n\nSchrijf een feitelijke Nederlandse tekst van ongeveer 3200-3500 tekens.\n\nMoet bevatten:\n\n- merk/model of herkenbare productnaam;\n- productsoort;\n- staat/conditie en wat wel/niet getest is;\n- concrete zichtbare kenmerken;\n- toepassing en compatibiliteit;\n- ophalen/verzenden, prijs en bieden;\n- natuurlijke zoekvarianten in gewone zinnen;\n- minimaal een, en bij voorkeur niet meer dan twee, subtiele productrelevante typefout-/schrijfvarianten in gewone zinnen. Voorbeeld: `buiten antenne` naast `buitenantenne`.\n\nNiet doen:\n\n- geen websiteadressen, domeinachtige merknamen, `www.`-tekst, URL's of e-mailadressen;\n- geen `Zoektermen:`, `Keywords:` of `SEO:` footer;\n- geen lange comma-keyworddump;\n- geen claims over werking, garantie of compleetheid zonder bewijs.\n\n### 2. Copy-QA\n\nAltijd draaien voordat Marktplaats wordt ingevuld of opgeslagen:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<merk-of-model>\" \\\n  --require \"<productsoort>\" \\\n  --variant \"<natuurlijke zoekvariant>\" \\\n  --ad-json ./ad.json\n```\n\nStop als dit geen `PASS` geeft. De command schrijft `copyQuality` inclusief `descriptionSha256` naar `ad.json`.\n\nHerhaal `--variant` alleen voor een tweede minimale variant als die natuurlijk in de omschrijving past. Gebruik geen losse typefoutenlijst.\n\nCopy-QA faalt bij URL's, `www.`-tekst, e-mailadressen en domeinachtige tekst zoals `startech.com`, ook als er geen protocol voor staat.\n\n### 3. Preflight\n\nAltijd draaien na copy-QA en voor browser/UI-werk:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nGebruik `--require-bidding-allowed` wanneer bieden aan moet staan. Stop bij failure.\n\nPreflight controleert onder andere:\n\n- verplichte advertentievelden;\n- omschrijving bestaat en is niet gewijzigd na copy-QA;\n- copy-QA is geslaagd;\n- publiceerbare advertentietekst bevat geen URL's, `www.`-tekst, e-mailadressen of domeinachtige tekst;\n- foto's bestaan;\n- biedeninstelling indien vereist.\n\n### 4. Formulier Probe\n\nInspecteer Marktplaats voordat je invult:\n\n```bash\nmarktplaats-place-probe --browser --save ./snapshot-place.json\n```\n\nAls Safari niet de actieve app hoeft te worden, open de plaatsingspagina op de achtergrond en probe daarna dezelfde Safari-context:\n\n```bash\nmarktplaats-place-probe --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save ./snapshot-place.json\n```\n\nOf met browser-fetch:\n\n```bash\nmarktplaats-place-probe --browser-fetch --url \"https://www.marktplaats.nl/plaats/...\" --save ./snapshot-place.json\n```\n\nStop als:\n\n- login/captcha/MFA/WAF verschijnt;\n- betaalde route verplicht lijkt;\n- formulierstructuur onduidelijk is;\n- foto-upload of bundelkeuze niet te verifieren is;\n- `security.challengeSignals` login, captcha, MFA, WAF of betaal-/promotiesignalen toont.\n\n### 5. Plaats Of Bewerk\n\nVul Marktplaats pas na groene copy-QA en preflight.\n\nControleer voor submit/save:\n\n- titel;\n- prijs;\n- bieden toegestaan indien gevraagd;\n- conditie;\n- levering;\n- foto-aantal;\n- gratis/basic route;\n- laatste zin van de omschrijving zichtbaar in het formulier;\n- alinea's zichtbaar in het omschrijvingsveld; gebruik bij voorkeur het zichtbare rich-text/contenteditable veld en geen directe hidden-field submit voor de omschrijving.\n\nGebruik geen blinde coordinate-clicks. Gebruik DOM/events of een expliciet UI-element met verificatie voor en na.\n\nGebruik geen directe hidden-field submit of platte `URLSearchParams`-post voor de omschrijving tenzij live-verificatie daarna bewijst dat alinea's bewaard zijn. Als Marktplaats de tekst ondanks correcte inhoud als een doorlopende lap toont, is de advertentie niet klaar.\n\n### 6. Live Verify\n\nNa opslaan of plaatsen moet de live advertentie gecontroleerd worden.\n\nAls fetch genoeg tekst bevat:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --url \"https://www.marktplaats.nl/seller/view/...\" --update-ad-json\n```\n\nAls de pagina dynamisch is, sla eerst zichtbare/live tekst op en verifieer die:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --text ./live-text.txt --update-ad-json\n```\n\nStop als:\n\n- begin van de omschrijving ontbreekt;\n- laatste zin ontbreekt;\n- omschrijving dubbel staat;\n- `Zoektermen:` of keyworddump live zichtbaar is;\n- live advertentietekst alsnog websiteadressen of domeinachtige tekst bevat;\n- live omschrijving geen aantoonbare alinea-/regelstructuur heeft.\n\n### 7. Register Update\n\nWerk na live verificatie het centrale register bij:\n\n```bash\nmarktplaats-register-update \\\n  --ad-json ./ad.json \\\n  --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json \\\n  --note \"Live gecontroleerd na plaatsing/bewerking.\"\n```\n\nRun register-updates sequentieel. Het script gebruikt een lock en faalt als een tweede update tegelijk hetzelfde centrale register probeert te schrijven.\n\nDe register-update hoort standaard te falen als live-verificatie ontbreekt of faalde. Gebruik `--allow-unverified` alleen voor niet-gepubliceerde conceptadministratie en vermeld waarom in `--note`.\n\n## Bestaande Advertentie Bewerken\n\nVoor elke inhoudelijke tekstbewerking geldt dezelfde pipeline:\n\n```bash\nmarktplaats-copy-qa ./description.md --require \"<term1>\" --require \"<term2>\" --variant \"<variant>\" --ad-json ./ad.json\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n# bewerk via Marktplaats UI/DOM\nmarktplaats-live-verify --ad-json ./ad.json --url \"<live-url>\" --update-ad-json\nmarktplaats-register-update --ad-json ./ad.json --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nAls live fetch de tekst niet ziet, gebruik `--text ./live-text.txt` met tekst uit de browser/accessibility snapshot.\n\n## Test De Skill\n\n```bash\nnpm test\n```\n\nDeze test moet groen zijn voordat je publiceert naar ClawHub.\n\n## Naslag\n\n- Publieke uitleg: `README.md`\n- Langere handleiding: `references/handleiding-nl.md`\n- Engelse guide: `references/guide-en.md`\n- Robuuste checklist: `references/robust-posting-checklist.md`\n\nFile v0.6.2:README.md\n\n# Marktplaats.nl Verkoopassistent\n\nDeze skill helpt je om een Marktplaats-advertentie netjes voor te bereiden, te plaatsen en achteraf te controleren.\n\nHet belangrijkste doel is simpel: een goede advertentie maken zonder half werk, zonder betaalde opties per ongeluk aan te zetten en zonder dat de tekst weer te kort, kaal of spammerig wordt.\n\nVanaf versie 0.6.0 is dit vooral een scriptmatige pipeline. De assistent krijgt dus niet alleen lange instructies, maar moet door harde checks heen: copy-QA, preflight, live-verificatie en register-update.\n\n## Wat doet deze skill?\n\n- Zoekt mee naar categorieën en vergelijkbare advertenties.\n- Helpt productinformatie te verwerken zonder dingen te verzinnen.\n- Schrijft een volle Nederlandse advertentietekst van ongeveer 3200 tot 3500 tekens.\n- Controleert de tekst voordat Marktplaats wordt ingevuld.\n- Werkt met een bestaande ingelogde Safari-sessie op macOS.\n- Begeleidt en controleert foto-upload via de normale Marktplaats-flow.\n- Houdt betaalde promoties standaard uit.\n- Controleert na het plaatsen of de advertentie echt live goed staat.\n- Bewaart lokaal wat er geplaatst is, inclusief tekstcheck en live controle.\n\nDeze skill is bedoeld voor normale verkoopadvertenties. Niet voor bulkposten, omzeilen van beveiliging, captcha's, loginproblemen of betaalflows.\n\n## Waarom is die tekstcheck zo streng?\n\nOmdat korte advertenties steeds terugkwamen als probleem.\n\nEen advertentie van een paar regels is snel gemaakt, maar meestal slecht vindbaar. Daarom zit er een harde controle in: de tekst moet lang genoeg zijn, genoeg inhoud hebben, natuurlijke zoekwoorden bevatten en geen los blok met `Zoektermen:` of keywordspam onderaan zetten.\n\nDe standaard is:\n\n- ongeveer 3200 tot 3500 tekens;\n- minimaal 7 duidelijke alinea's of onderdelen;\n- merk/model en productsoort moeten erin staan;\n- minimaal één kleine natuurlijke typefout/schrijfvariant in context, zoals `deur slot` of `buiten antenne`;\n- geen losse zoekwoordenlijst;\n- de laatste zin moet ook live zichtbaar zijn na opslaan.\n\nAls die check faalt, moet de advertentie eerst beter worden. Niet toch maar plaatsen.\n\n## Copy check draaien\n\nGebruik dit voordat je Marktplaats opent of een bestaande advertentie opslaat:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"KFV\" \\\n  --require \"motorslot\" \\\n  --variant \"deur slot\" \\\n  --ad-json ./ad.json\n```\n\nDe check schrijft het resultaat in `ad.json`. Alleen als `copyQuality.passed` op `true` staat, mag de tekst door naar Marktplaats.\nWil je twee minimale varianten afdwingen, herhaal dan `--variant` en gebruik `--min-variants 2`.\n\nVoor een snelle test van de tool zelf:\n\n```bash\nmarktplaats-copy-qa --self-test\n```\n\n## Preflight voor het plaatsen\n\nNa de copy check moet de advertentie door preflight:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nDeze check kijkt of `ad.json`, de omschrijving, foto's, bieden-instelling en copy-QA bij elkaar passen. Als de omschrijving na de copy check nog is aangepast, faalt preflight op de tekst-hash.\n\n## Live controleren na opslaan\n\nNa plaatsen of bewerken moet de live advertentie worden gecontroleerd:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --url \"https://www.marktplaats.nl/seller/view/...\" --update-ad-json\n```\n\nAls Marktplaats de tekst niet goed in de HTML meestuurt, gebruik je tekst uit de browser:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --text ./live-text.txt --update-ad-json\n```\n\nDeze check faalt als het begin van de omschrijving ontbreekt, de laatste zin ontbreekt, de tekst dubbel staat, alinea's live niet herkenbaar zijn, er toch een `Zoektermen:` blok zichtbaar is, of de live omschrijvingswindow domeinachtige tekst bevat.\n\n## Register bijwerken\n\nDaarna werk je het centrale register bij:\n\n```bash\nmarktplaats-register-update \\\n  --ad-json ./ad.json \\\n  --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json \\\n  --note \"Live gecontroleerd.\"\n```\n\nVoer register-updates niet parallel uit op hetzelfde bestand. De tool gebruikt een lock en stopt als er al een update loopt.\nStandaard weigert deze stap advertenties zonder geslaagde live-verificatie. Gebruik `--allow-unverified` alleen voor conceptadministratie.\n\n## Advertentie voorbereiden\n\nEen praktische map per advertentie werkt het prettigst:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/photos/\n```\n\nZet in `ad.json` in elk geval titel, prijs, categorie, foto's, status, live URL en het resultaat van de copy check. Zo kun je later terugvinden wat er is geplaatst en wanneer het live gecontroleerd is.\n\n## Plaatsen of bewerken\n\nDe normale volgorde:\n\n1. Maak lokaal titel, prijs, foto's en omschrijving klaar.\n2. Zoek productinformatie op als merk of model bekend is.\n3. Schrijf de omschrijving rijk, feitelijk en verkoopbaar.\n4. Draai `marktplaats-copy-qa`.\n5. Draai `marktplaats-ad-preflight`.\n6. Stop als een van de checks niet slaagt.\n7. Open pas daarna de Marktplaats plaats- of bewerkpagina.\n8. Controleer dat de gratis/basic route actief is.\n9. Upload foto's en controleer de fototeller.\n10. Controleer titel, prijs, bieden, foto's en laatste zin van de omschrijving.\n11. Sla op of plaats pas als de gebruiker daar opdracht voor gaf.\n12. Draai `marktplaats-live-verify`.\n13. Draai `marktplaats-register-update`.\n\nVoor kleinere modellen geldt: één stap uitvoeren, output lezen, dan pas de volgende stap. Geen coördinatenkliks, geen verborgen submit en geen betaal-/promotieroute zonder expliciet akkoord.\n\n## Gratis blijft gratis\n\nDeze skill kiest standaard geen betaalde opties.\n\nAls Marktplaats een betaalde promotie, topadvertentie, urgent-optie, bundel of betaalpagina toont, is dat een stopmoment. Alleen doorgaan als de gebruiker voor die specifieke advertentie expliciet zegt dat een betaalde optie mag.\n\n## Safari en privacy\n\nVoor echt plaatsen of bewerken gebruikt de skill een bestaande ingelogde Safari-sessie. Dat is handig, maar privacygevoelig.\n\nDaarom:\n\n- geen cookies printen;\n- geen sessietokens opslaan;\n- geen XSRF/auth-waarden loggen;\n- geen lokale privébestanden of advertentie-id's in voorbeelden zetten;\n- geen koperberichten sturen zonder aparte toestemming.\n\nDe browser mag als veilige sessiecontext gebruikt worden. De sessie zelf mag niet worden gelekt.\n\n## Zoek- en categoriehulpen\n\nZoeken:\n\n```bash\nmarktplaats-search \"4G antenne\"\n```\n\nCategorieën:\n\n```bash\nmarktplaats-categories\nmarktplaats-categories <parent-id>\n```\n\nFormulier inspecteren via de ingelogde browsercontext:\n\n```bash\nmarktplaats-place-probe --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nPlaatsingspagina rustig in Safari op de achtergrond openen en daarna proben:\n\n```bash\nmarktplaats-place-probe --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\n## Installeren en testen\n\n```bash\nnpm install -g .\nnpm test\n```\n\nNode.js 18 of nieuwer is nodig.\n\n## Wat deze skill niet doet\n\n- Geen bulkplaatsingen.\n- Geen captcha's of loginbeveiliging omzeilen.\n- Geen betaalde opties stil aanzetten.\n- Geen garanties verzinnen over werking, compleetheid of accessoires.\n- Geen privédata publiceren.\n- Geen berichten naar kopers sturen zonder expliciete toestemming.\n\n## Licentie\n\nMIT\n\nFile v0.6.2:_meta.json\n\n{\n  \"ownerId\": \"kn7ewt9n4xqy7yhf2bnykj7ssh882qa4\",\n  \"slug\": \"marktplaats-publisher\",\n  \"version\": \"0.6.2\",\n  \"publishedAt\": 1783554929396\n}\n\nFile v0.6.2:references/guide-en.md\n\n# Marktplaats Seller Assistant - English Guide\n\n## Name\n\n**Marktplaats Seller Assistant**\n\nTechnical skill key: `marktplaats`.\n\nThe name is intentionally broader than search. The skill supports the selling workflow: category selection, live field inspection, photo preparation/upload, local ad tracking, repost preparation, dry-run review, and publishing only after explicit confirmation.\n\n## Purpose\n\nThis skill helps an agent prepare, place, track and later repost Marktplaats advertisements safely and reliably. Its main value is that it inspects the current category-specific placement form before filling or submitting anything, then stores enough local metadata to revisit the ad later.\n\n## Capabilities\n\n- Search Marktplaats listings.\n- Fetch category and subcategory information.\n- Suggest the best category for an item.\n- Inspect the live placement form in a logged-in browser session.\n- Extract category-specific fields such as condition, brand, type, delivery, price and options.\n- Prepare resized, metadata-reduced photo copies where possible.\n- Guide and verify photo upload through the logged-in browser context.\n- Fill advertisement fields conservatively.\n- Keep paid features disabled by default.\n- Present a dry-run summary.\n- Publish only after explicit approval for that exact advertisement.\n- Report the success URL or validation errors after submission.\n- Track posted advertisements locally.\n- Mark expired or removed advertisements for reposting.\n- Use photos and short item descriptions from WhatsApp/iMessage as ad intake when the user asks.\n- Validate listing descriptions with the hard Copy Quality Gate before filling or publishing Marktplaats.\n\n## What The Skill Must Not Do\n\n- Do not publish or repost without explicit per-ad approval.\n- Do not enable paid options without separate approval.\n- Do not invent price, condition, or uncertain required fields.\n- Do not bypass login, captcha, WAF, or security checks.\n- Do not reply to buyers without separate permission.\n- Do not expose cookies, XSRF tokens, or session data.\n\n## Required Permissions\n\nFor search:\n\n- Network access to Marktplaats.\n- Node.js for the existing CLI tools.\n\nFor preparation:\n\n- Read access to local photo files provided by the user.\n- Read access to relevant WhatsApp/iMessage attachments when the user asks to use them.\n- Write access for ad records, photos and snapshots, preferably:\n  - `~/Documents/OpenClaw/Data/marktplaats/`\n  - `housekeeping/marktplaats-snapshots/`\n  - `housekeeping/marktplaats-test/`\n\nFor publishing:\n\n- A browser session where the user is already logged in to Marktplaats.\n- macOS automation through AppleScript or Peekaboo to use that browser context.\n- Access to the Marktplaats placement page.\n\nThe skill does not need the user's Marktplaats password. Authentication stays inside the browser.\n\n## Local Ad Register\n\nCentral register:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nOptional per-ad directory:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/\n```\n\nRecommended contents:\n\n- `ad.json`: ad id, URL, status, price, category, source and repost metadata.\n- `description.md`: latest listing description.\n- `photos/originals/`: source photos.\n- `photos/processed/`: resized/metadata-reduced publish photos.\n- `snapshots/`: form or submit snapshots.\n\nImportant statuses:\n\n- `draft`\n- `pending_approval`\n- `active`\n- `removed`\n- `expired`\n- `needs_repost`\n- `reposted`\n- `test`\n\nUpdate the register after every placement, validation error, removal, status check or repost.\n\n## Reposting After Expiry\n\nMarktplaats can change its rules. Check the current listing duration or ad status before relying on dates.\n\nStandard flow:\n\n1. Read `advertenties.json`.\n2. Find active ads with past `renewAfter`/`expiresAt` values, or ads that no longer appear active.\n3. Verify the ad status.\n4. Set `needs_repost` when reposting makes sense.\n5. Build a fresh dry-run from the existing text/photos, with current category and form checks.\n6. Publish only after explicit user approval.\n7. Add the new ad id to the register and keep the old ad in `repostHistory`.\n\nA cron/heartbeat may report that ads need reposting, but it must not publish automatically.\n\n## Intake From WhatsApp Or iMessage\n\nWhen the user sends photos and says what the item is:\n\n1. Read only the relevant messages/attachments.\n2. Store photos in the ad directory.\n3. Create safe publishing copies.\n4. Record the source, such as channel, chat id, message id and timestamp.\n5. Identify the item, brand/model and visible details.\n6. Ask for missing essentials: price, condition, pickup/shipping, defects, missing parts.\n7. Research product information online.\n8. Choose a category and inspect the current form.\n9. Write a strong SEO listing of roughly 3200-3500 characters.\n10. Run `marktplaats-copy-qa` with product terms and a natural search variant.\n11. Present a dry-run.\n12. Publish only after explicit approval.\n\nFor WhatsApp/iMessage: reading/analyzing is allowed when the user asks for this task; sending replies to other people or buyers requires separate permission.\n\n## Standard Workflow\n\n### 1. Understand The Item\n\nDetermine:\n\n- item type;\n- brand/model/type;\n- condition;\n- asking price;\n- pickup/shipping preference;\n- included accessories;\n- defects or important notes;\n- available photos.\n\nAsk the user if essential information is missing.\n\n### 2. Find Candidate Categories\n\nUse:\n\n```bash\nmarktplaats-categories --json\nmarktplaats-categories <parent-id> --json\nmarktplaats-search \"<product name>\" --json -n 10\n```\n\nChoose based on:\n\n- comparable listings;\n- suitable category attributes;\n- free listing availability;\n- buyer discoverability.\n\nExplain the chosen category in the dry-run.\n\n### 3. Copy Quality Gate\n\nBefore filling Marktplaats, run:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<brand-or-type>\" \\\n  --require \"<product-kind>\" \\\n  --variant \"<natural search variant>\" \\\n  --ad-json ./ad.json\n```\n\nStop if the command fails or if `ad.json.copyQuality.passed` is not `true`.\n\nHard requirements:\n\n- default length 3200-3500 characters;\n- hard lower stop at 2800 characters;\n- at least 7 substantial sections/paragraphs;\n- no `Zoektermen:`, `Keywords:`, `SEO:` or keyword dump;\n- natural SEO terms in prose;\n- at least one subtle product-relevant typo/spelling/search variant in context.\n\n### 4. Inspect The Live Form\n\nOpen the placement page for the chosen category and capture a fresh snapshot with the probe:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nOr open the placement page in Safari in the background before probing the same session:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\nInspect:\n\n- `form.action` (usually `https://www.marktplaats.nl/plaats/ads`);\n- category identifiers;\n- presence of an XSRF token, not the value;\n- hidden form values;\n- title and description fields;\n- price fields;\n- condition fields;\n- category attributes;\n- delivery fields;\n- postcode/contact fields;\n- paid feature fields;\n- selected bundle.\n- `security.challengeSignals` for login, captcha, MFA, WAF, or payment/promotion signals.\n\nA `curl` probe on `/plaats` may return `401` without a session cookie. That is expected. In that case, use the logged-in browser DOM as the source of truth instead of manual UI clicking.\n\n### 4. Fill Fields Conservatively\n\n- Keep the title short and specific.\n- Keep the description factual.\n- Fill condition only when reasonably certain.\n- Use the user's price or ask for one.\n- Select multi-value attributes only when clearly applicable.\n- Default delivery to pickup unless shipping is requested.\n\n### 5. Enforce Free Listing\n\nBefore publishing, verify:\n\n- free bundle selected;\n- no urgent/homepage/promoted features enabled;\n- no paid bundle selected;\n- no payment page shown.\n\nStop if Marktplaats asks for payment unexpectedly.\n\n### 6. Prepare Photos\n\nCreate temporary resized copies when possible:\n\n```bash\nmkdir -p housekeeping/marktplaats-test\nsips -Z 1600 -s format jpeg input.jpg --out housekeeping/marktplaats-test/photo-1.jpg\n```\n\nCheck for obvious EXIF/GPS metadata where possible.\n\n### 7. Upload Photos\n\nThe proven browser-context upload uses:\n\n- endpoint: `/plaats/api/image/upload`\n- method: `POST`\n- FormData fields:\n  - `name`\n  - `imageData`\n- header:\n  - `x-mp-xsrf`\n\nPreferred local helper:\n\nUpload the photos in the live flow and then read back the generated `images.ids` / hidden fields through the probe. Use the browser only as a session carrier, not to guess an upload path by hand. If upload or photo count cannot be verified, stop.\n\n### 8. Dry-Run Summary\n\nAlways show before publishing:\n\n```text\nCategory: ...\nReason: ...\nTitle: ...\nPrice: ...\nCondition: ...\nDelivery: ...\nPhotos: ...\nFree listing: yes/no\nPaid options: none\nUncertain fields: ...\nAfter approval: publish to Marktplaats\n```\n\n### 9. Publish\n\nPublish only after explicit approval. After submission:\n\n- report the success URL;\n- report the advertisement id/link;\n- summarize validation errors if any;\n- stop if a payment page appears;\n- run live verification;\n- update the local ad register.\n\n## Testing Protocol\n\nRecommended test period:\n\n1. Start with one dummy/test advertisement.\n2. Try 2-3 low-risk real ads.\n3. Check category, price, photos and free options.\n4. Confirm that ads can be removed easily.\n5. Note problematic categories/fields.\n6. Test reposting from the local register.\n7. Test intake from WhatsApp/iMessage photos.\n8. Consider ClawHub publication only after testing.\n\n## ClawHub Publication Notes\n\nA public listing should clearly state:\n\n- publishing and reposting require explicit approval;\n- the user must be logged in themselves;\n- the skill does not bypass login/captcha/security checks;\n- paid options are off by default;\n- local ad tracking may contain personal photos/data and must be treated as private;\n- required local tools and permissions;\n- Marktplaats flows may change;\n- users remain responsible for ad content and platform compliance.\n\nFile v0.6.2:references/handleiding-nl.md\n\n# Marktplaats Verkoopassistent - Nederlandse Handleiding\n\n## Naam\n\n**Marktplaats Verkoopassistent**\n\nTechnische skill-key: `marktplaats`.\n\nDeze naam is bewust breder dan alleen zoeken. De skill helpt bij het volledige verkoopproces: categorie kiezen, velden bepalen, foto's voorbereiden/uploaden, lokaal bijhouden, herplaatsing voorbereiden, dry-run maken en pas na akkoord publiceren.\n\n## Doel\n\nDe skill helpt een gebruiker of agent om Marktplaats-advertenties betrouwbaar en veilig voor te bereiden, te plaatsen en later terug te vinden voor controle of herplaatsing. De belangrijkste verbetering ten opzichte van handmatig werken is dat de agent eerst de actuele categorievelden uitleest en daarna pas een advertentie invult. Daarnaast houdt de skill lokaal bij wat geplaatst is, met welke foto's en tekst, zodat verlopen advertenties later opnieuw voorbereid kunnen worden.\n\n## Wat De Skill Kan\n\n- Marktplaats doorzoeken op vergelijkbare advertenties.\n- Categorieën en subcategorieën ophalen.\n- Een beste categorie voorstellen voor een item.\n- Een live plaatsingsformulier uitlezen via de browser.\n- Categorie-specifieke velden verzamelen, zoals conditie, merk, type, maat, levering, prijs en extra opties.\n- Foto's verkleinen en metadata-arm maken waar mogelijk.\n- Foto-upload begeleiden en controleren via de ingelogde Marktplaats-browsercontext.\n- Advertentiedata invullen in het formulier.\n- Betaalde opties standaard uitschakelen.\n- Een dry-run samenvatting tonen.\n- Na expliciet akkoord een advertentie publiceren.\n- Na publicatie de success-URL of foutmelding rapporteren.\n- Geplaatste advertenties lokaal administreren.\n- Verlopen of verwijderde advertenties markeren voor herplaatsing.\n- Foto's en korte omschrijvingen uit WhatsApp/iMessage als advertentie-intake gebruiken wanneer de gebruiker daarom vraagt.\n- Advertentieteksten vóór publicatie verplicht controleren met de Copy Quality Gate.\n\n## Wat De Skill Niet Zelfstandig Mag\n\n- Geen advertentie publiceren of herplaatsen zonder expliciet akkoord per advertentie.\n- Geen betaalde plaatsing of promotie inschakelen zonder apart akkoord.\n- Geen prijs verzinnen als de gebruiker geen prijs heeft gegeven.\n- Geen conditie kiezen als die onzeker is.\n- Geen captcha, login, WAF of beveiligingscontrole omzeilen.\n- Geen berichten beantwoorden aan kopers zonder aparte toestemming.\n- Geen cookies, XSRF-tokens of sessiegegevens delen.\n\n## Benodigde Rechten\n\nVoor zoeken:\n\n- Netwerktoegang naar Marktplaats.\n- Node.js voor de CLI-tools.\n\nVoor advertentievoorbereiding:\n\n- Leesrechten op lokale fotobestanden.\n- Leesrechten op relevante WhatsApp/iMessage-bijlagen wanneer de gebruiker vraagt die te gebruiken.\n- Schrijfrechten voor advertentiegegevens, foto's en snapshots, bij voorkeur:\n  - `~/Documents/OpenClaw/Data/marktplaats/`\n  - `housekeeping/marktplaats-snapshots/`\n  - `housekeeping/marktplaats-test/`\n\nVoor plaatsen:\n\n- Een browser waarin de gebruiker al is ingelogd op Marktplaats.\n- macOS automation via AppleScript of Peekaboo om de browsercontext te gebruiken.\n- Toegang tot de Marktplaats plaatsingspagina.\n\nBelangrijk: de skill heeft geen Marktplaats-wachtwoord nodig. Login blijft bij de gebruiker/browser.\n\n## Lokale Advertentieadministratie\n\nCentrale administratie:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nPer advertentie kan een eigen map worden gebruikt:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/\n```\n\nAanbevolen inhoud:\n\n- `ad.json`: advertentie-id, URL, status, prijs, categorie, bron en herplaatsinformatie.\n- `description.md`: laatst gebruikte advertentietekst.\n- `photos/originals/`: bronfoto's.\n- `photos/processed/`: verkleinde/metadata-arme publicatiefoto's.\n- `snapshots/`: formulier- of submit-snapshots.\n\nBelangrijke statussen:\n\n- `draft`\n- `pending_approval`\n- `active`\n- `removed`\n- `expired`\n- `needs_repost`\n- `reposted`\n- `test`\n\nNa elke plaatsing, foutmelding, verwijdering, statuscheck of herplaatsing wordt het register bijgewerkt.\n\n## Herplaatsing Na Verlopen\n\nMarktplaats kan regels wijzigen. Controleer daarom de actuele looptijd of advertentiestatus voordat je automatisch conclusies trekt.\n\nStandaardflow:\n\n1. Lees `advertenties.json`.\n2. Zoek actieve advertenties met verlopen `renewAfter`/`expiresAt` of advertenties die niet meer zichtbaar lijken.\n3. Controleer de advertentiestatus.\n4. Zet ze op `needs_repost` als herplaatsing zinvol is.\n5. Maak een nieuwe dry-run op basis van de bestaande tekst/foto's, met verse categorie- en formuliercheck.\n6. Publiceer pas na expliciet akkoord van de gebruiker.\n7. Voeg de nieuwe advertentie-id toe aan het register en bewaar de oude in `repostHistory`.\n\nEen cron/heartbeat mag melden dat advertenties herplaatst moeten worden, maar mag niet zelfstandig publiceren.\n\n## Intake Vanuit WhatsApp Of iMessage\n\nWanneer de gebruiker foto's stuurt en zegt wat het is:\n\n1. Lees alleen de relevante berichten/bijlagen.\n2. Sla de foto's lokaal op in de advertentiemap.\n3. Maak veilige publicatiekopieën.\n4. Leg de bron vast, zoals kanaal, chat-id, message-id en tijdstip.\n5. Herken item, merk/model en zichtbare details.\n6. Vraag ontbrekende kerngegevens: prijs, conditie, ophalen/verzenden, gebreken, missende onderdelen.\n7. Zoek productinformatie online.\n8. Kies categorie en inspecteer het actuele formulier.\n9. Schrijf een sterke SEO-advertentie van circa 3200-3500 tekens.\n10. Draai `marktplaats-copy-qa` met producttermen en een natuurlijke zoekvariant.\n11. Toon dry-run.\n12. Plaats alleen na expliciet akkoord.\n\nVoor WhatsApp/iMessage geldt: lezen/analyseren mag als de gebruiker daarom vraagt; antwoorden naar anderen of kopers sturen alleen na aparte toestemming.\n\n## Standaard Stappenplan\n\n### 1. Item Begrijpen\n\nBepaal:\n\n- wat het item is;\n- merk/type/model;\n- conditie;\n- gewenste prijs;\n- ophalen/verzenden;\n- meegeleverde onderdelen;\n- gebreken of bijzonderheden;\n- beschikbare foto's.\n\nAls prijs, conditie of essentieel detail ontbreekt: vraag de gebruiker.\n\n### 2. Categorie-Kandidaten Zoeken\n\nGebruik:\n\n```bash\nmarktplaats-categories --json\nmarktplaats-categories <parent-id> --json\nmarktplaats-search \"<productnaam>\" --json -n 10\n```\n\nKies de categorie op basis van:\n\n- bestaande vergelijkbare advertenties;\n- passende attributen;\n- gratis plaatsingsmogelijkheid;\n- logische vindbaarheid voor kopers.\n\nMotiveer de keuze in de dry-run.\n\n### 3. Copy Quality Gate\n\nVoordat Marktplaats wordt ingevuld:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<merk-of-type>\" \\\n  --require \"<productsoort>\" \\\n  --variant \"<natuurlijke zoekvariant>\" \\\n  --ad-json ./ad.json\n```\n\nStop als de command faalt of als `ad.json.copyQuality.passed` niet `true` is.\n\nHarde eisen:\n\n- standaard 3200-3500 tekens;\n- absolute ondergrens 2800 tekens;\n- minimaal 7 substantiële secties/alinea's;\n- geen `Zoektermen:`, `Keywords:` of keyworddump;\n- natuurlijke SEO-termen in lopende tekst;\n- minimaal één subtiele, productrelevante spelfout/schrijfvariant in context.\n\n### 4. Live Plaatsingsformulier Inspecteren\n\nOpen de plaatsingspagina voor de gekozen categorie en maak een snapshot met de probe:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nOf open de plaatsingspagina in Safari op de achtergrond en probe daarna dezelfde sessie:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\nControleer:\n\n- `form.action` (meestal `https://www.marktplaats.nl/plaats/ads`);\n- categorievelden (`l1`, `l2`, `bucket`);\n- aanwezigheid van een XSRF-token, niet de waarde;\n- hidden formulierwaarden;\n- titel/omschrijving;\n- prijsvelden;\n- conditievelden;\n- categorie-attributen;\n- leveringsvelden;\n- postcode/contact;\n- betaalde opties;\n- geselecteerde bundle.\n- `security.challengeSignals` voor login, captcha, MFA, WAF of betaal-/promotiesignalen.\n\nEen `curl`-probe op `/plaats` kan `401` geven als er geen sessiecookie wordt meegegeven. Dat is normaal: gebruik in dat geval de ingelogde browser-DOM als bron van waarheid, niet handmatige UI-kliks.\n\nGebruik voor authenticated requests zonder cookies te exporteren:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser-fetch --url https://www.marktplaats.nl/plaats\n```\n\nDeze route gebruikt Safari's bestaande sessie via `XMLHttpRequest` met credentials. Cookies en sessietokens blijven in Safari en worden niet gelogd.\n\n### 5. Velden Invullen\n\nGebruik conservatieve mapping:\n\n- Titel kort en specifiek.\n- Beschrijving feitelijk, geen overdreven verkooppraat.\n- Conditie alleen invullen als redelijk zeker.\n- Prijs alleen van de gebruiker of expliciet akkoord.\n- Multi-selects alleen aanvinken als zeker passend.\n- Levering standaard ophalen, tenzij de gebruiker verzending wil.\n\n### 6. Gratis Advertentie Afdwingen\n\nControleer vóór publicatie:\n\n- gratis bundle geselecteerd;\n- geen urgent/etalage/homepage/promotie;\n- geen betaalpagina;\n- geen onverwachte kosten.\n\nAls Marktplaats toch kosten toont: stoppen en rapporteren.\n\n### 7. Foto's Voorbereiden\n\nMaak bij voorkeur tijdelijke kopieën:\n\n```bash\nmkdir -p housekeeping/marktplaats-test\nsips -Z 1600 -s format jpeg input.jpg --out housekeeping/marktplaats-test/photo-1.jpg\n```\n\nControleer waar mogelijk of GPS/EXIF niet meer zichtbaar is.\n\n### 8. Foto's Uploaden\n\nGebruik de bewezen browsercontext-route. De Marktplaats frontend verwacht:\n\n- endpoint: `/plaats/api/image/upload`\n- method: `POST`\n- FormData velden:\n  - `name`\n  - `imageData`\n- header:\n  - `x-mp-xsrf`\n\nUpload de foto's in de live flow en lees daarna de gegenereerde `images.ids`/hidden fields terug uit de probe. Gebruik de browser alleen als sessiedrager, niet om handmatig een uploadpad te raden. Als upload of fototeller niet te verifieren is, stoppen.\n\n### 9. Dry-Run Tonen\n\nAltijd tonen vóór publiceren:\n\n```text\nCategorie: ...\nWaarom deze categorie: ...\nTitel: ...\nPrijs: ...\nConditie: ...\nLevering: ...\nFoto's: ...\nGratis advertentie: ja/nee\nBetaalde opties: geen\nOnzekere velden: ...\nNa akkoord: publiceren op Marktplaats\n```\n\n### 9. Publiceren\n\nAlleen na expliciet akkoord. Na submit:\n\n- success-redirect rapporteren;\n- advertentie-id/link rapporteren;\n- validatiefouten kort samenvatten;\n- bij betaalpagina stoppen;\n- daarna live-verificatie draaien;\n- lokale advertentieadministratie bijwerken.\n\n## Testprotocol\n\nAanbevolen testperiode:\n\n1. Begin met 1 dummy/testadvertentie.\n2. Test daarna 2-3 echte goedkope advertenties.\n3. Controleer of categorie, prijs, foto's en gratis opties kloppen.\n4. Controleer of advertenties makkelijk te verwijderen zijn.\n5. Noteer welke categorieën/velden lastig zijn.\n6. Test daarna herplaatsing vanuit het lokale register.\n7. Test daarna intake vanuit WhatsApp/iMessage-foto's.\n8. Pas daarna publicatie op ClawHub overwegen.\n\n## Publicatie Op ClawHub\n\nVoor publicatie moet de skill duidelijk vermelden:\n\n- dat publiceren en herplaatsen alleen na expliciet akkoord mag;\n- dat de gebruiker zelf ingelogd moet zijn;\n- dat de skill geen login/captcha omzeilt;\n- dat betaalde opties standaard uit staan;\n- dat lokaal advertentiebeheer persoonsgegevens/foto's kan bevatten en dus privé behandeld moet worden;\n- welke lokale tools nodig zijn;\n- dat Marktplaats-flows kunnen wijzigen;\n- dat de gebruiker verantwoordelijk blijft voor advertentie-inhoud en platformregels.\n\nFile v0.6.2:references/robust-posting-checklist.md\n\n- Work linearly and deterministically.\n- Run `marktplaats-copy-qa` before touching Marktplaats; stop if it fails.\n- Keep descriptions around 3200-3500 characters, with a hard stop below 2800.\n- Use natural SEO in prose; never publish `Zoektermen:` or keyword-dump footers.\n- Include one subtle product-relevant typo/search variant in context.\n- Prefer one dedicated browser window/tab for a single ad flow.\n- Avoid extra screens, helper windows, and parallel UI actions.\n- Rotate photos only when preview/orientation shows it is needed.\n- Use ASCII-safe text if live rendering shows mojibake.\n- Verify live seller-view as source of truth.\n- Keep the flow understandable for smaller models like GPT-5.4-mini.\n- One step, one verification, then next step.\n- Use `marktplaats-place-probe --browser --open-background <url>` when Safari can stay in the background.\n- Register update only after successful live verification, unless explicitly tracking a draft with `--allow-unverified`.\n\nFile v0.6.2:skill-card.md\n\n## Description: <br>\nHelps agents prepare, quality-check, place or edit, live-verify, and locally register Marktplaats advertisements. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[roelbroersma](https://clawhub.ai/user/roelbroersma) <br>\n\n### License/Terms of Use: <br>\nMIT <br>\n\n\n## Use Case: <br>\nExternal users and agents use this skill to prepare normal Marktplaats sales listings, run copy and preflight gates, verify live ads, and maintain local ad records. It is designed for explicit per-ad approval rather than bulk posting or unattended publishing. <br>\n\n### Deployment Geography for Use: <br>\nNetherlands <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can work through a logged-in Safari session and local ad records, making account context, listing details, snapshots, and file paths privacy-sensitive. <br>\nMitigation: Review every publish, edit, and payment-related step before approval; keep snapshots and registers private; do not expose cookies, tokens, auth values, or local private paths. <br>\nRisk: Automated listing assistance could publish incorrect copy, lose formatting, or enable paid options if checks are skipped. <br>\nMitigation: Run copy-QA, preflight, live verification, and register update in sequence; stop on failed gates; require explicit user approval for each publication, edit, or paid option. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/roelbroersma/skills/marktplaats-publisher) <br>\n- [README](README.md) <br>\n- [English guide](references/guide-en.md) <br>\n- [Nederlandse handleiding](references/handleiding-nl.md) <br>\n- [Robust posting checklist](references/robust-posting-checklist.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with shell command examples and local JSON ad records] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May create or update local ad records, verification snapshots, and register entries when the bundled commands are run.] <br>\n\n## Skill Version(s): <br>\n0.6.2 (source: package.json and server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.6.2:package.json\n\n{\n  \"name\": \"marktplaats-publisher\",\n  \"version\": \"0.6.2\",\n  \"description\": \"Maak en controleer Marktplaats-advertenties met scriptmatige preflight, live-verificatie en register-update.\",\n  \"type\": \"module\",\n  \"bin\": {\n    \"marktplaats-search\": \"./bin/marktplaats-search.js\",\n    \"marktplaats-categories\": \"./bin/marktplaats-categories.js\",\n    \"marktplaats-place-probe\": \"./scripts/marktplaats-place-probe.js\",\n    \"marktplaats-copy-qa\": \"./scripts/marktplaats-copy-qa.js\",\n    \"marktplaats-ad-preflight\": \"./scripts/marktplaats-ad-preflight.js\",\n    \"marktplaats-live-verify\": \"./scripts/marktplaats-live-verify.js\",\n    \"marktplaats-register-update\": \"./scripts/marktplaats-register-update.js\"\n  },\n  \"exports\": \"./src/index.js\",\n  \"files\": [\n    \"bin\",\n    \"src\",\n    \"scripts\",\n    \"references\",\n    \"README.md\",\n    \"LICENSE\",\n    \"SKILL.md\"\n  ],\n  \"scripts\": {\n    \"test\": \"node ./bin/marktplaats-search.js --help && node ./bin/marktplaats-categories.js --help && node ./scripts/marktplaats-place-probe.js --self-test && node ./scripts/marktplaats-copy-qa.js --self-test && node ./scripts/marktplaats-ad-preflight.js --self-test && node ./scripts/marktplaats-live-verify.js --self-test && node ./scripts/marktplaats-register-update.js --self-test\"\n  },\n  \"keywords\": [\n    \"marktplaats\",\n    \"classifieds\",\n    \"publisher\",\n    \"posting\",\n    \"search\",\n    \"cli\",\n    \"copy-qa\",\n    \"self-healing\"\n  ],\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"license\": \"MIT\",\n  \"author\": \"OpenClaw community\"\n}\n\nArchive v0.6.1: 17 files, 48886 bytes\n\nFiles: _meta.json (140b), bin/marktplaats-categories.js (2982b), bin/marktplaats-search.js (8020b), package.json (1504b), README.md (7412b), references/guide-en.md (10165b), references/handleiding-nl.md (11376b), references/robust-posting-checklist.md (981b), scripts/marktplaats-ad-preflight.js (12971b), scripts/marktplaats-copy-qa.js (14188b), scripts/marktplaats-live-verify.js (17066b), scripts/marktplaats-place-probe.js (20555b), scripts/marktplaats-register-update.js (9233b), skill-card.md (2684b), SKILL.md (1778b), src/api.js (14739b), src/index.js (160b)\n\nFile v0.6.1:SKILL.md\n\n---\nname: \"marktplaats-publisher\"\ndescription: \"Marktplaats publisher 0.6.1: strictere gates en mini-model flow.\"\nmetadata: {\"clawdbot\":{\"emoji\":\"🇳🇱\",\"requires\":{\"bins\":[\"node\"]}}}\n---\n\n# marktplaats-publisher 0.6.1 update\n\nApplied update to the live skill files before publishing.\n\n## Changes\n\n- Removed unsupported `homepage` frontmatter so public skill validation passes.\n- Bumped package and skill metadata to `0.6.1`.\n- Included `references/` in `package.json` so referenced docs are packaged.\n- Tightened `SKILL.md`, README, and references for smaller models: one phase, one verification, then next phase.\n- Clarified that scripts are gates and UI/publication remains browser work with readback verification.\n- Added explicit guidance for one or two subtle product-relevant typo/search variants.\n- Added `marktplaats-copy-qa --min-variants` support.\n- Added `marktplaats-place-probe --open-background URL --wait-ms N` to open Safari in the background before probing.\n- Changed curl probe default body retention to `--body-limit 0` for privacy.\n- Added security/payment signal detection to place probes without logging page body text.\n- Made live verification accept `<br>`/single-newline paragraph preservation while still rejecting flat one-line descriptions.\n- Added live description-window domain/email/URL detection.\n- Stored live verification `passed` and live website reference evidence in `ad.json`.\n- Made `marktplaats-register-update` block by default unless live verification succeeded; `--allow-unverified` is explicit and intended only for drafts.\n\n## Validation\n\n- `npm test` passed.\n- `python3 .../quick_validate.py /Users/roelbroersma/.openclaw/workspace/skills/marktplaats` passed.\n- `npm pack --dry-run` shows `references/` included in the package.\n\nFile v0.6.1:README.md\n\n# Marktplaats.nl Verkoopassistent\n\nDeze skill helpt je om een Marktplaats-advertentie netjes voor te bereiden, te plaatsen en achteraf te controleren.\n\nHet belangrijkste doel is simpel: een goede advertentie maken zonder half werk, zonder betaalde opties per ongeluk aan te zetten en zonder dat de tekst weer te kort, kaal of spammerig wordt.\n\nVanaf versie 0.6.0 is dit vooral een scriptmatige pipeline. De assistent krijgt dus niet alleen lange instructies, maar moet door harde checks heen: copy-QA, preflight, live-verificatie en register-update.\n\n## Wat doet deze skill?\n\n- Zoekt mee naar categorieën en vergelijkbare advertenties.\n- Helpt productinformatie te verwerken zonder dingen te verzinnen.\n- Schrijft een volle Nederlandse advertentietekst van ongeveer 3200 tot 3500 tekens.\n- Controleert de tekst voordat Marktplaats wordt ingevuld.\n- Werkt met een bestaande ingelogde Safari-sessie op macOS.\n- Begeleidt en controleert foto-upload via de normale Marktplaats-flow.\n- Houdt betaalde promoties standaard uit.\n- Controleert na het plaatsen of de advertentie echt live goed staat.\n- Bewaart lokaal wat er geplaatst is, inclusief tekstcheck en live controle.\n\nDeze skill is bedoeld voor normale verkoopadvertenties. Niet voor bulkposten, omzeilen van beveiliging, captcha's, loginproblemen of betaalflows.\n\n## Waarom is die tekstcheck zo streng?\n\nOmdat korte advertenties steeds terugkwamen als probleem.\n\nEen advertentie van een paar regels is snel gemaakt, maar meestal slecht vindbaar. Daarom zit er een harde controle in: de tekst moet lang genoeg zijn, genoeg inhoud hebben, natuurlijke zoekwoorden bevatten en geen los blok met `Zoektermen:` of keywordspam onderaan zetten.\n\nDe standaard is:\n\n- ongeveer 3200 tot 3500 tekens;\n- minimaal 7 duidelijke alinea's of onderdelen;\n- merk/model en productsoort moeten erin staan;\n- minimaal één kleine natuurlijke typefout/schrijfvariant in context, zoals `deur slot` of `buiten antenne`;\n- geen losse zoekwoordenlijst;\n- de laatste zin moet ook live zichtbaar zijn na opslaan.\n\nAls die check faalt, moet de advertentie eerst beter worden. Niet toch maar plaatsen.\n\n## Copy check draaien\n\nGebruik dit voordat je Marktplaats opent of een bestaande advertentie opslaat:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"KFV\" \\\n  --require \"motorslot\" \\\n  --variant \"deur slot\" \\\n  --ad-json ./ad.json\n```\n\nDe check schrijft het resultaat in `ad.json`. Alleen als `copyQuality.passed` op `true` staat, mag de tekst door naar Marktplaats.\nWil je twee minimale varianten afdwingen, herhaal dan `--variant` en gebruik `--min-variants 2`.\n\nVoor een snelle test van de tool zelf:\n\n```bash\nmarktplaats-copy-qa --self-test\n```\n\n## Preflight voor het plaatsen\n\nNa de copy check moet de advertentie door preflight:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nDeze check kijkt of `ad.json`, de omschrijving, foto's, bieden-instelling en copy-QA bij elkaar passen. Als de omschrijving na de copy check nog is aangepast, faalt preflight op de tekst-hash.\n\n## Live controleren na opslaan\n\nNa plaatsen of bewerken moet de live advertentie worden gecontroleerd:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --url \"https://www.marktplaats.nl/seller/view/...\" --update-ad-json\n```\n\nAls Marktplaats de tekst niet goed in de HTML meestuurt, gebruik je tekst uit de browser:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --text ./live-text.txt --update-ad-json\n```\n\nDeze check faalt als het begin van de omschrijving ontbreekt, de laatste zin ontbreekt, de tekst dubbel staat, alinea's live niet herkenbaar zijn, er toch een `Zoektermen:` blok zichtbaar is, of de live omschrijvingswindow domeinachtige tekst bevat.\n\n## Register bijwerken\n\nDaarna werk je het centrale register bij:\n\n```bash\nmarktplaats-register-update \\\n  --ad-json ./ad.json \\\n  --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json \\\n  --note \"Live gecontroleerd.\"\n```\n\nVoer register-updates niet parallel uit op hetzelfde bestand. De tool gebruikt een lock en stopt als er al een update loopt.\nStandaard weigert deze stap advertenties zonder geslaagde live-verificatie. Gebruik `--allow-unverified` alleen voor conceptadministratie.\n\n## Advertentie voorbereiden\n\nEen praktische map per advertentie werkt het prettigst:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<advertentie-slug>/photos/\n```\n\nZet in `ad.json` in elk geval titel, prijs, categorie, foto's, status, live URL en het resultaat van de copy check. Zo kun je later terugvinden wat er is geplaatst en wanneer het live gecontroleerd is.\n\n## Plaatsen of bewerken\n\nDe normale volgorde:\n\n1. Maak lokaal titel, prijs, foto's en omschrijving klaar.\n2. Zoek productinformatie op als merk of model bekend is.\n3. Schrijf de omschrijving rijk, feitelijk en verkoopbaar.\n4. Draai `marktplaats-copy-qa`.\n5. Draai `marktplaats-ad-preflight`.\n6. Stop als een van de checks niet slaagt.\n7. Open pas daarna de Marktplaats plaats- of bewerkpagina.\n8. Controleer dat de gratis/basic route actief is.\n9. Upload foto's en controleer de fototeller.\n10. Controleer titel, prijs, bieden, foto's en laatste zin van de omschrijving.\n11. Sla op of plaats pas als de gebruiker daar opdracht voor gaf.\n12. Draai `marktplaats-live-verify`.\n13. Draai `marktplaats-register-update`.\n\nVoor kleinere modellen geldt: één stap uitvoeren, output lezen, dan pas de volgende stap. Geen coördinatenkliks, geen verborgen submit en geen betaal-/promotieroute zonder expliciet akkoord.\n\n## Gratis blijft gratis\n\nDeze skill kiest standaard geen betaalde opties.\n\nAls Marktplaats een betaalde promotie, topadvertentie, urgent-optie, bundel of betaalpagina toont, is dat een stopmoment. Alleen doorgaan als de gebruiker voor die specifieke advertentie expliciet zegt dat een betaalde optie mag.\n\n## Safari en privacy\n\nVoor echt plaatsen of bewerken gebruikt de skill een bestaande ingelogde Safari-sessie. Dat is handig, maar privacygevoelig.\n\nDaarom:\n\n- geen cookies printen;\n- geen sessietokens opslaan;\n- geen XSRF/auth-waarden loggen;\n- geen lokale privébestanden of advertentie-id's in voorbeelden zetten;\n- geen koperberichten sturen zonder aparte toestemming.\n\nDe browser mag als veilige sessiecontext gebruikt worden. De sessie zelf mag niet worden gelekt.\n\n## Zoek- en categoriehulpen\n\nZoeken:\n\n```bash\nmarktplaats-search \"4G antenne\"\n```\n\nCategorieën:\n\n```bash\nmarktplaats-categories\nmarktplaats-categories <parent-id>\n```\n\nFormulier inspecteren via de ingelogde browsercontext:\n\n```bash\nmarktplaats-place-probe --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nPlaatsingspagina rustig in Safari op de achtergrond openen en daarna proben:\n\n```bash\nmarktplaats-place-probe --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\n## Installeren en testen\n\n```bash\nnpm install -g .\nnpm test\n```\n\nNode.js 18 of nieuwer is nodig.\n\n## Wat deze skill niet doet\n\n- Geen bulkplaatsingen.\n- Geen captcha's of loginbeveiliging omzeilen.\n- Geen betaalde opties stil aanzetten.\n- Geen garanties verzinnen over werking, compleetheid of accessoires.\n- Geen privédata publiceren.\n- Geen berichten naar kopers sturen zonder expliciete toestemming.\n\n## Licentie\n\nMIT\n\nFile v0.6.1:_meta.json\n\n{\n  \"ownerId\": \"kn7ewt9n4xqy7yhf2bnykj7ssh882qa4\",\n  \"slug\": \"marktplaats-publisher\",\n  \"version\": \"0.6.1\",\n  \"publishedAt\": 1783554806812\n}\n\nFile v0.6.1:references/guide-en.md\n\n# Marktplaats Seller Assistant - English Guide\n\n## Name\n\n**Marktplaats Seller Assistant**\n\nTechnical skill key: `marktplaats`.\n\nThe name is intentionally broader than search. The skill supports the selling workflow: category selection, live field inspection, photo preparation/upload, local ad tracking, repost preparation, dry-run review, and publishing only after explicit confirmation.\n\n## Purpose\n\nThis skill helps an agent prepare, place, track and later repost Marktplaats advertisements safely and reliably. Its main value is that it inspects the current category-specific placement form before filling or submitting anything, then stores enough local metadata to revisit the ad later.\n\n## Capabilities\n\n- Search Marktplaats listings.\n- Fetch category and subcategory information.\n- Suggest the best category for an item.\n- Inspect the live placement form in a logged-in browser session.\n- Extract category-specific fields such as condition, brand, type, delivery, price and options.\n- Prepare resized, metadata-reduced photo copies where possible.\n- Guide and verify photo upload through the logged-in browser context.\n- Fill advertisement fields conservatively.\n- Keep paid features disabled by default.\n- Present a dry-run summary.\n- Publish only after explicit approval for that exact advertisement.\n- Report the success URL or validation errors after submission.\n- Track posted advertisements locally.\n- Mark expired or removed advertisements for reposting.\n- Use photos and short item descriptions from WhatsApp/iMessage as ad intake when the user asks.\n- Validate listing descriptions with the hard Copy Quality Gate before filling or publishing Marktplaats.\n\n## What The Skill Must Not Do\n\n- Do not publish or repost without explicit per-ad approval.\n- Do not enable paid options without separate approval.\n- Do not invent price, condition, or uncertain required fields.\n- Do not bypass login, captcha, WAF, or security checks.\n- Do not reply to buyers without separate permission.\n- Do not expose cookies, XSRF tokens, or session data.\n\n## Required Permissions\n\nFor search:\n\n- Network access to Marktplaats.\n- Node.js for the existing CLI tools.\n\nFor preparation:\n\n- Read access to local photo files provided by the user.\n- Read access to relevant WhatsApp/iMessage attachments when the user asks to use them.\n- Write access for ad records, photos and snapshots, preferably:\n  - `~/Documents/OpenClaw/Data/marktplaats/`\n  - `housekeeping/marktplaats-snapshots/`\n  - `housekeeping/marktplaats-test/`\n\nFor publishing:\n\n- A browser session where the user is already logged in to Marktplaats.\n- macOS automation through AppleScript or Peekaboo to use that browser context.\n- Access to the Marktplaats placement page.\n\nThe skill does not need the user's Marktplaats password. Authentication stays inside the browser.\n\n## Local Ad Register\n\nCentral register:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nOptional per-ad directory:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/\n```\n\nRecommended contents:\n\n- `ad.json`: ad id, URL, status, price, category, source and repost metadata.\n- `description.md`: latest listing description.\n- `photos/originals/`: source photos.\n- `photos/processed/`: resized/metadata-reduced publish photos.\n- `snapshots/`: form or submit snapshots.\n\nImportant statuses:\n\n- `draft`\n- `pending_approval`\n- `active`\n- `removed`\n- `expired`\n- `needs_repost`\n- `reposted`\n- `test`\n\nUpdate the register after every placement, validation error, removal, status check or repost.\n\n## Reposting After Expiry\n\nMarktplaats can change its rules. Check the current listing duration or ad status before relying on dates.\n\nStandard flow:\n\n1. Read `advertenties.json`.\n2. Find active ads with past `renewAfter`/`expiresAt` values, or ads that no longer appear active.\n3. Verify the ad status.\n4. Set `needs_repost` when reposting makes sense.\n5. Build a fresh dry-run from the existing text/photos, with current category and form checks.\n6. Publish only after explicit user approval.\n7. Add the new ad id to the register and keep the old ad in `repostHistory`.\n\nA cron/heartbeat may report that ads need reposting, but it must not publish automatically.\n\n## Intake From WhatsApp Or iMessage\n\nWhen the user sends photos and says what the item is:\n\n1. Read only the relevant messages/attachments.\n2. Store photos in the ad directory.\n3. Create safe publishing copies.\n4. Record the source, such as channel, chat id, message id and timestamp.\n5. Identify the item, brand/model and visible details.\n6. Ask for missing essentials: price, condition, pickup/shipping, defects, missing parts.\n7. Research product information online.\n8. Choose a category and inspect the current form.\n9. Write a strong SEO listing of roughly 3200-3500 characters.\n10. Run `marktplaats-copy-qa` with product terms and a natural search variant.\n11. Present a dry-run.\n12. Publish only after explicit approval.\n\nFor WhatsApp/iMessage: reading/analyzing is allowed when the user asks for this task; sending replies to other people or buyers requires separate permission.\n\n## Standard Workflow\n\n### 1. Understand The Item\n\nDetermine:\n\n- item type;\n- brand/model/type;\n- condition;\n- asking price;\n- pickup/shipping preference;\n- included accessories;\n- defects or important notes;\n- available photos.\n\nAsk the user if essential information is missing.\n\n### 2. Find Candidate Categories\n\nUse:\n\n```bash\nmarktplaats-categories --json\nmarktplaats-categories <parent-id> --json\nmarktplaats-search \"<product name>\" --json -n 10\n```\n\nChoose based on:\n\n- comparable listings;\n- suitable category attributes;\n- free listing availability;\n- buyer discoverability.\n\nExplain the chosen category in the dry-run.\n\n### 3. Copy Quality Gate\n\nBefore filling Marktplaats, run:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<brand-or-type>\" \\\n  --require \"<product-kind>\" \\\n  --variant \"<natural search variant>\" \\\n  --ad-json ./ad.json\n```\n\nStop if the command fails or if `ad.json.copyQuality.passed` is not `true`.\n\nHard requirements:\n\n- default length 3200-3500 characters;\n- hard lower stop at 2800 characters;\n- at least 7 substantial sections/paragraphs;\n- no `Zoektermen:`, `Keywords:`, `SEO:` or keyword dump;\n- natural SEO terms in prose;\n- at least one subtle product-relevant typo/spelling/search variant in context.\n\n### 4. Inspect The Live Form\n\nOpen the placement page for the chosen category and capture a fresh snapshot with the probe:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nOr open the placement page in Safari in the background before probing the same session:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\nInspect:\n\n- `form.action` (usually `https://www.marktplaats.nl/plaats/ads`);\n- category identifiers;\n- presence of an XSRF token, not the value;\n- hidden form values;\n- title and description fields;\n- price fields;\n- condition fields;\n- category attributes;\n- delivery fields;\n- postcode/contact fields;\n- paid feature fields;\n- selected bundle.\n- `security.challengeSignals` for login, captcha, MFA, WAF, or payment/promotion signals.\n\nA `curl` probe on `/plaats` may return `401` without a session cookie. That is expected. In that case, use the logged-in browser DOM as the source of truth instead of manual UI clicking.\n\n### 4. Fill Fields Conservatively\n\n- Keep the title short and specific.\n- Keep the description factual.\n- Fill condition only when reasonably certain.\n- Use the user's price or ask for one.\n- Select multi-value attributes only when clearly applicable.\n- Default delivery to pickup unless shipping is requested.\n\n### 5. Enforce Free Listing\n\nBefore publishing, verify:\n\n- free bundle selected;\n- no urgent/homepage/promoted features enabled;\n- no paid bundle selected;\n- no payment page shown.\n\nStop if Marktplaats asks for payment unexpectedly.\n\n### 6. Prepare Photos\n\nCreate temporary resized copies when possible:\n\n```bash\nmkdir -p housekeeping/marktplaats-test\nsips -Z 1600 -s format jpeg input.jpg --out housekeeping/marktplaats-test/photo-1.jpg\n```\n\nCheck for obvious EXIF/GPS metadata where possible.\n\n### 7. Upload Photos\n\nThe proven browser-context upload uses:\n\n- endpoint: `/plaats/api/image/upload`\n- method: `POST`\n- FormData fields:\n  - `name`\n  - `imageData`\n- header:\n  - `x-mp-xsrf`\n\nPreferred local helper:\n\nUpload the photos in the live flow and then read back the generated `images.ids` / hidden fields through the probe. Use the browser only as a session carrier, not to guess an upload path by hand. If upload or photo count cannot be verified, stop.\n\n### 8. Dry-Run Summary\n\nAlways show before publishing:\n\n```text\nCategory: ...\nReason: ...\nTitle: ...\nPrice: ...\nCondition: ...\nDelivery: ...\nPhotos: ...\nFree listing: yes/no\nPaid options: none\nUncertain fields: ...\nAfter approval: publish to Marktplaats\n```\n\n### 9. Publish\n\nPublish only after explicit approval. After submission:\n\n- report the success URL;\n- report the advertisement id/link;\n- summarize validation errors if any;\n- stop if a payment page appears;\n- run live verification;\n- update the local ad register.\n\n## Testing Protocol\n\nRecommended test period:\n\n1. Start with one dummy/test advertisement.\n2. Try 2-3 low-risk real ads.\n3. Check category, price, photos and free options.\n4. Confirm that ads can be removed easily.\n5. Note problematic categories/fields.\n6. Test reposting from the local register.\n7. Test intake from WhatsApp/iMessage photos.\n8. Consider ClawHub publication only after testing.\n\n## ClawHub Publication Notes\n\nA public listing should clearly state:\n\n- publishing and reposting require explicit approval;\n- the user must be logged in themselves;\n- the skill does not bypass login/captcha/security checks;\n- paid options are off by default;\n- local ad tracking may contain personal photos/data and must be treated as private;\n- required local tools and permissions;\n- Marktplaats flows may change;\n- users remain responsible for ad content and platform compliance.\n\nFile v0.6.1:references/handleiding-nl.md\n\n# Marktplaats Verkoopassistent - Nederlandse Handleiding\n\n## Naam\n\n**Marktplaats Verkoopassistent**\n\nTechnische skill-key: `marktplaats`.\n\nDeze naam is bewust breder dan alleen zoeken. De skill helpt bij het volledige verkoopproces: categorie kiezen, velden bepalen, foto's voorbereiden/uploaden, lokaal bijhouden, herplaatsing voorbereiden, dry-run maken en pas na akkoord publiceren.\n\n## Doel\n\nDe skill helpt een gebruiker of agent om Marktplaats-advertenties betrouwbaar en veilig voor te bereiden, te plaatsen en later terug te vinden voor controle of herplaatsing. De belangrijkste verbetering ten opzichte van handmatig werken is dat de agent eerst de actuele categorievelden uitleest en daarna pas een advertentie invult. Daarnaast houdt de skill lokaal bij wat geplaatst is, met welke foto's en tekst, zodat verlopen advertenties later opnieuw voorbereid kunnen worden.\n\n## Wat De Skill Kan\n\n- Marktplaats doorzoeken op vergelijkbare advertenties.\n- Categorieën en subcategorieën ophalen.\n- Een beste categorie voorstellen voor een item.\n- Een live plaatsingsformulier uitlezen via de browser.\n- Categorie-specifieke velden verzamelen, zoals conditie, merk, type, maat, levering, prijs en extra opties.\n- Foto's verkleinen en metadata-arm maken waar mogelijk.\n- Foto-upload begeleiden en controleren via de ingelogde Marktplaats-browsercontext.\n- Advertentiedata invullen in het formulier.\n- Betaalde opties standaard uitschakelen.\n- Een dry-run samenvatting tonen.\n- Na expliciet akkoord een advertentie publiceren.\n- Na publicatie de success-URL of foutmelding rapporteren.\n- Geplaatste advertenties lokaal administreren.\n- Verlopen of verwijderde advertenties markeren voor herplaatsing.\n- Foto's en korte omschrijvingen uit WhatsApp/iMessage als advertentie-intake gebruiken wanneer de gebruiker daarom vraagt.\n- Advertentieteksten vóór publicatie verplicht controleren met de Copy Quality Gate.\n\n## Wat De Skill Niet Zelfstandig Mag\n\n- Geen advertentie publiceren of herplaatsen zonder expliciet akkoord per advertentie.\n- Geen betaalde plaatsing of promotie inschakelen zonder apart akkoord.\n- Geen prijs verzinnen als de gebruiker geen prijs heeft gegeven.\n- Geen conditie kiezen als die onzeker is.\n- Geen captcha, login, WAF of beveiligingscontrole omzeilen.\n- Geen berichten beantwoorden aan kopers zonder aparte toestemming.\n- Geen cookies, XSRF-tokens of sessiegegevens delen.\n\n## Benodigde Rechten\n\nVoor zoeken:\n\n- Netwerktoegang naar Marktplaats.\n- Node.js voor de CLI-tools.\n\nVoor advertentievoorbereiding:\n\n- Leesrechten op lokale fotobestanden.\n- Leesrechten op relevante WhatsApp/iMessage-bijlagen wanneer de gebruiker vraagt die te gebruiken.\n- Schrijfrechten voor advertentiegegevens, foto's en snapshots, bij voorkeur:\n  - `~/Documents/OpenClaw/Data/marktplaats/`\n  - `housekeeping/marktplaats-snapshots/`\n  - `housekeeping/marktplaats-test/`\n\nVoor plaatsen:\n\n- Een browser waarin de gebruiker al is ingelogd op Marktplaats.\n- macOS automation via AppleScript of Peekaboo om de browsercontext te gebruiken.\n- Toegang tot de Marktplaats plaatsingspagina.\n\nBelangrijk: de skill heeft geen Marktplaats-wachtwoord nodig. Login blijft bij de gebruiker/browser.\n\n## Lokale Advertentieadministratie\n\nCentrale administratie:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nPer advertentie kan een eigen map worden gebruikt:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/\n```\n\nAanbevolen inhoud:\n\n- `ad.json`: advertentie-id, URL, status, prijs, categorie, bron en herplaatsinformatie.\n- `description.md`: laatst gebruikte advertentietekst.\n- `photos/originals/`: bronfoto's.\n- `photos/processed/`: verkleinde/metadata-arme publicatiefoto's.\n- `snapshots/`: formulier- of submit-snapshots.\n\nBelangrijke statussen:\n\n- `draft`\n- `pending_approval`\n- `active`\n- `removed`\n- `expired`\n- `needs_repost`\n- `reposted`\n- `test`\n\nNa elke plaatsing, foutmelding, verwijdering, statuscheck of herplaatsing wordt het register bijgewerkt.\n\n## Herplaatsing Na Verlopen\n\nMarktplaats kan regels wijzigen. Controleer daarom de actuele looptijd of advertentiestatus voordat je automatisch conclusies trekt.\n\nStandaardflow:\n\n1. Lees `advertenties.json`.\n2. Zoek actieve advertenties met verlopen `renewAfter`/`expiresAt` of advertenties die niet meer zichtbaar lijken.\n3. Controleer de advertentiestatus.\n4. Zet ze op `needs_repost` als herplaatsing zinvol is.\n5. Maak een nieuwe dry-run op basis van de bestaande tekst/foto's, met verse categorie- en formuliercheck.\n6. Publiceer pas na expliciet akkoord van de gebruiker.\n7. Voeg de nieuwe advertentie-id toe aan het register en bewaar de oude in `repostHistory`.\n\nEen cron/heartbeat mag melden dat advertenties herplaatst moeten worden, maar mag niet zelfstandig publiceren.\n\n## Intake Vanuit WhatsApp Of iMessage\n\nWanneer de gebruiker foto's stuurt en zegt wat het is:\n\n1. Lees alleen de relevante berichten/bijlagen.\n2. Sla de foto's lokaal op in de advertentiemap.\n3. Maak veilige publicatiekopieën.\n4. Leg de bron vast, zoals kanaal, chat-id, message-id en tijdstip.\n5. Herken item, merk/model en zichtbare details.\n6. Vraag ontbrekende kerngegevens: prijs, conditie, ophalen/verzenden, gebreken, missende onderdelen.\n7. Zoek productinformatie online.\n8. Kies categorie en inspecteer het actuele formulier.\n9. Schrijf een sterke SEO-advertentie van circa 3200-3500 tekens.\n10. Draai `marktplaats-copy-qa` met producttermen en een natuurlijke zoekvariant.\n11. Toon dry-run.\n12. Plaats alleen na expliciet akkoord.\n\nVoor WhatsApp/iMessage geldt: lezen/analyseren mag als de gebruiker daarom vraagt; antwoorden naar anderen of kopers sturen alleen na aparte toestemming.\n\n## Standaard Stappenplan\n\n### 1. Item Begrijpen\n\nBepaal:\n\n- wat het item is;\n- merk/type/model;\n- conditie;\n- gewenste prijs;\n- ophalen/verzenden;\n- meegeleverde onderdelen;\n- gebreken of bijzonderheden;\n- beschikbare foto's.\n\nAls prijs, conditie of essentieel detail ontbreekt: vraag de gebruiker.\n\n### 2. Categorie-Kandidaten Zoeken\n\nGebruik:\n\n```bash\nmarktplaats-categories --json\nmarktplaats-categories <parent-id> --json\nmarktplaats-search \"<productnaam>\" --json -n 10\n```\n\nKies de categorie op basis van:\n\n- bestaande vergelijkbare advertenties;\n- passende attributen;\n- gratis plaatsingsmogelijkheid;\n- logische vindbaarheid voor kopers.\n\nMotiveer de keuze in de dry-run.\n\n### 3. Copy Quality Gate\n\nVoordat Marktplaats wordt ingevuld:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<merk-of-type>\" \\\n  --require \"<productsoort>\" \\\n  --variant \"<natuurlijke zoekvariant>\" \\\n  --ad-json ./ad.json\n```\n\nStop als de command faalt of als `ad.json.copyQuality.passed` niet `true` is.\n\nHarde eisen:\n\n- standaard 3200-3500 tekens;\n- absolute ondergrens 2800 tekens;\n- minimaal 7 substantiële secties/alinea's;\n- geen `Zoektermen:`, `Keywords:` of keyworddump;\n- natuurlijke SEO-termen in lopende tekst;\n- minimaal één subtiele, productrelevante spelfout/schrijfvariant in context.\n\n### 4. Live Plaatsingsformulier Inspecteren\n\nOpen de plaatsingspagina voor de gekozen categorie en maak een snapshot met de probe:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser --save housekeeping/marktplaats-snapshots/current.json\n```\n\nOf open de plaatsingspagina in Safari op de achtergrond en probe daarna dezelfde sessie:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser \\\n  --open-background \"https://www.marktplaats.nl/plaats/...\" \\\n  --save housekeeping/marktplaats-snapshots/current.json\n```\n\nControleer:\n\n- `form.action` (meestal `https://www.marktplaats.nl/plaats/ads`);\n- categorievelden (`l1`, `l2`, `bucket`);\n- aanwezigheid van een XSRF-token, niet de waarde;\n- hidden formulierwaarden;\n- titel/omschrijving;\n- prijsvelden;\n- conditievelden;\n- categorie-attributen;\n- leveringsvelden;\n- postcode/contact;\n- betaalde opties;\n- geselecteerde bundle.\n- `security.challengeSignals` voor login, captcha, MFA, WAF of betaal-/promotiesignalen.\n\nEen `curl`-probe op `/plaats` kan `401` geven als er geen sessiecookie wordt meegegeven. Dat is normaal: gebruik in dat geval de ingelogde browser-DOM als bron van waarheid, niet handmatige UI-kliks.\n\nGebruik voor authenticated requests zonder cookies te exporteren:\n\n```bash\nnode scripts/marktplaats-place-probe.js --browser-fetch --url https://www.marktplaats.nl/plaats\n```\n\nDeze route gebruikt Safari's bestaande sessie via `XMLHttpRequest` met credentials. Cookies en sessietokens blijven in Safari en worden niet gelogd.\n\n### 5. Velden Invullen\n\nGebruik conservatieve mapping:\n\n- Titel kort en specifiek.\n- Beschrijving feitelijk, geen overdreven verkooppraat.\n- Conditie alleen invullen als redelijk zeker.\n- Prijs alleen van de gebruiker of expliciet akkoord.\n- Multi-selects alleen aanvinken als zeker passend.\n- Levering standaard ophalen, tenzij de gebruiker verzending wil.\n\n### 6. Gratis Advertentie Afdwingen\n\nControleer vóór publicatie:\n\n- gratis bundle geselecteerd;\n- geen urgent/etalage/homepage/promotie;\n- geen betaalpagina;\n- geen onverwachte kosten.\n\nAls Marktplaats toch kosten toont: stoppen en rapporteren.\n\n### 7. Foto's Voorbereiden\n\nMaak bij voorkeur tijdelijke kopieën:\n\n```bash\nmkdir -p housekeeping/marktplaats-test\nsips -Z 1600 -s format jpeg input.jpg --out housekeeping/marktplaats-test/photo-1.jpg\n```\n\nControleer waar mogelijk of GPS/EXIF niet meer zichtbaar is.\n\n### 8. Foto's Uploaden\n\nGebruik de bewezen browsercontext-route. De Marktplaats frontend verwacht:\n\n- endpoint: `/plaats/api/image/upload`\n- method: `POST`\n- FormData velden:\n  - `name`\n  - `imageData`\n- header:\n  - `x-mp-xsrf`\n\nUpload de foto's in de live flow en lees daarna de gegenereerde `images.ids`/hidden fields terug uit de probe. Gebruik de browser alleen als sessiedrager, niet om handmatig een uploadpad te raden. Als upload of fototeller niet te verifieren is, stoppen.\n\n### 9. Dry-Run Tonen\n\nAltijd tonen vóór publiceren:\n\n```text\nCategorie: ...\nWaarom deze categorie: ...\nTitel: ...\nPrijs: ...\nConditie: ...\nLevering: ...\nFoto's: ...\nGratis advertentie: ja/nee\nBetaalde opties: geen\nOnzekere velden: ...\nNa akkoord: publiceren op Marktplaats\n```\n\n### 9. Publiceren\n\nAlleen na expliciet akkoord. Na submit:\n\n- success-redirect rapporteren;\n- advertentie-id/link rapporteren;\n- validatiefouten kort samenvatten;\n- bij betaalpagina stoppen;\n- daarna live-verificatie draaien;\n- lokale advertentieadministratie bijwerken.\n\n## Testprotocol\n\nAanbevolen testperiode:\n\n1. Begin met 1 dummy/testadvertentie.\n2. Test daarna 2-3 echte goedkope advertenties.\n3. Controleer of categorie, prijs, foto's en gratis opties kloppen.\n4. Controleer of advertenties makkelijk te verwijderen zijn.\n5. Noteer welke categorieën/velden lastig zijn.\n6. Test daarna herplaatsing vanuit het lokale register.\n7. Test daarna intake vanuit WhatsApp/iMessage-foto's.\n8. Pas daarna publicatie op ClawHub overwegen.\n\n## Publicatie Op ClawHub\n\nVoor publicatie moet de skill duidelijk vermelden:\n\n- dat publiceren en herplaatsen alleen na expliciet akkoord mag;\n- dat de gebruiker zelf ingelogd moet zijn;\n- dat de skill geen login/captcha omzeilt;\n- dat betaalde opties standaard uit staan;\n- dat lokaal advertentiebeheer persoonsgegevens/foto's kan bevatten en dus privé behandeld moet worden;\n- welke lokale tools nodig zijn;\n- dat Marktplaats-flows kunnen wijzigen;\n- dat de gebruiker verantwoordelijk blijft voor advertentie-inhoud en platformregels.\n\nFile v0.6.1:references/robust-posting-checklist.md\n\n- Work linearly and deterministically.\n- Run `marktplaats-copy-qa` before touching Marktplaats; stop if it fails.\n- Keep descriptions around 3200-3500 characters, with a hard stop below 2800.\n- Use natural SEO in prose; never publish `Zoektermen:` or keyword-dump footers.\n- Include one subtle product-relevant typo/search variant in context.\n- Prefer one dedicated browser window/tab for a single ad flow.\n- Avoid extra screens, helper windows, and parallel UI actions.\n- Rotate photos only when preview/orientation shows it is needed.\n- Use ASCII-safe text if live rendering shows mojibake.\n- Verify live seller-view as source of truth.\n- Keep the flow understandable for smaller models like GPT-5.4-mini.\n- One step, one verification, then next step.\n- Use `marktplaats-place-probe --browser --open-background <url>` when Safari can stay in the background.\n- Register update only after successful live verification, unless explicitly tracking a draft with `--allow-unverified`.\n\nFile v0.6.1:skill-card.md\n\n## Description: <br>\nHelps agents prepare, quality-check, publish, verify, and locally track Marktplaats advertisements through guided workflows and Node.js CLI gates. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[roelbroersma](https://clawhub.ai/user/roelbroersma) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and agents use this skill to prepare normal Marktplaats sales listings, run copy quality and preflight checks, publish only after explicit approval, verify the live ad, and update a local register for later tracking or reposting. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Authenticated Safari and cookie-based probing can inspect the user's active browser session and is not technically limited to Marktplaats. <br>\nMitigation: Keep Safari on the intended Marktplaats tab, avoid raw cookie mode unless necessary, and do not use browser-fetch or cookie modes on unrelated sites. <br>\nRisk: Saved snapshots, ad files, and register updates may contain private listing details or session-adjacent data. <br>\nMitigation: Review saved files before sharing them and keep generated ad/register artifacts in a trusted local workspace. <br>\nRisk: The security verdict is suspicious because the skill includes broad authenticated browser and cookie-based probing behavior. <br>\nMitigation: Install and run it only when comfortable with local session inspection, and review commands and outputs before publication or sharing. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/roelbroersma/skills/marktplaats-publisher) <br>\n- [Marktplaats Seller Assistant - English Guide](references/guide-en.md) <br>\n- [Marktplaats Verkoopassistent - Nederlandse Handleiding](references/handleiding-nl.md) <br>\n- [Robust Posting Checklist](references/robust-posting-checklist.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, JSON, Guidance] <br>\n**Output Format:** [Markdown guidance with inline shell commands and JSON-backed local ad records] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May write local ad/register files and snapshots when the user supplies paths and permissions.] <br>\n\n## Skill Version(s): <br>\n0.6.1 (source: server release evidence and package.json) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.6.1:package.json\n\n{\n  \"name\": \"marktplaats-publisher\",\n  \"version\": \"0.6.1\",\n  \"description\": \"Maak en controleer Marktplaats-advertenties met scriptmatige preflight, live-verificatie en register-update.\",\n  \"type\": \"module\",\n  \"bin\": {\n    \"marktplaats-search\": \"./bin/marktplaats-search.js\",\n    \"marktplaats-categories\": \"./bin/marktplaats-categories.js\",\n    \"marktplaats-place-probe\": \"./scripts/marktplaats-place-probe.js\",\n    \"marktplaats-copy-qa\": \"./scripts/marktplaats-copy-qa.js\",\n    \"marktplaats-ad-preflight\": \"./scripts/marktplaats-ad-preflight.js\",\n    \"marktplaats-live-verify\": \"./scripts/marktplaats-live-verify.js\",\n    \"marktplaats-register-update\": \"./scripts/marktplaats-register-update.js\"\n  },\n  \"exports\": \"./src/index.js\",\n  \"files\": [\n    \"bin\",\n    \"src\",\n    \"scripts\",\n    \"references\",\n    \"README.md\",\n    \"LICENSE\",\n    \"SKILL.md\"\n  ],\n  \"scripts\": {\n    \"test\": \"node ./bin/marktplaats-search.js --help && node ./bin/marktplaats-categories.js --help && node ./scripts/marktplaats-place-probe.js --self-test && node ./scripts/marktplaats-copy-qa.js --self-test && node ./scripts/marktplaats-ad-preflight.js --self-test && node ./scripts/marktplaats-live-verify.js --self-test && node ./scripts/marktplaats-register-update.js --self-test\"\n  },\n  \"keywords\": [\n    \"marktplaats\",\n    \"classifieds\",\n    \"publisher\",\n    \"posting\",\n    \"search\",\n    \"cli\",\n    \"copy-qa\",\n    \"self-healing\"\n  ],\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"license\": \"MIT\",\n  \"author\": \"OpenClaw community\"\n}\n\nArchive v0.6.0: 17 files, 45810 bytes\n\nFiles: _meta.json (140b), bin/marktplaats-categories.js (2982b), bin/marktplaats-search.js (8020b), package.json (1486b), README.md (6611b), references/guide-en.md (9693b), references/handleiding-nl.md (10881b), references/robust-posting-checklist.md (756b), scripts/marktplaats-ad-preflight.js (11210b), scripts/marktplaats-copy-qa.js (12377b), scripts/marktplaats-live-verify.js (10982b), scripts/marktplaats-place-probe.js (16182b), scripts/marktplaats-register-update.js (6833b), skill-card.md (2855b), SKILL.md (5829b), src/api.js (14739b), src/index.js (160b)\n\nFile v0.6.0:SKILL.md\n\n---\nname: \"marktplaats-publisher\"\ndescription: \"Marktplaats publisher met scriptmatige copy-QA, preflight, live verify en register-update.\"\nhomepage: https://www.marktplaats.nl\nmetadata: {\"clawdbot\":{\"emoji\":\"🇳🇱\",\"requires\":{\"bins\":[\"node\"]}}}\n---\n\n# Marktplaats Publisher\n\nGebruik deze skill voor normale Marktplaats-advertenties: voorbereiden, plaatsen, bewerken, live controleren en lokaal registreren.\n\nDe workflow is command-first. Proceduretekst is alleen toelichting. Als een gate faalt, stop je.\n\n## Harde Regels\n\n- Geen publicatie of inhoudelijke bewerking zonder expliciete opdracht voor die advertentie.\n- Geen betaalde opties, bundels, promoties of betaalflow zonder expliciet akkoord.\n- Geen cookies, sessietokens, XSRF/auth-waarden, klantdata of lokale privepaden loggen of publiceren.\n- Geen captcha, MFA, login challenge, WAF of accountbeveiliging omzeilen.\n- Geen tekst plaatsen als copy-QA of preflight faalt.\n- Na opslaan altijd live verifieren en het lokale register bijwerken.\n- Bij UI-drift, browser-hang of onduidelijke formulierstatus: stop, maak een snapshot en rapporteer de blokkade.\n\n## Lokale Bestanden\n\nWerk per advertentie in:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/<slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<slug>/photos/\n```\n\nCentraal register:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\n`ad.json` moet minimaal bevatten: titel, prijs, conditie, levering, categorie/categoryIds, `biddingAllowed`, `descriptionFile`, `imageDir` of foto's, URL/adId zodra live, en `copyQuality`.\n\n## Verplichte Pipeline\n\n### 1. Schrijf De Omschrijving\n\nSchrijf een feitelijke Nederlandse tekst van ongeveer 3200-3500 tekens.\n\nMoet bevatten:\n\n- merk/model of herkenbare productnaam;\n- productsoort;\n- staat/conditie en wat wel/niet getest is;\n- concrete zichtbare kenmerken;\n- toepassing en compatibiliteit;\n- ophalen/verzenden, prijs en bieden;\n- natuurlijke zoekvarianten in gewone zinnen.\n\nNiet doen:\n\n- geen `Zoektermen:`, `Keywords:` of `SEO:` footer;\n- geen lange comma-keyworddump;\n- geen claims over werking, garantie of compleetheid zonder bewijs.\n\n### 2. Copy-QA\n\nAltijd draaien voordat Marktplaats wordt ingevuld of opgeslagen:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"<merk-of-model>\" \\\n  --require \"<productsoort>\" \\\n  --variant \"<natuurlijke zoekvariant>\" \\\n  --ad-json ./ad.json\n```\n\nStop als dit geen `PASS` geeft. De command schrijft `copyQuality` inclusief `descriptionSha256` naar `ad.json`.\n\n### 3. Preflight\n\nAltijd draaien na copy-QA en voor browser/UI-werk:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nGebruik `--require-bidding-allowed` wanneer bieden aan moet staan. Stop bij failure.\n\nPreflight controleert onder andere:\n\n- verplichte advertentievelden;\n- omschrijving bestaat en is niet gewijzigd na copy-QA;\n- copy-QA is geslaagd;\n- foto's bestaan;\n- biedeninstelling indien vereist.\n\n### 4. Formulier Probe\n\nInspecteer Marktplaats voordat je invult:\n\n```bash\nmarktplaats-place-probe --browser --save ./snapshot-place.json\n```\n\nOf met browser-fetch:\n\n```bash\nmarktplaats-place-probe --browser-fetch --url \"https://www.marktplaats.nl/plaats/...\" --save ./snapshot-place.json\n```\n\nStop als:\n\n- login/captcha/MFA/WAF verschijnt;\n- betaalde route verplicht lijkt;\n- formulierstructuur onduidelijk is;\n- foto-upload of bundelkeuze niet te verifieren is.\n\n### 5. Plaats Of Bewerk\n\nVul Marktplaats pas na groene copy-QA en preflight.\n\nControleer voor submit/save:\n\n- titel;\n- prijs;\n- bieden toegestaan indien gevraagd;\n- conditie;\n- levering;\n- foto-aantal;\n- gratis/basic route;\n- laatste zin van de omschrijving zichtbaar in het formulier.\n\nGebruik geen blinde coordinate-clicks. Gebruik DOM/events of een expliciet UI-element met verificatie voor en na.\n\n### 6. Live Verify\n\nNa opslaan of plaatsen moet de live advertentie gecontroleerd worden.\n\nAls fetch genoeg tekst bevat:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --url \"https://www.marktplaats.nl/seller/view/...\" --update-ad-json\n```\n\nAls de pagina dynamisch is, sla eerst zichtbare/live tekst op en verifieer die:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --text ./live-text.txt --update-ad-json\n```\n\nStop als:\n\n- begin van de omschrijving ontbreekt;\n- laatste zin ontbreekt;\n- omschrijving dubbel staat;\n- `Zoektermen:` of keyworddump live zichtbaar is.\n\n### 7. Register Update\n\nWerk na live verificatie het centrale register bij:\n\n```bash\nmarktplaats-register-update \\\n  --ad-json ./ad.json \\\n  --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json \\\n  --note \"Live gecontroleerd na plaatsing/bewerking.\"\n```\n\nRun register-updates sequentieel. Het script gebruikt een lock en faalt als een tweede update tegelijk hetzelfde centrale register probeert te schrijven.\n\n## Bestaande Advertentie Bewerken\n\nVoor elke inhoudelijke tekstbewerking geldt dezelfde pipeline:\n\n```bash\nmarktplaats-copy-qa ./description.md --require \"<term1>\" --require \"<term2>\" --variant \"<variant>\" --ad-json ./ad.json\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n# bewerk via Marktplaats UI/DOM\nmarktplaats-live-verify --ad-json ./ad.json --url \"<live-url>\" --update-ad-json\nmarktplaats-register-update --ad-json ./ad.json --central-json ~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nAls live fetch de tekst niet ziet, gebruik `--text ./live-text.txt` met tekst uit de browser/accessibility snapshot.\n\n## Test De Skill\n\n```bash\nnpm test\n```\n\nDeze test moet groen zijn voordat je publiceert naar ClawHub.\n\n## Naslag\n\n- Publieke uitleg: `README.md`\n- Langere handleiding: `references/handleiding-nl.md`\n- Engelse guide: `references/guide-en.md`\n- Robuuste checklist: `references/robust-posting-checklist.md`\n\nFile v0.6.0:README.md\n\n# Marktplaats.nl Verkoopassistent\n\nDeze skill helpt je om een Marktplaats-advertentie netjes voor te bereiden, te plaatsen en achteraf te controleren.\n\nHet belangrijkste doel is simpel: een goede advertentie maken zonder half werk, zonder betaalde opties per ongeluk aan te zetten en zonder dat de tekst weer te kort, kaal of spammerig wordt.\n\nVanaf versie 0.6.0 is dit vooral een scriptmatige pipeline. De assistent krijgt dus niet alleen lange instructies, maar moet door harde checks heen: copy-QA, preflight, live-verificatie en register-update.\n\n## Wat doet deze skill?\n\n- Zoekt mee naar categorieën en vergelijkbare advertenties.\n- Helpt productinformatie te verwerken zonder dingen te verzinnen.\n- Schrijft een volle Nederlandse advertentietekst van ongeveer 3200 tot 3500 tekens.\n- Controleert de tekst voordat Marktplaats wordt ingevuld.\n- Werkt met een bestaande ingelogde Safari-sessie op macOS.\n- Uploadt en controleert foto's via de normale Marktplaats-flow.\n- Houdt betaalde promoties standaard uit.\n- Controleert na het plaatsen of de advertentie echt live goed staat.\n- Bewaart lokaal wat er geplaatst is, inclusief tekstcheck en live controle.\n\nDeze skill is bedoeld voor normale verkoopadvertenties. Niet voor bulkposten, omzeilen van beveiliging, captcha's, loginproblemen of betaalflows.\n\n## Waarom is die tekstcheck zo streng?\n\nOmdat korte advertenties steeds terugkwamen als probleem.\n\nEen advertentie van een paar regels is snel gemaakt, maar meestal slecht vindbaar. Daarom zit er een harde controle in: de tekst moet lang genoeg zijn, genoeg inhoud hebben, natuurlijke zoekwoorden bevatten en geen los blok met `Zoektermen:` of keywordspam onderaan zetten.\n\nDe standaard is:\n\n- ongeveer 3200 tot 3500 tekens;\n- minimaal 7 duidelijke alinea's of onderdelen;\n- merk/model en productsoort moeten erin staan;\n- een kleine natuurlijke zoekvariant mag, zoals `deur slot` of `buiten antenne`;\n- geen losse zoekwoordenlijst;\n- de laatste zin moet ook live zichtbaar zijn na opslaan.\n\nAls die check faalt, moet de advertentie eerst beter worden. Niet toch maar plaatsen.\n\n## Copy check draaien\n\nGebruik dit voordat je Marktplaats opent of een bestaande advertentie opslaat:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"KFV\" \\\n  --require \"motorslot\" \\\n  --variant \"deur slot\" \\\n  --ad-json ./ad.json\n```\n\nDe check schrijft het resultaat in `ad.json`. Alleen als `copyQuality.passed` op `true` staat, mag de tekst door naar Marktplaats.\n\nVoor een snelle test van de tool zelf:\n\n```bash\nmarktplaats-copy-qa --self-test\n```\n\n## Preflight voor het plaatsen\n\nNa de copy check moet de advertentie door preflight:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nDeze check kijkt of `ad.json`, de omschrijving, foto's, bieden-instelling en copy-QA bij elkaar passen. Als de omschrijving na de copy check nog is aangepast, faalt preflight op de tekst-hash.\n\n## Live controleren na opslaan\n\nNa plaatsen of bewerken moet de live advertentie worden gecontroleerd:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --url \"https://www.marktplaats.nl/seller/view/...\" --update-ad-json\n```\n\nAls Marktplaats de tekst niet goed in de HTML meestuurt, gebruik je tekst uit de browser:\n\n```bash\nmarktplaats-live-verify --ad-json ./ad.json --text ./live-text.txt --update-ad-json\n```\n\nArchive v0.5.1: 14 files, 43710 bytes\n\nFiles: _meta.json (140b), bin/marktplaats-categories.js (2982b), bin/marktplaats-search.js (8020b), package.json (1079b), README.md (5027b), references/guide-en.md (9693b), references/handleiding-nl.md (10881b), references/robust-posting-checklist.md (756b), scripts/marktplaats-copy-qa.js (12151b), scripts/marktplaats-place-probe.js (16182b), skill-card.md (2951b), SKILL.md (29371b), src/api.js (14739b), src/index.js (160b)\n\nArchive v0.5.0: 14 files, 43558 bytes\n\nFiles: _meta.json (140b), bin/marktplaats-categories.js (2982b), bin/marktplaats-search.js (8020b), package.json (1091b), README.md (4500b), references/guide-en.md (9693b), references/handleiding-nl.md (10881b), references/robust-posting-checklist.md (756b), scripts/marktplaats-copy-qa.js (12151b), scripts/marktplaats-place-probe.js (16182b), skill-card.md (2843b), SKILL.md (29371b), src/api.js (14739b), src/index.js (160b)\n\nArchive v0.4.4: 10 files, 29647 bytes\n\nFiles: bin/marktplaats-categories.js (2982b), bin/marktplaats-search.js (8020b), package.json (970b), README.md (12869b), scripts/marktplaats-place-probe.js (15351b), skill-card.md (2555b), SKILL.md (21748b), src/api.js (14739b), src/index.js (160b), _meta.json (140b)","readmeExcerpt":"Skill: Marktplaats Owner: roelbroersma Summary: Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register. Tags: latest:0.6.3 Version history: v0.6.3 | 2026-07-09T10:16:48.409Z | user Improve GPT-4.5 mini setup gates and add background-safe Safari probing. v0.6.2 | 2026-07-08T23:55:29.396Z | user Correct 0.6.1 workshop-body publish and ship the actual Marktplaats pipel","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"node ./scripts/marktplaats-place-probe.js --self-test\nnode ./scripts/marktplaats-copy-qa.js --self-test\nnode ./scripts/marktplaats-ad-preflight.js --self-test\nnode ./scripts/marktplaats-live-verify.js --self-test\nnode ./scripts/marktplaats-register-update.js --self-test"},{"language":"text","snippet":"~/Documents/OpenClaw/Data/marktplaats/<slug>/ad.json\n~/Documents/OpenClaw/Data/marktplaats/<slug>/description.md\n~/Documents/OpenClaw/Data/marktplaats/<slug>/photos/"},{"language":"text","snippet":"~/Documents/OpenClaw/Data/marktplaats/advertenties.json"},{"language":"bash","snippet":"marktplaats-copy-qa ./description.md \\\n  --require \"<merk-of-model>\" \\\n  --require \"<productsoort>\" \\\n  --variant \"<natuurlijke zoekvariant>\" \\\n  --ad-json ./ad.json"},{"language":"bash","snippet":"marktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed"},{"language":"bash","snippet":"marktplaats-place-probe --browser-fetch --url \"https://www.marktplaats.nl/plaats/...\" --save ./snapshot-place.json"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: \"marktplaats-publisher\"\ndescription: \"Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register.\"\nmetadata: {\"clawdbot\":{\"emoji\":\"🇳🇱\",\"requires\":{\"bins\":[\"node\"]}}}\n---\n\n# Marktplaats Publisher\n\nGebruik deze skill voor normale Marktplaats-advertenties: voorbereiden, plaatsen, bewerken, live controleren en lokaal registreren.\n\nDe workflow is command-first. Proceduretekst is alleen toelichting. Als een gate faalt, stop je.\n\nVoor kleinere modellen: doe steeds een fase, lees de output, en ga pas door als de vorige fase aantoonbaar geslaagd is. De scripts zijn harde gates; publiceren en UI-invulwerk blijven browserwerk met verificatie, geen blinde submit-flow.\n\n## Setup En Modelmodus\n\nAls de taak installatie, eerste setup of herstel van de skill is, laad `references/setup-small-model-nl.md`.\n\nPackage-identiteit:\n\n- correcte skill/package: `marktplaats-publisher`;\n- oude namen zoals `marktplaats`, `marktplaats-nl-publisher` of `pvoo/marktplaats` zijn niet de doel-skill;\n- vereiste runtime: Node.js 18 of nieuwer;\n- vereiste smoke-test: `npm test` vanuit de skillmap.\n\nVoor lichte modellen zoals GPT-4.5 mini of de lokaal beschikbare mini-route geldt dit contract:\n\n- voer steeds precies een gate uit;\n- lees de output volledig;\n- ga alleen door bij expliciet `PASS`, `self-test ok` of exitcode 0 met verwachte output;\n- bij failure: repareer een oorzaak, draai dezelfde gate opnieuw, maximaal twee herstelpogingen per foutklasse;\n- publiceer, bewerk of submit niets als setup, copy-QA, preflight of probe niet aantoonbaar groen is;\n- houd per advertentie een klein statusblok bij met `adDir`, `adJson`, `description`, `currentGate`, `lastCommand`, `result` en `nextStep`.\n\nAls globale CLI-commando's ontbreken, gebruik vanaf de skillmap de directe fallback:\n\n```bash\nnode ./scripts/marktplaats-place-probe.js --self-test\nnode ./scripts/marktplaats-copy-qa.js --self-test\nnode ./scripts/marktplaats-ad-preflight.js --self-test\nnode ./scripts/marktplaats-live-verify.js --self-test\nnode ./scripts/marktplaats-register-update.js --self-test\n```\n\n## Harde Regels\n\n- Geen publicatie of inhoudelijke bewerking zonder expliciete opdracht voor die advertentie.\n- Geen betaalde opties, bundels, promoties of betaalflow zonder expliciet akkoord.\n- Geen cookies, sessietokens, XSRF/auth-waarden, klantdata of lokale privepaden loggen of publiceren.\n- Geen captcha, MFA, login challenge, WAF of accountbeveiliging omzeilen.\n- Geen tekst plaatsen als copy-QA of preflight faalt.\n- Gebruik `--allow-*` opties alleen bij expliciete, taak-specifieke uitzondering van de gebruiker.\n- Publiceerbare advertentietekst mag nooit websiteadressen of domeinachtige tekst bevatten. Verboden zijn onder andere `http://`, `https://`, `www.`, e-mailadressen en woorden met bekende domeinextensies zoals `.com`, `.nl`, `.eu`, `.org`, `.net`, `.de`, `.be` en `.io`. Merknamen met een domeinextensie, zoals `StarTech.com`, moeten worden herschreven naar een gew"},{"path":"README.md","content":"# Marktplaats.nl Verkoopassistent\n\nDeze skill helpt je om een Marktplaats-advertentie netjes voor te bereiden, te plaatsen en achteraf te controleren.\n\nHet belangrijkste doel is simpel: een goede advertentie maken zonder half werk, zonder betaalde opties per ongeluk aan te zetten en zonder dat de tekst weer te kort, kaal of spammerig wordt.\n\nVanaf versie 0.6.0 is dit vooral een scriptmatige pipeline. De assistent krijgt dus niet alleen lange instructies, maar moet door harde checks heen: copy-QA, preflight, live-verificatie en register-update.\n\n## Wat doet deze skill?\n\n- Zoekt mee naar categorieën en vergelijkbare advertenties.\n- Helpt productinformatie te verwerken zonder dingen te verzinnen.\n- Schrijft een volle Nederlandse advertentietekst van ongeveer 3200 tot 3500 tekens.\n- Controleert de tekst voordat Marktplaats wordt ingevuld.\n- Werkt met een bestaande ingelogde Safari-sessie op macOS.\n- Begeleidt en controleert foto-upload via de normale Marktplaats-flow.\n- Houdt betaalde promoties standaard uit.\n- Controleert na het plaatsen of de advertentie echt live goed staat.\n- Bewaart lokaal wat er geplaatst is, inclusief tekstcheck en live controle.\n\nDeze skill is bedoeld voor normale verkoopadvertenties. Niet voor bulkposten, omzeilen van beveiliging, captcha's, loginproblemen of betaalflows.\n\n## Waarom is die tekstcheck zo streng?\n\nOmdat korte advertenties steeds terugkwamen als probleem.\n\nEen advertentie van een paar regels is snel gemaakt, maar meestal slecht vindbaar. Daarom zit er een harde controle in: de tekst moet lang genoeg zijn, genoeg inhoud hebben, natuurlijke zoekwoorden bevatten en geen los blok met `Zoektermen:` of keywordspam onderaan zetten.\n\nDe standaard is:\n\n- ongeveer 3200 tot 3500 tekens;\n- minimaal 7 duidelijke alinea's of onderdelen;\n- merk/model en productsoort moeten erin staan;\n- minimaal één kleine natuurlijke typefout/schrijfvariant in context, zoals `deur slot` of `buiten antenne`;\n- geen losse zoekwoordenlijst;\n- de laatste zin moet ook live zichtbaar zijn na opslaan.\n\nAls die check faalt, moet de advertentie eerst beter worden. Niet toch maar plaatsen.\n\n## Copy check draaien\n\nGebruik dit voordat je Marktplaats opent of een bestaande advertentie opslaat:\n\n```bash\nmarktplaats-copy-qa ./description.md \\\n  --require \"KFV\" \\\n  --require \"motorslot\" \\\n  --variant \"deur slot\" \\\n  --ad-json ./ad.json\n```\n\nDe check schrijft het resultaat in `ad.json`. Alleen als `copyQuality.passed` op `true` staat, mag de tekst door naar Marktplaats.\nWil je twee minimale varianten afdwingen, herhaal dan `--variant` en gebruik `--min-variants 2`.\n\nVoor een snelle test van de tool zelf:\n\n```bash\nmarktplaats-copy-qa --self-test\n```\n\n## Preflight voor het plaatsen\n\nNa de copy check moet de advertentie door preflight:\n\n```bash\nmarktplaats-ad-preflight --ad-json ./ad.json --require-bidding-allowed\n```\n\nDeze check kijkt of `ad.json`, de omschrijving, foto's, bieden-instelling en copy-QA bij elkaar passen. Als de omschrijving na de copy check nog"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7ewt9n4xqy7yhf2bnykj7ssh882qa4\",\n  \"slug\": \"marktplaats-publisher\",\n  \"version\": \"0.6.3\",\n  \"publishedAt\": 1783592208409\n}"},{"path":"references/background-safari-nl.md","content":"# Rustige Safari En Background-Flow\n\nGebruik deze reference wanneer `marktplaats-publisher` een ingelogde Safari-context nodig heeft voor formulierinspectie, foto-upload of live controle.\n\n## Doel\n\nGebruik Safari als sessiedrager zonder de gebruiker onnodig te storen. Background-first betekent: geen vensters naar voren halen, geen coordinate-clicks en geen zichtbare UI tenzij de Marktplaats-flow dat echt vereist.\n\n## Voorkeursvolgorde\n\n1. Gebruik gewone HTTP/API/zoek-CLI voor publieke informatie.\n2. Gebruik `marktplaats-place-probe --browser-fetch --url ...` voor authenticated HTML/formulierinspectie vanuit Safari-context.\n3. Gebruik `marktplaats-place-probe --browser --open-background ...` om een plaatsings- of bewerkpagina in Safari te openen zonder Safari te activeren.\n4. Gebruik zichtbare UI alleen voor stappen die niet betrouwbaar via DOM/fetch kunnen: foto-upload, contenteditable tekstcontrole of expliciete visuele bevestiging.\n\n## Niet Storen-Regels\n\n- Activeer Safari niet wanneer background-probe of browser-fetch voldoende is.\n- Open geen extra vensters of schermen bovenop het werk van de gebruiker.\n- Kies Safari-tabs/documenten op URL, categoriepad of advertentie-id, niet op schermpositie.\n- Laat de gebruiker zijn actieve app en tab houden waar dat kan.\n- Gebruik snapshots in `housekeeping/marktplaats-snapshots/` voor bewijs en debugging.\n- Bij foreground UI: meld kort waarom foreground nodig is en doe zo weinig mogelijk.\n\n## Privacyregels\n\n- Cookies, sessietokens, XSRF/auth-waarden, contactgegevens en browserprofielinformatie nooit printen of opslaan.\n- Safari mag credentials gebruiken via normale browsercontext, maar de skill mag die credentials niet exporteren.\n- Geen Marktplaats-wachtwoorden vragen of opslaan.\n\n## Stopmomenten\n\nStop en rapporteer bij:\n\n- login/captcha/MFA/WAF;\n- betaalpagina of promotieroute;\n- onduidelijke formulierstructuur;\n- foto-upload of fototeller die niet te verifieren is;\n- Safari-hang of browser-UI die niet betrouwbaar te herstellen is.\n\nBij een vastgelopen automationproces: stop alleen het vastzittende helperproces waar mogelijk, niet heel Safari."},{"path":"references/guide-en.md","content":"# Marktplaats Seller Assistant - English Guide\n\n## Name\n\n**Marktplaats Seller Assistant**\n\nTechnical skill key: `marktplaats-publisher`.\n\nThe name is intentionally broader than search. The skill supports the selling workflow: category selection, live field inspection, photo preparation/upload, local ad tracking, repost preparation, dry-run review, and publishing only after explicit confirmation.\n\n## Purpose\n\nThis skill helps an agent prepare, place, track and later repost Marktplaats advertisements safely and reliably. Its main value is that it inspects the current category-specific placement form before filling or submitting anything, then stores enough local metadata to revisit the ad later.\n\n## Capabilities\n\n- Search Marktplaats listings.\n- Fetch category and subcategory information.\n- Suggest the best category for an item.\n- Inspect the live placement form in a logged-in browser session.\n- Extract category-specific fields such as condition, brand, type, delivery, price and options.\n- Prepare resized, metadata-reduced photo copies where possible.\n- Guide and verify photo upload through the logged-in browser context.\n- Fill advertisement fields conservatively.\n- Keep paid features disabled by default.\n- Present a dry-run summary.\n- Publish only after explicit approval for that exact advertisement.\n- Report the success URL or validation errors after submission.\n- Track posted advertisements locally.\n- Mark expired or removed advertisements for reposting.\n- Use photos and short item descriptions from WhatsApp/iMessage as ad intake when the user asks.\n- Validate listing descriptions with the hard Copy Quality Gate before filling or publishing Marktplaats.\n\n## What The Skill Must Not Do\n\n- Do not publish or repost without explicit per-ad approval.\n- Do not enable paid options without separate approval.\n- Do not invent price, condition, or uncertain required fields.\n- Do not bypass login, captcha, WAF, or security checks.\n- Do not reply to buyers without separate permission.\n- Do not expose cookies, XSRF tokens, or session data.\n\n## Required Permissions\n\nFor search:\n\n- Network access to Marktplaats.\n- Node.js for the existing CLI tools.\n\nFor preparation:\n\n- Read access to local photo files provided by the user.\n- Read access to relevant WhatsApp/iMessage attachments when the user asks to use them.\n- Write access for ad records, photos and snapshots, preferably:\n  - `~/Documents/OpenClaw/Data/marktplaats/`\n  - `housekeeping/marktplaats-snapshots/`\n  - `housekeeping/marktplaats-test/`\n\nFor publishing:\n\n- A browser session where the user is already logged in to Marktplaats.\n- macOS automation through AppleScript or Peekaboo to use that browser context.\n- Access to the Marktplaats placement page.\n\nThe skill does not need the user's Marktplaats password. Authentication stays inside the browser.\n\n## Local Ad Register\n\nCentral register:\n\n```text\n~/Documents/OpenClaw/Data/marktplaats/advertenties.json\n```\n\nOptional per-ad directory:\n\n```text\n~/Documents/Ope"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register. Skill: Marktplaats Owner: roelbroersma Summary: Marktplaats-advertenties voorbereiden, plaatsen/bewerken, copy-QA, preflight, live-verificatie en register. Tags: latest:0.6.3 Version history: v0.6.3 | 2026-07-09T10:16:48.409Z | user Improve GPT-4.5 mini setup gates and add background-safe Safari probing. v0.6.2 | 2026-07-08T23:55:29.396Z | user Correct 0.6.1 workshop-body publish and ship the actual Marktplaats pipel","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1954,"uniquenessScore":53,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T04:19:36.738Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T04:19:36.738Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:53:01.571Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}