<title>Docscope — see what an Office file still hides</title>
<metaname="description"content="Drop a .docx, .xlsx or .pptx. Docscope unzips it in your browser and shows every OOXML part, plus a leak report for authors, tracked changes, thumbnails, EXIF and hidden sheets. Nothing is uploaded.">
<aclass="btn primary"href="https://teahub.xyz/teahubxyz/time/issues/new?template=early-access.yml&title=Early+access%3A+Docscope&venture=docscope&plan=Pro+%28founding%29">Get early access</a>
<strong>Drag a .docx, .xlsx or .pptx here</strong>
<p>Unzipped locally with <code>DecompressionStream</code>. The page works offline once loaded. The list below is the ZIP central directory, verbatim — nothing is invented.</p>
<inputclass="file-input"id="file"type="file"accept=".docx,.xlsx,.pptx,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.presentationml.presentation"aria-label="Choose an Office file">
</div>
<pclass="meta-line"id="pkg-meta">Loading the preloaded sample through the same unzipper…</p>
<divclass="layout">
<divclass="panel">
<h3>Exploded package</h3>
<divclass="body"id="tree"><pclass="meta-line">No parts yet.</p></div>
<pclass="anno">Click any part in the diagram. Raw XML (or a hex preview of a binary part) appears here, with a plain-English note and a safe-to-send verdict.</p>
<preclass="xml"id="raw">(nothing selected)</pre>
</div>
</div>
<divclass="statusline">
<spanid="status-left">client-side · no upload</span>
<pclass="promise">Drop a .docx, .xlsx or .pptx and see everything still inside it — author names, tracked deletions, thumbnails, comments — dissected on this machine. Nothing is uploaded.</p>
<divclass="hero-actions">
<aclass="try-link"href="#try">Inspect the sample ↑</a>
</div>
<pclass="fineprint">Opens a public GitHub issue. No email, no payment. Nothing is charged today.</p>
<pclass="lede">Only parts the inspector reads are listed. Each link goes to the ECMA-376 5th edition page. Parts we do not understand still appear in the diagram, labelled as unhandled.</p>
<thead><tr><th>Part</th><th>What we read</th><th>Spec</th></tr></thead>
<tbody>
<tr><td><code>[Content_Types].xml</code></td><td>Default and override content types for every part</td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 2, §10.1.2</a></td></tr>
<tr><td><code>_rels/.rels</code> and <code>*.rels</code></td><td>Package and part relationships, including the thumbnail relationship</td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 2, §9.2 / §10.2</a></td></tr>
<tr><td><code>word/comments.xml</code></td><td>Comment author, date, and text</td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 1, §17.13.4</a></td></tr>
<tr><td><code>word/people.xml</code></td><td>Presence authors and user ids</td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 1, people part</a></td></tr>
<tr><td><code>word/styles.xml</code></td><td>Style ids and names (annotation only)</td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 1, §17.7</a></td></tr>
<tr><td><code>word/media/*</code></td><td>Embedded images; JPEG EXIF and PNG tEXt / iTXt</td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 1, §15.2.14 images</a></td></tr>
<tr><td><code>xl/workbook.xml</code></td><td>Sheet names and <code>state="hidden"</code> / <code>veryHidden</code></td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 1, §18.2 workbook</a></td></tr>
<tr><td><code>ppt/presentation.xml</code></td><td>Slides with <code>show="0"</code></td><td><ahref="https://ecma-international.org/publications-and-standards/standards/ecma-376/">ECMA-376 Part 1, §19.2 presentation</a></td></tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
<sectionid="how">
<divclass="wrap">
<pclass="sec-label">How it works</p>
<divclass="steps">
<divclass="step">
<pclass="n">1</p>
<h3>Drop the package</h3>
<p>A .docx, .xlsx or .pptx is a ZIP. The page reads the central directory and inflates each part with the browser's <code>DecompressionStream</code>. Stored and deflate only — the methods Office writes.</p>
</div>
<divclass="step">
<pclass="n">2</p>
<h3>Read the leak report</h3>
<p>Core properties, tracked insertions and deletions, comments, people.xml, thumbnail parts, JPEG EXIF, PNG text, and hidden sheets or slides are flagged from the XML itself.</p>
</div>
<divclass="step">
<pclass="n">3</p>
<h3>Open any part</h3>
<p>Click a name in the diagram. You get the raw XML, or a hex preview if the part is binary, plus a plain-English note on what it does and whether it is safe to send.</p>
</div>
</div>
</div>
</section>
<sectionid="why">
<divclass="wrap">
<pclass="sec-label">Why this exists</p>
<divclass="win">
<divclass="titlebar"><spanclass="glyph"aria-hidden="true"></span><spanclass="caption">Why this exists — the repos this rides</span></div>
<divclass="face">
<pclass="lede">People are generating Office files from plain text again. Docscope rides the trending repos wordcraft, gridcraft and deckcraft: builders starring those projects need to see what the package they just wrote actually contains before it is emailed.</p>
<pclass="note">Plain text in, .docx out. Docscope is the check on the other side: creator, last-modified-by, comments and tracked-change remnants in the file that left the tool.</p>
<pclass="note">Spreadsheets from structured text. Hidden sheets (<code>state="hidden"</code>) and workbook metadata are exactly what a generated .xlsx can still carry.</p>
<pclass="note">Decks from text. A generated .pptx still has a thumbnail, author names, and slides with <code>show="0"</code> that a client can recover.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<sectionid="pricing">
<divclass="wrap">
<pclass="sec-label">Pricing</p>
<divclass="tiers">
<divclass="tier">
<pclass="tier-name">Free</p>
<pclass="price">$0</p>
<pclass="for-whom">Anyone checking a file before it leaves their machine.</p>
<ul>
<li>Full local dissection of .docx, .xlsx and .pptx</li>
<li>Interactive exploded diagram of every OOXML part</li>
<li>Leak report: authors, tracked insertions and deletions, comments, thumbnails, EXIF, hidden sheets and slides</li>
<li>Raw XML with a plain-English note and a safe-to-send verdict</li>
<aclass="btn primary"href="https://teahub.xyz/teahubxyz/time/issues/new?template=early-access.yml&title=Early+access%3A+Docscope&venture=docscope&plan=Pro+%28founding%29">Get early access</a>
<aclass="btn"href="https://teahub.xyz/teahubxyz/time/issues/new?template=early-access.yml&title=Early+access%3A+Docscope&venture=docscope&plan=Team%2FCI+%28founding%29">Get early access</a>
<pclass="nothing-charged">Nothing is charged today.</p>
</div>
</section>
<sectionid="limits"class="honest-limits">
<divclass="wrap">
<pclass="sec-label">Honest limits</p>
<divclass="win">
<divclass="titlebar"><spanclass="glyph"aria-hidden="true"></span><spanclass="caption">Honest limits — what this page does not do</span></div>
<divclass="face">
<ulclass="limits">
<li>Does not yet support PDF or DWG files. Office Open XML packages only: .docx, .xlsx, .pptx.</li>
<li>ZIP method 0 (stored) and method 8 (deflate) only — the methods Office writes. Encrypted packages are not decrypted.</li>
<li>EXIF reading covers JPEG APP1 text (ASCII tags such as Artist and DateTime) and PNG tEXt/iTXt. It does not decode every TIFF IFD type.</li>
<li>No one-click scrubbing in the free version. Inspection shows the leak; it does not rewrite the file.</li>
<li>Batch scanning is only in the Pro version. This page takes one file at a time.</li>
<li>CI and pre-commit checks are only in the Team/CI version.</li>
<li>The parsed file list is the ZIP central directory. If a part is missing from that listing, it is missing here too — we do not fill in parts the package does not have.</li>
"[Content_Types].xml":{title:"Content Types stream",spec:"ECMA-376 Part 2, §10.1.2",note:"Names the media type of every part. Office uses it to decide which XML vocabulary a part speaks. It is not itself a leak, but a missing or odd override is a sign the package was hand-edited.",send:"yes"},
"docProps/core.xml":{title:"Core properties",spec:"ECMA-376 Part 2, §11.1",note:"Dublin Core metadata: title, creator, lastModifiedBy, revision, created and modified. This is the usual place a previous client's name or your own name survives a Save As.",send:"no"},
"docProps/app.xml":{title:"Extended properties",spec:"ECMA-376 Part 1, §22.2",note:"Application, company, template name, and page or word counts. The template name often identifies the firm or the prior engagement the file was cloned from.",send:"careful"},
"docProps/thumbnail.jpeg":{title:"Package thumbnail",spec:"ECMA-376 Part 2, thumbnail relationship",note:"A JPEG preview of the document, stored even when you never inserted an image. It can show a page you have since deleted, and its EXIF can name the author.",send:"no"},
"word/document.xml":{title:"Main document part",spec:"ECMA-376 Part 1, §17.13",note:"The visible text, plus tracked insertions (w:ins), tracked deletions (w:del / w:delText) and comment markers. Accepting changes in Word is not the same as this XML being clean.",send:"careful"},
"word/comments.xml":{title:"Comments part",spec:"ECMA-376 Part 1, §17.13.4",note:"Comment authors, timestamps and the comment text. Deleting a comment in the UI does not always remove this part.",send:"no"},
"word/people.xml":{title:"People part",spec:"ECMA-376 people part",note:"Authors who have touched the document, sometimes with a provider user id or email. Easy to miss because Word never shows this file.",send:"no"},
"word/styles.xml":{title:"Styles part",spec:"ECMA-376 Part 1, §17.7",note:"Paragraph and character styles. Rarely a direct leak; style names copied from a client template can still identify the source firm.",send:"yes"},
"xl/workbook.xml":{title:"Workbook part",spec:"ECMA-376 Part 1, §18.2",note:"Sheet index. state=\"hidden\" or state=\"veryHidden\" marks a sheet the recipient will not see in the tab bar but can unhide.",send:"careful"},
"ppt/presentation.xml":{title:"Presentation part",spec:"ECMA-376 Part 1, §19.2",note:"Slide list. show=\"0\" marks a hidden slide. Hidden is not deleted — the slide XML is still in the package.",send:"careful"}
if(creator.length)add("leak","Author","dc:creator is <strong>"+esc(creator.join(", "))+"</strong>. That name travels with the file.","docProps/core.xml");
if(modifiedBy.length)add("leak","Last modified by","cp:lastModifiedBy is <strong>"+esc(modifiedBy.join(", "))+"</strong>"+(modified.length?" ("+esc(modified.join(", "))+")":"")+".","docProps/core.xml");
if(title.length)add("info","Title","dc:title is “"+esc(title.join(" / "))+"”.","docProps/core.xml");
if(!creator.length&&!modifiedBy.length)add("ok","Core properties","No creator or lastModifiedBy in docProps/core.xml.","docProps/core.xml");
ins.slice(0,6).forEach(function(el){bits.push("insertion by "+esc(attr(el,"author")||"unknown")+(textOf(el)?": “"+esc(textOf(el).slice(0,140))+"”":""));});
del.slice(0,6).forEach(function(el){bits.push("deletion by "+esc(attr(el,"author")||"unknown")+(textOf(el)?": “"+esc(textOf(el).slice(0,140))+"”":""));});
add("leak","Tracked changes",ins.length+" insertion"+(ins.length===1?"":"s")+" (w:ins) and "+del.length+" deletion"+(del.length===1?"":"s")+" (w:del) still in "+esc(part.name)+". "+bits.join("; ")+".",part.name);
if(people.length)add("leak","People",people.length+" person record"+(people.length===1?"":"s")+" in people.xml: <strong>"+esc(people.map(function(el){returnattr(el,"author")||textOf(el);}).filter(Boolean).join(", "))+"</strong>.",part.name);
if(hidden.length)add("leak","Hidden sheets",hidden.map(function(el){returnesc(attr(el,"name")||"(unnamed)")+" ("+esc(attr(el,"state"))+")";}).join(", ")+" — still in the workbook, just not on the tab bar.",part.name);
if(sld.length)add("leak","Hidden slides",sld.length+" slide"+(sld.length===1?"":"s")+" with show=\"0\". Hidden slides stay in ppt/slides/.",part.name);
if(/thumbnail/.test(lower))add("leak","Thumbnail","Embedded thumbnail preview at <code>"+esc(part.name)+"</code> ("+part.size+" bytes). Recipients can open it without Word.",part.name);
add("ok","No leak flags","Nothing in the handled parts matched author names, tracked changes, comments, people, thumbnails, EXIF, PNG text, or hidden sheets/slides. Unhandled parts are still listed in the diagram.");
if(/\.rels$/i.test(part.name))return{title:"Relationships part",spec:"ECMA-376 Part 2, §9.2",note:"Points from one part to another (styles, comments, images, the thumbnail). A thumbnail relationship here is how Explorer finds the preview.",send:"careful"};
if(/media\//i.test(part.name))return{title:"Embedded media",spec:"ECMA-376 Part 1, §15.2.14",note:"A binary file stored inside the package. Images can carry EXIF or PNG text even when the slide looks clean.",send:"careful"};
return{title:"Unhandled part",spec:"",note:"Listed because it is in the ZIP central directory. This page does not interpret this vocabulary; the bytes are shown as-is.",send:"careful"};
treeEl.innerHTML="<p class=\"meta-line\">"+pkg.parts.length+" central-directory entries, shown verbatim. Red marks a part the leak report cited.</p>"+walk(root);