diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e61ab0a37..2b5cba61d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,22 @@ on: # The runner images are pinned to the platforms thirdshift supports. jobs: + site-test: + runs-on: ubuntu-24.04 + defaults: + run: + working-directory: site + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v6 + with: + node-version: 24 + cache: npm + cache-dependency-path: site/package-lock.json + - run: npm ci + - run: npx playwright install --with-deps chromium + - run: npm test + test: runs-on: ubuntu-24.04 steps: diff --git a/.gitignore b/.gitignore index 206591e22..f3975f74c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target +/site/node_modules/ .obsidian/plugins/obsidian-quiet-outline/markdown-states.json .obsidian/user/Jacob-MacBook-Pro/workspace.json .obsidian/user/Jacob-MacBook-Pro/plugins/remote-ssh/data.json diff --git a/site/main.js b/site/main.js index a1ab2e8c3..3b605f96a 100644 --- a/site/main.js +++ b/site/main.js @@ -1,3 +1,31 @@ +// Fragment links on the Prompts and skills page reveal their folded target. +function revealFoldedTarget() { + let id; + try { + id = decodeURIComponent(location.hash.slice(1)); + } catch { + return; + } + const target = document.getElementById(id); + if (!target) return; + let fold = target.matches(".job-sheet") + ? target.querySelector("details.fold") + : target.closest("details.fold"); + if (!fold) return; + while (fold) { + fold.open = true; + fold = fold.parentElement.closest("details.fold"); + } + target.scrollIntoView({ block: "start" }); +} +revealFoldedTarget(); +addEventListener("hashchange", revealFoldedTarget); +document.addEventListener("click", event => { + const link = event.target.closest("a[href^='#']"); + // Repeating the current link doesn't fire hashchange. + if (link && link.hash === location.hash) revealFoldedTarget(); +}); + // Copy buttons: put the command next to the button on the clipboard. for (const button of document.querySelectorAll(".install button.copy")) { const code = button.closest(".install").querySelector("code"); diff --git a/site/package-lock.json b/site/package-lock.json new file mode 100644 index 000000000..d08e1bda6 --- /dev/null +++ b/site/package-lock.json @@ -0,0 +1,41 @@ +{ + "name": "site", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "playwright": "1.64.0" + } + }, + "node_modules/playwright": { + "version": "1.64.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.64.0.tgz", + "integrity": "sha512-kVzTnYFYEyQ9RGzBjNCd2+yEqWmVbxl3AHPynv3qQ6JTjv4a+kwRcnqQwIpuP3NnrnIrE/Q6wWAIAvMfIE2/Yg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.64.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/playwright-core": { + "version": "1.64.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.64.0.tgz", + "integrity": "sha512-T9r+MZkTECl2+oUcZ26YgZzTrYidTsIhYYkJix+6iDOymOb1FB2RLLSOxRGnZGv5DStt+aduIVbt+E8WygXYpg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + } + } +} diff --git a/site/package.json b/site/package.json new file mode 100644 index 000000000..0e35d627b --- /dev/null +++ b/site/package.json @@ -0,0 +1,9 @@ +{ + "private": true, + "scripts": { + "test": "node --test tests/*.test.cjs" + }, + "devDependencies": { + "playwright": "1.64.0" + } +} diff --git a/site/prompts/index.html b/site/prompts/index.html index c317b8db9..8ede0cda3 100644 --- a/site/prompts/index.html +++ b/site/prompts/index.html @@ -33,21 +33,26 @@

Prompts and skills

-

The command line

How each session starts

+
+ The command line

How each session starts

Every session runs claude headless in the Run's worktree, in auto permission mode. The Factory skills are linked into the worktree's .claude/skills/, where Claude Code finds them, and kept out of git. The prompt is one of the templates below.

claude -p --permission-mode auto --output-format stream-json --verbose <prompt>

A Resume continues the session that ended:

claude -p --permission-mode auto --output-format stream-json --verbose --resume <session id> <prompt>

With harness codex, each session runs codex exec --json --dangerously-bypass-approvals-and-sandbox -m <model> -c model_reasoning_effort="<effort>" -c project_doc_fallback_filenames=["CLAUDE.md"] <prompt> instead, without -m <model> or the Effort's -c where they are not set, and with resume <session id> before the prompt for a Resume. The Factory skills are linked into .agents/skills/, and a prompt's first line loads its skill as $thirdshift-<skill>.

+
-

Prompts

What a Run tells the agent

+
+ Prompts

What a Run tells the agent

Every prompt a Run can send, with its placeholders highlighted: they change for each Run.

-

Fresh

+
+

Fresh

+

Starts the implement session, which goes on to review and open the pull request, when the Run starts a new Issue branch.

Sent by 2 · M · Implement

/thirdshift-implement <Issue URL>
@@ -59,9 +64,13 @@ 

Fresh

Include "Closes #<n>" in the PR body. You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Continuation, with no pull request

+
+

Continuation, with no pull request

+

Starts the implement session when the Run is a Continuation of an Issue branch that has no pull request.

Sent by 2 · M · Implement

/thirdshift-implement <Issue URL>
@@ -83,9 +92,13 @@ 

Continuation, with no pull request

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Continuation, with an open pull request

+
+

Continuation, with an open pull request

+

Starts the implement session when the Run is a Continuation of an Issue branch whose pull request is open.

Sent by 2 · M · Implement

/thirdshift-implement <Issue URL>
@@ -107,9 +120,13 @@ 

Continuation, with an open pull request

+
+
-

Spec review

+
+

Spec review

+

In a Spec run, starts the Spec review once every Ticket has landed on the Spec branch, before the Spec PR, a draft until then, is marked ready.

Sent by 3 · Y · Review

/thirdshift-code-review <base>, with the Spec <Spec URL> as the spec
@@ -131,9 +148,13 @@ 

Spec review

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Architecture review

+
+

Architecture review

+

Starts the Architecture review, the session an Architect run opens with, in a worktree at the head of the Base branch. The line naming the focus is left out when the command gives none.

Sent by an Architect run, before any unit

/thirdshift-improve-codebase-architecture
@@ -157,9 +178,13 @@ 

Architecture review

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Security review

+
+

Security review

+

When enabled, runs one guidance review after a Run's opening session or a Spec run's Spec review, before Delivery pushes and enters the Repair loop. Ticket Runs get none; Base fixes get one too. Introduced findings, refusals or incomplete reviews hold Self-merge.

Sent by 3 · Y · Review

Use the `thirdshift-security-audit` skill in guidance mode.
@@ -181,9 +206,13 @@ 

Security review

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Security audit

+
+

Security audit

+

Starts the report-only Security audit in a throwaway worktree at origin's Base branch head. The threat-model line is included when a conventional document exists; artifacts stay under the repository's audit root.

Sent by a Security run, before any unit

/thirdshift-security-audit
@@ -200,9 +229,13 @@ 

Security audit

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Security reproduction

+
+

Security reproduction

+

After a Security audit, tries to reproduce one recorded finding in a fresh throwaway worktree at its audited commit. The test is copied into the private record only after a complete outcome.

Sent by a Security run, before any unit

Reproduce this recorded Security finding at audited commit `<audited commit>`.
@@ -219,9 +252,13 @@ 

Security reproduction

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Conflict Repair

+
+

Conflict Repair

+

Starts a Repair session when merging the Base branch into the Issue branch leaves conflicts.

Sent by 4 · K · Finish

/thirdshift-resolving-merge-conflicts
@@ -233,9 +270,13 @@ 

Conflict Repair

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Security fix publishing

+
+

Security fix publishing

+

With fixing allowed, publishes a terse Ticket or Spec with Tickets for the most severe reproduced finding, reusing a private finding's issue. thirdshift checks and marks it ready before dispatching its Run or Spec run.

Sent by a Security run, before any unit

Publish the fix for this reproduced Security finding on Base branch `<base>`.
@@ -270,9 +311,13 @@ 

Security fix publishing

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

Conflict Repair, on Foreign commits

+
+

Conflict Repair, on Foreign commits

+

In a Merge run, starts a Repair session when merging Foreign commits from the Issue branch on origin into the local one leaves conflicts.

Sent by 4 · K · Finish

/thirdshift-resolving-merge-conflicts
@@ -284,9 +329,13 @@ 

Conflict Repair, on Foreign commit You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.

+
+
-

Review Repair

+
+

Review Repair

+

In a Merge run, starts a Repair session once Foreign commits are merged into the Issue branch, to review them from the head the Run last knew as its own before they can be merged.

Sent by 4 · K · Finish

/thirdshift-code-review <own head>
@@ -304,9 +353,13 @@ 

Review Repair

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

CI-fix Repair

+
+

CI-fix Repair

+

Starts a Repair session when CI fails on the pull request's head commit, listing each failed check.

Sent by 4 · K · Finish

CI failed on pull request <pull request URL> (branch <branch>, implementing <Issue URL>).
@@ -321,9 +374,13 @@ 

CI-fix Repair

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
-

CI-fix Repair, with Inherited failures

+
+

CI-fix Repair, with Inherited failures

+

Starts a Repair session when CI fails on the pull request's head commit and some of the failed checks, but not all, are Inherited failures: they also failed on the Base branch commit the head last merged in, so they are listed apart as not to fix.

Sent by 4 · K · Finish

CI failed on pull request <pull request URL> (branch <branch>, implementing <Issue URL>).
@@ -341,9 +398,13 @@ 

CI-fix Repair, with Inherited fail You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.

+
+
-

Resume

+
+

Resume

+

Continues any session, once, that ended its turn with background work still running, which was killed with it.

Sent by 2 · M · Implement, 3 · Y · Review or 4 · K · Finish

Your background work (<background work>) was killed when your turn ended, because ending the turn ends the session.
@@ -352,19 +413,26 @@ 

Resume

You run headless: nobody is watching, and ending your turn ends the session. Run tests and other long commands in the foreground, raising the command's timeout if needed. If a command is moved to the background, wait for that task by its own task id or output file, never by process names or patterns (`pgrep`, `ps | grep`, and the like): other sessions on this machine run the same commands. Never end your turn while a background task you depend on is still running: ending the turn kills it. Before ending your turn, stop every background task you no longer need, by its task id (with the `TaskStop` tool, if you have it): a task still running when your turn ends is taken as work you were waiting on.
+
+
+
-

Factory skills

The skills, as the agent reads them

+
+ Factory skills

The skills, as the agent reads them

Every Factory skill and supporting file, raw, exactly as thirdshift writes it out.

-

thirdshift-code-review

+
+

thirdshift-code-review

+

Used by 3 · Y · Review

-

thirdshift-code-review/SKILL.md

+
+

thirdshift-code-review/SKILL.md

---
 name: thirdshift-code-review
 description: "Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes: Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/spec asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to \"review since X\"."
@@ -469,16 +537,24 @@ 

thirdshift-code-review/SKILL Reporting them separately stops one axis from masking the other.

-

thirdshift-code-review/agents/openai.yaml

+
+
+

thirdshift-code-review/agents/openai.yaml

interface:
   display_name: "Code Review"
   short_description: "Review a diff on standards and spec"
 
+
+
+
-

thirdshift-codebase-design

+
+

thirdshift-codebase-design

+

Used by the Architecture review, in an Architect run

-

thirdshift-codebase-design/SKILL.md

+
+

thirdshift-codebase-design/SKILL.md

---
 name: thirdshift-codebase-design
 description: Shared vocabulary for designing deep modules. Use when designing or improving a module's interface, finding deepening opportunities, deciding where a seam goes, making code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.
@@ -594,7 +670,9 @@ 

thirdshift-codebase-desi - **Deepening a cluster given its dependencies**, see [DEEPENING.md](DEEPENING.md): dependency categories, seam discipline, and replace-don't-layer testing. - **Exploring alternative interfaces**, see [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md): spin up parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and seam placement.

-

thirdshift-codebase-design/DEEPENING.md

+
+
+

thirdshift-codebase-design/DEEPENING.md

# Deepening
 
 How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [SKILL.md](SKILL.md): **module**, **interface**, **seam**, **adapter**.
@@ -633,7 +711,9 @@ 

thirdshift-codebase- - Tests assert on observable outcomes through the interface, not internal state. - Tests should survive internal refactors, since they describe behaviour, not implementation. If a test has to change when the implementation changes, it's testing past the interface.

-

thirdshift-codebase-design/DESIGN-IT-TWICE.md

+
+
+

thirdshift-codebase-design/DESIGN-IT-TWICE.md

# Design It Twice
 
 To explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout): your first idea is unlikely to be the best.
@@ -679,16 +759,24 @@ 

thirdshift-cod After comparing, decide: which design is strongest and why. If elements from different designs would combine well, take a hybrid. Be opinionated: the choice is yours to make, and nobody picks from a menu. Record the decision and its reason, with the designs you turned down and why.

-

thirdshift-codebase-design/agents/openai.yaml

+
+
+

thirdshift-codebase-design/agents/openai.yaml

interface:
   display_name: "Codebase Design"
   short_description: "Vocabulary for deep-module design"
 
+
+
+
-

thirdshift-implement

+
+

thirdshift-implement

+

Used by 2 · M · Implement

-

thirdshift-implement/SKILL.md

+
+

thirdshift-implement/SKILL.md

---
 name: thirdshift-implement
 description: "Implement a piece of work based on a spec or set of tickets."
@@ -705,18 +793,26 @@ 

thirdshift-implement/SKILL.md< Commit your work to the current branch.

-

thirdshift-implement/agents/openai.yaml

+
+
+

thirdshift-implement/agents/openai.yaml

interface:
   display_name: "Implement"
   short_description: "Build work from a spec or tickets"
 policy:
   allow_implicit_invocation: true
 
+
+
+
-

thirdshift-improve-codebase-architecture

+
+

thirdshift-improve-codebase-architecture

+

Used by the Architecture review, in an Architect run

-

thirdshift-improve-codebase-architecture/SKILL.md

+
+

thirdshift-improve-codebase-architecture/SKILL.md

---
 name: thirdshift-improve-codebase-architecture
 description: "Scan a codebase for deepening opportunities, take the top recommendation, and publish it to the issue tracker: as a plan when it is Strong, as an idea otherwise. Only for an Architecture review."
@@ -849,7 +945,9 @@ 

thirdshift thirdshift reads only that line, so everything else you want read belongs in the issue.

-

thirdshift-improve-codebase-architecture/REPORT.md

+
+
+

thirdshift-improve-codebase-architecture/REPORT.md

# Report Format
 
 The Architecture review's report is Markdown, written into the issue it publishes: the plan's top issue, or the idea issue. GitHub renders Mermaid in a fenced `mermaid` block, so the diagrams live where the issue is read. Write no file, and open nothing.
@@ -962,18 +1060,26 @@ 

thirdshif No hedging, no throat-clearing, no "it's worth noting that…". If a sentence could be a bullet, make it a bullet. If a bullet could be cut, cut it. If a term isn't in the `thirdshift-codebase-design` skill's glossary, reach for one that is before inventing a new one.

-

thirdshift-improve-codebase-architecture/agents/openai.yaml

+
+
+

thirdshift-improve-codebase-architecture/agents/openai.yaml

interface:
   display_name: "Improve Codebase Architecture"
   short_description: "Find and publish the top architecture improvement"
 policy:
   allow_implicit_invocation: true
 
+
+
+
-

thirdshift-pr

+
+

thirdshift-pr

+

Used by 3 · Y · Review

-

thirdshift-pr/SKILL.md

+
+

thirdshift-pr/SKILL.md

---
 name: thirdshift-pr
 description: "Use when writing a PR body."
@@ -1143,21 +1249,31 @@ 

thirdshift-pr/SKILL.md

The blast radius is the potential impact or scope of the changes introduced by this PR. Consider all possibilities. Examples are layout shift, breakages for consumers, mobile responsiveness, etc.
-

thirdshift-pr/CREDITS.md

+
+
+

thirdshift-pr/CREDITS.md

# Credits
 
 "The shape of the change" section is [Dex Horthy](https://github.com/dexhorthy)'s [`show-me`](https://github.com/humanlayer/humanlayer) skill, reproduced almost word for word, aimed at a diff instead of a live conversation. `pr` does not depend on `show-me` as a skill (it isn't part of this repo, and a hard dependency would break standalone installs), so the content is copied in rather than pointed at; this file is the attribution a dependency would otherwise have carried.
 
-

thirdshift-pr/agents/openai.yaml

+
+
+

thirdshift-pr/agents/openai.yaml

interface:
   display_name: "PR"
   short_description: "Write a PR body that's fast to review"
 
+
+
+
-

thirdshift-resolving-merge-conflicts

+
+

thirdshift-resolving-merge-conflicts

+

Used by 4 · K · Finish, in a Repair

-

thirdshift-resolving-merge-conflicts/SKILL.md

+
+

thirdshift-resolving-merge-conflicts/SKILL.md

---
 name: thirdshift-resolving-merge-conflicts
 description: "Use when you need to resolve an in-progress git merge/rebase conflict."
@@ -1172,16 +1288,24 @@ 

thirdshift-res 4. Discover the project's **automated checks** and run them, typically typecheck, then tests, then format. Fix anything the merge broke. 5. **Finish the merge/rebase.** Stage everything, commit, and push. If rebasing, continue the rebase process until all commits are rebased.

-

thirdshift-resolving-merge-conflicts/agents/openai.yaml

+
+
+

thirdshift-resolving-merge-conflicts/agents/openai.yaml

interface:
   display_name: "Resolving Merge Conflicts"
   short_description: "Resolve merge and rebase conflicts"
 
+
+
+
-

thirdshift-security-audit

+
+

thirdshift-security-audit

+

Used by the Security audit, in a Security run, or a Security review

-

thirdshift-security-audit/SKILL.md

+
+

thirdshift-security-audit/SKILL.md

---
 name: thirdshift-security-audit
 description: Security guidance and vulnerability review for codebases, APIs, services, CLI tools, libraries, and daemons. Use for security questions, focused reviews, vulnerability research, security audits, or pen tests. Run the complete workflow only for explicit codebase audit or pen-test requests, full/comprehensive/end-to-end reviews, or requested report artifacts.
@@ -1375,7 +1499,9 @@ 

thirdshift-security-audit 9. Assigning severity to `needs_validation` records. 10. Writing the report before independent verification or letting prose and JSON disagree.

-

thirdshift-security-audit/AI-AND-LLM.md

+
+
+

thirdshift-security-audit/AI-AND-LLM.md

# AI, LLM, and Agent Hunting
 
 #### When to use this file
@@ -1460,7 +1586,9 @@ 

thirdshift-security- 5. For MCP identity claims, verify the authenticated connection, request correlation, tool namespace, and effective credential. Mark `needs_validation` if external server identity or deployment routing is required. 6. Return `confirmed` findings only with a complete source trace and meaningful result. Return `needs_validation` for a specific unresolved boundary fact and state the bounded local or owner-observed check needed to resolve it.

-

thirdshift-security-audit/ATTACK-CLASSES.md

+
+
+

thirdshift-security-audit/ATTACK-CLASSES.md

# Attack Classes
 
 #### Attack classes — choose and split based on Phase 1
@@ -1592,7 +1720,9 @@ 

thirdshift-secur **Important**: For any finding this agent reports, it must verify the full code path, not just surface appearance. If a cookie is missing `HttpOnly`, check whether the cookie contains security-sensitive data and whether JS needs to read it by design. If an error message contains a field name, check whether the field is ever actually populated with sensitive data. A flag is not a finding — trace the impact before reporting.

-

thirdshift-security-audit/CLIENT-SIDE.md

+
+
+

thirdshift-security-audit/CLIENT-SIDE.md

# Client-Side and Browser Hunting
 
 #### When to use this file
@@ -1677,7 +1807,9 @@ 

thirdshift-security 4. For messaging, CORS, WebSocket, and XS-Leaks, show exact origin/source validation and the protected state or action exposed. Confirm that CSP, COOP/CORP, cookies, and SameSite policy do not already block it. 5. Return `confirmed` findings only with a complete client path and bounded local evidence. Return `needs_validation` with the precise deployed header, extension permission, browser version, or renderer behavior an owner must verify.

-

thirdshift-security-audit/CLOUD-AND-DEPLOYMENT.md

+
+
+

thirdshift-security-audit/CLOUD-AND-DEPLOYMENT.md

# Cloud and Deployment Hunting
 
 #### When to use this file
@@ -1765,7 +1897,9 @@ 

thirdshift 4. Local validation may render templates, evaluate policy, inspect container/user namespaces in an isolated fixture, or run an emulator with dummy identities. Do not probe live endpoints or alter shared cloud resources. 5. Return `confirmed` only with a complete active source trace and concrete boundary result. Return `needs_validation` with the exact deployed policy, identity attachment, overlay, network, or drift observation needed.

-

thirdshift-security-audit/CREDITS.md

+
+
+

thirdshift-security-audit/CREDITS.md

# Upstream and licence
 
 Copied from Cloudflare's [security-audit-skill](https://github.com/cloudflare/security-audit-skill), at commit [`c1c8a8c1471069fb0e188eeaff69b8e8db6564a8`](https://github.com/cloudflare/security-audit-skill/tree/c1c8a8c1471069fb0e188eeaff69b8e8db6564a8).
@@ -1774,7 +1908,9 @@ 

thirdshift-security-aud Used under the MIT License. Cloudflare's copyright notice and licence are kept in [LICENSE](LICENSE) in this directory.

-

thirdshift-security-audit/DATA-ISOLATION-AND-LIFECYCLE.md

+
+
+

thirdshift-security-audit/DATA-ISOLATION-AND-LIFECYCLE.md

# Data Isolation and Lifecycle Hunting
 
 #### When to use this file
@@ -1860,7 +1996,9 @@ 

th 4. If external cache, object storage, replicas, analytics, backup, or retention policy is required, classify `needs_validation` and state the owner-observed check. 5. Return `confirmed` only with complete lineage and concrete boundary impact. Return `needs_validation` with the exact unresolved storage, ACL, invalidation, retention, or restore fact.

-

thirdshift-security-audit/DESKTOP-MOBILE-AND-LOCAL-IPC.md

+
+
+

thirdshift-security-audit/DESKTOP-MOBILE-AND-LOCAL-IPC.md

# Desktop, Mobile, and Local IPC Hunting
 
 #### When to use this file
@@ -1951,7 +2089,9 @@ 

th 4. Keep local tests bounded and use dummy content/accounts. Stop after proving the boundary result; do not extend proof into persistence or broader system modification. 5. Return `confirmed` only with a complete source and local evidence chain. Return `needs_validation` with the exact OS, manifest, signing, ACL, or device-lifecycle fact required.

-

thirdshift-security-audit/HUNTING.md

+
+
+

thirdshift-security-audit/HUNTING.md

# Vulnerability Hunting
 
 ### Phase 2: Run coverage-led hunting waves
@@ -2204,7 +2344,9 @@ 

thirdshift-security-aud A budget bounds it the same way. Before assigning each wave, compare remaining budget against its hunter count, the validation reserve, the immediate post-wave critic, and the retained final-clean critic (`quick` reserves only its single final post-wave critic). Shrink the hunter wave to fit, taking units in priority order. If those mandatory reserves do not fit, launch no hunter from that wave and mark its planned units `deferred` with reason `budget_cannot_reserve_critics_and_validation`. Critic-proposed units enter the same ranked queue rather than extending the budget. If surviving candidates exceed the validation reserve, follow the incomplete-run rule in `SKILL.md`: stop hunting, validate in fingerprint order, retain unvalidated units as unresolved candidates, and never present them as findings.

-

thirdshift-security-audit/LICENSE

+
+
+

thirdshift-security-audit/LICENSE

MIT License
 
 Copyright (c) 2025-2026 Cloudflare, Inc.
@@ -2227,7 +2369,9 @@ 

thirdshift-security-audit/ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-

thirdshift-security-audit/MEMORY-SAFETY-AND-BINARY.md

+
+
+

thirdshift-security-audit/MEMORY-SAFETY-AND-BINARY.md

# Memory Safety, Binary, and Kernel Hunting
 
 #### When to use this file
@@ -2330,7 +2474,9 @@ 

thirds 4. For concurrency, use a deterministic schedule or sanitizer trace. For binary loading, prove the checked identity differs from the mapped identity and name the lower-trust writer. 5. Return `confirmed` findings only with exact input, source trace, and observed result. Return `needs_validation` for a specific unresolved reachability, ABI, build, deployment, or runtime fact and state the bounded check needed.

-

thirdshift-security-audit/PROTOCOLS-RPC-AND-MESSAGING.md

+
+
+

thirdshift-security-audit/PROTOCOLS-RPC-AND-MESSAGING.md

# Protocols, RPC, and Messaging Hunting
 
 #### When to use this file
@@ -2413,7 +2559,9 @@ 

thi 4. For authorization and isolation, verify all interceptor, broker ACL, gateway, and consumer layers visible in source. External attachments make the candidate `needs_validation`. 5. Return `confirmed` only with the complete message lifecycle and observed meaningful result. Return `needs_validation` with the exact broker, service identity, route, or delivery fact required.

-

thirdshift-security-audit/RECONNAISSANCE.md

+
+
+

thirdshift-security-audit/RECONNAISSANCE.md

# Reconnaissance
 
 ### Phase 1: Map the source and plan coverage
@@ -2571,7 +2719,9 @@ 

thirdshift-secur Run `node <skill-dir>/validate-coverage-ledger.cjs <output-dir>/coverage-ledger.json` after seeding, after every parent update, and before Phase 6. The validator rejects input beyond 5 MiB, 64 nesting levels, 10,000 units, 1,000 entries in a nested collection, or 500,000 traversed values, and caps reported validation errors at 100. In practice the 5 MiB byte limit holds roughly 2,000-5,000 realistic units, so it binds before the 10,000-unit cap. Fix every error before assigning work or making a coverage claim.

-

thirdshift-security-audit/RESOURCE-EXHAUSTION-AND-AVAILABILITY.md

+
+
+

thirdshift-security-audit/RESOURCE-EXHAUSTION-AND-AVAILABILITY.md

# Resource Exhaustion and Availability Hunting
 
 #### When to use this file
@@ -2651,7 +2801,9 @@ 

4. Prioritize by low requester work, unauthenticated reachability, cross-tenant scope, persistence, and poor recovery; do not validate with availability impact. 5. Return `confirmed` only with safe local proof and meaningful shared effect. Return `needs_validation` with the exact upstream limit, topology, quota, or recovery observation an owner must check.

-

thirdshift-security-audit/SUPPLY-CHAIN-AND-RELEASE.md

+
+
+

thirdshift-security-audit/SUPPLY-CHAIN-AND-RELEASE.md

# Supply Chain and Release Hunting
 
 #### When to use this file
@@ -2726,7 +2878,9 @@ 

thirds 4. Keep local validation bounded: use a harmless fixture repository, dummy credential marker, local registry/config, and non-production artifact namespace. Do not publish or alter a real release. 5. Return `confirmed` only with a complete source-visible handoff and meaningful result. Return `needs_validation` with the precise branch, runner, registry, signing, or deployment fact an owner must observe.

-

thirdshift-security-audit/VALIDATION-AND-REPORTING.md

+
+
+

thirdshift-security-audit/VALIDATION-AND-REPORTING.md

# Validation, Structured Output, Verification, and Reporting
 
 ### Phase 3: Independently validate every candidate
@@ -2914,7 +3068,9 @@ 

thirds Keep the report proportional to the evidence. A clean run may have zero confirmed records. State that result and the remaining coverage/validation limits without inventing LOW findings.

-

thirdshift-security-audit/WEB-PROTOCOL-AND-AUTH.md

+
+
+

thirdshift-security-audit/WEB-PROTOCOL-AND-AUTH.md

# HTTP-Protocol and Authentication Hunting
 
 #### When to use this file
@@ -3021,7 +3177,9 @@ 

thirdshif 5. Verify framework and library defaults. If version or configuration is unknown, use `needs_validation`; do not turn an unverified critical claim into a lower-severity confirmed finding. 6. Return `confirmed` only with a complete source trace and observable unauthorized identity, state, or disclosure. For `needs_validation`, name the missing fact and safe local or owner-observed check that resolves it.

-

thirdshift-security-audit/report-schema.json

+
+
+

thirdshift-security-audit/report-schema.json

{
   "$comment": "Top-level contract for findings.json. validate-findings.cjs interprets and checks this schema directly.",
   "type": "array",
@@ -3484,7 +3642,9 @@ 

thirdshift-secu } }

-

thirdshift-security-audit/validate-coverage-ledger.cjs

+
+
+

thirdshift-security-audit/validate-coverage-ledger.cjs

#!/usr/bin/env node
 
 /**
@@ -4358,7 +4518,9 @@ 

third if (require.main === module) process.exit(run(process.argv[2]));

-

thirdshift-security-audit/validate-coverage-ledger.test.cjs

+
+
+

thirdshift-security-audit/validate-coverage-ledger.test.cjs

const assert = require("node:assert/strict");
 const fs = require("node:fs");
 const os = require("node:os");
@@ -5100,7 +5262,9 @@ 

} });

-

thirdshift-security-audit/validate-findings.cjs

+
+
+

thirdshift-security-audit/validate-findings.cjs

#!/usr/bin/env node
 
 /**
@@ -5875,7 +6039,9 @@ 

thirdshift-s if (require.main === module) process.exit(run(process.argv[2]));

-

thirdshift-security-audit/validate-findings.test.cjs

+
+
+

thirdshift-security-audit/validate-findings.test.cjs

const assert = require("node:assert/strict");
 const fs = require("node:fs");
 const os = require("node:os");
@@ -6529,11 +6695,17 @@ 

thirdsh } });

+
+
+
-

thirdshift-tdd

+
+

thirdshift-tdd

+

Used by 2 · M · Implement

-

thirdshift-tdd/SKILL.md

+
+

thirdshift-tdd/SKILL.md

---
 name: thirdshift-tdd
 description: Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
@@ -6573,12 +6745,16 @@ 

thirdshift-tdd/SKILL.md

- **One slice at a time.** One seam, one test, one minimal implementation per cycle. - **Refactoring is not part of the loop.** It belongs to the review stage (see the `thirdshift-code-review` skill), not the red → green implementation cycle.
-

thirdshift-tdd/agents/openai.yaml

+
+
+

thirdshift-tdd/agents/openai.yaml

interface:
   display_name: "TDD"
   short_description: "Test-driven red-green-refactor"
 
-

thirdshift-tdd/mocking.md

+
+
+

thirdshift-tdd/mocking.md

# When to Mock
 
 Mock at **system boundaries** only:
@@ -6639,7 +6815,9 @@ 

thirdshift-tdd/mocking.md

-

thirdshift-tdd/tests.md

+
+
+

thirdshift-tdd/tests.md

# Good and Bad Tests
 
 ## Good Tests
@@ -6718,11 +6896,17 @@ 

thirdshift-tdd/tests.md

}); ```
+
+
+
-

thirdshift-to-spec

+
+

thirdshift-to-spec

+

Used by the Architecture review, in an Architect run, or Security fix publishing, in a Security run

-

thirdshift-to-spec/SKILL.md

+
+

thirdshift-to-spec/SKILL.md

---
 name: thirdshift-to-spec
 description: "Turn the current session into a spec and publish it to the project issue tracker: no interview, just synthesis of what you've already settled. For an Architecture review or Security fix publishing."
@@ -6803,18 +6987,26 @@ 

thirdshift-to-spec/SKILL.md

-

thirdshift-to-spec/agents/openai.yaml

+
+
+

thirdshift-to-spec/agents/openai.yaml

interface:
   display_name: "To Spec"
   short_description: "Turn a session into a spec"
 policy:
   allow_implicit_invocation: true
 
+
+
+
-

thirdshift-to-tickets

+
+

thirdshift-to-tickets

+

Used by the Architecture review, in an Architect run, or Security fix publishing, in a Security run

-

thirdshift-to-tickets/SKILL.md

+
+

thirdshift-to-tickets/SKILL.md

---
 name: thirdshift-to-tickets
 description: Break a plan, spec, or the current session into a set of tracer-bullet tickets, each declaring its blocking edges, published to the issue tracker with native sub-issue and blocking links. For an Architecture review or Security fix publishing.
@@ -6918,22 +7110,30 @@ 

thirdshift-to-tickets/SKILL.m Avoid specific file paths or code snippets: they go stale fast. Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it and note briefly that it came from a prototype. Trim to the decision-rich parts, not a working demo, just the important bits.

-

thirdshift-to-tickets/agents/openai.yaml

+
+
+

thirdshift-to-tickets/agents/openai.yaml

interface:
   display_name: "To Tickets"
   short_description: "Split a plan into tracer-bullet tickets"
 policy:
   allow_implicit_invocation: true
 
+
+
+
+
-

Licence and credits

Whose skills these are

+
+ Licence and credits

Whose skills these are

Most Factory skills are adapted from Matt Pocock's skills, under the licence below. The thirdshift-pr skill credits Dex Horthy's show-me skill in its CREDITS.md. The thirdshift-security-audit skill is copied from Cloudflare's security-audit-skill, under its own MIT licence, with its upstream repository and commit recorded in CREDITS.md.

-

LICENSE

+
+

LICENSE

MIT License
 
 Copyright (c) 2026 Matt Pocock
@@ -6956,6 +7156,8 @@ 

LICENSE

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
diff --git a/site/styles.css b/site/styles.css index 5b72b0b87..637eff161 100644 --- a/site/styles.css +++ b/site/styles.css @@ -328,6 +328,16 @@ body::after { /* scanlines */ .job-sheet h3 { font-size: 30px; } .job-sheet h4 { margin: 10px 0 0; font: 700 13px/1.3 var(--f-mono); color: var(--dim); } .job-sheet p { margin: 0; max-width: 90ch; } +.job-body { display: grid; gap: 10px; margin-top: 10px; } +.fold > summary { display: block; position: relative; padding-right: 32px; cursor: pointer; } +.fold > summary::-webkit-details-marker { display: none; } +.fold > summary::after { content: "+"; position: absolute; right: 0; top: 0; color: var(--c); font: 700 24px/1 var(--f-mono); } +.fold[open] > summary::after { content: "−"; } +.fold > .sec-head { display: grid; margin-bottom: 0; } +.fold[open] > .sec-head { margin-bottom: 28px; } +.fold > summary h4 { margin: 0; overflow-wrap: anywhere; } +.fold > summary + .job-text { margin-top: 10px; } +.fold > .lede + .job-sheets { margin-top: 28px; } .sent-by { font-size: 13px; color: var(--dim); } .job-text { margin: 0; padding: 14px 16px; background: #000; border: 1px solid var(--rule); font-size: 13px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; } diff --git a/site/tests/README.md b/site/tests/README.md new file mode 100644 index 000000000..310eb319b --- /dev/null +++ b/site/tests/README.md @@ -0,0 +1,13 @@ +# Browser tests + +The site still serves static files with no build step. To run its browser tests: + +```sh +cd site +npm ci +npx playwright install --with-deps chromium +npm test +``` + +The tests start a local server on an unused port and close it and the browser +before exiting. CI runs them in the `site-test` job. diff --git a/site/tests/prompts.test.cjs b/site/tests/prompts.test.cjs new file mode 100644 index 000000000..7c6994204 --- /dev/null +++ b/site/tests/prompts.test.cjs @@ -0,0 +1,110 @@ +const { test, before, after } = require("node:test"); +const assert = require("node:assert/strict"); +const { createServer } = require("node:http"); +const { readFile } = require("node:fs/promises"); +const { join } = require("node:path"); +const { chromium } = require("playwright"); + +let server, browser, origin; +before(async () => { + server = createServer(async (request, response) => { + const path = new URL(request.url, "http://localhost").pathname; + const file = path === "/prompts/" ? "prompts/index.html" : path.slice(1); + try { + const content = await readFile(join(__dirname, "..", file)); + const type = file.endsWith(".js") ? "text/javascript" : file.endsWith(".css") ? "text/css" : "text/html"; + response.writeHead(200, { "Content-Type": type }).end(content); + } catch { + response.writeHead(404).end(); + } + }); + await new Promise(resolve => server.listen(0, "127.0.0.1", resolve)); + origin = `http://127.0.0.1:${server.address().port}`; + browser = await chromium.launch({ headless: true }); +}); +after(async () => { + await browser?.close(); + if (server) await new Promise(resolve => server.close(resolve)); +}); + +async function pageForTest(t, options) { + const context = await browser.newContext(options); + t.after(() => context.close()); + const page = await context.newPage(); + await page.route("https://**", route => route.abort()); + return page; +} + +test("every headed section starts closed and toggles independently by its heading", async (t) => { + const page = await pageForTest(t); + await page.goto(`${origin}/prompts/`); + const headings = page.locator("main :is(h2, h3, h4)"); + assert.ok(await headings.count() > 30); + const ids = await headings.evaluateAll(nodes => nodes.map(node => node.id)); + for (const id of ids) { + assert.equal(await page.locator(`#${id}`).evaluate(heading => { + const summary = heading.closest("summary"); + return Boolean(summary && summary.parentElement.tagName === "DETAILS" && !summary.parentElement.open); + }), true, `${id} must control a closed section`); + } + assert.equal(await page.locator("main details[open]").count(), 0); + for (const id of ids) { + const heading = page.locator(`#${id}`); + // Open only the containing sections, as a reader does before reaching a nested heading. + const ancestors = await heading.evaluate(node => { + const ids = []; + for (let parent = node.closest("details")?.parentElement; parent; parent = parent.parentElement) { + if (parent.tagName === "DETAILS") ids.unshift(parent.querySelector("summary :is(h2,h3,h4)").id); + } + return ids; + }); + for (const parent of ancestors) { + if (!await page.locator(`#${parent}`).evaluate(node => node.closest("details").open)) { + await page.locator(`#${parent}`).click(); + } + } + await heading.click(); + assert.equal(await heading.evaluate(node => node.closest("details").open), true, id); + const content = heading.locator("xpath=ancestor::summary/parent::details/*[not(self::summary)][1]"); + assert.equal(await content.isVisible(), true, `${id} reveals its content`); + await heading.click(); + assert.equal(await heading.evaluate(node => node.closest("details").open), false, id); + assert.equal(await content.isVisible(), false, `${id} hides its content`); + } + await page.locator("#command-title").click(); + await page.locator("#prompts-title").click(); + assert.equal(await page.locator("#command-title").evaluate(node => node.closest("details").open), true); +}); + +test("fragment links reveal the prompt or supporting file and its containing sections", async (t) => { + const page = await pageForTest(t); + await page.goto(`${origin}/prompts/#prompt-resume`); + assert.equal(await page.locator("#prompt-resume .job-text").isVisible(), true); + await page.goto(`${origin}/prompts/`); + await page.locator("#licence-title").click(); + await page.locator('a[href="#file-thirdshift-pr-credits-md"]').click(); + const credits = page.locator("#file-thirdshift-pr-credits-md").locator("xpath=ancestor::details[1]/pre"); + assert.equal(await credits.isVisible(), true); + // A link to the current fragment must reveal a section the reader closed. + await page.locator("#file-thirdshift-pr-credits-md").click(); + assert.equal(await credits.isVisible(), false); + await page.locator('a[href="#file-thirdshift-pr-credits-md"]').click(); + assert.equal(await credits.isVisible(), true); +}); + +test("mobile readers can toggle headings with the keyboard without JavaScript", async (t) => { + const page = await pageForTest(t, { javaScriptEnabled: false, viewport: { width: 390, height: 844 } }); + await page.goto(`${origin}/prompts/`); + assert.equal(await page.locator("main details[open]").count(), 0); + const prompts = page.locator("#prompts-title").locator("xpath=parent::summary"); + await prompts.focus(); + await page.keyboard.press("Enter"); + assert.equal(await page.locator("#prompt-fresh-title").isVisible(), true); + const fresh = page.locator("#prompt-fresh-title").locator("xpath=parent::summary"); + await fresh.focus(); + await page.keyboard.press("Space"); + assert.equal(await page.locator("#prompt-fresh .job-text").isVisible(), true); + await page.keyboard.press("Space"); + assert.equal(await page.locator("#prompt-fresh .job-text").isVisible(), false); + assert.equal(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth), true); +}); diff --git a/src/prompts_page.rs b/src/prompts_page.rs index 37b29adfe..c5e90c53f 100644 --- a/src/prompts_page.rs +++ b/src/prompts_page.rs @@ -439,12 +439,14 @@ fn command_line(html: &mut String) { html, r##"
-

The command line

How each session starts

+
+ The command line

How each session starts

Every session runs claude headless in the Run's worktree, in auto permission mode. The Factory skills are linked into the worktree's .claude/skills/, where Claude Code finds them, and kept out of git. The prompt is one of the templates below.

{new}

A Resume continues the session that ended:

{resume}

{codex}

+
"##, @@ -458,7 +460,8 @@ fn prompt_section(html: &mut String) { html.push_str( r##"
-

Prompts

What a Run tells the agent

+
+ Prompts

What a Run tells the agent

Every prompt a Run can send, with its placeholders highlighted: they change for each Run.

"##, @@ -467,10 +470,14 @@ fn prompt_section(html: &mut String) { let _ = write!( html, r##"
-

{title}

+
+

{title}

+

{when}

Sent by {sender}

{text}
+
+
"##, id = prompt.id, @@ -480,14 +487,15 @@ fn prompt_section(html: &mut String) { text = highlighted(&prompt.text), ); } - html.push_str("
\n
\n
\n"); + html.push_str(" \n \n \n\n"); } fn skills_section(html: &mut String) { html.push_str( r##"
-

Factory skills

The skills, as the agent reads them

+
+ Factory skills

The skills, as the agent reads them

Every Factory skill and supporting file, raw, exactly as thirdshift writes it out.

"##, @@ -499,7 +507,9 @@ fn skills_section(html: &mut String) { let _ = write!( html, r##"
-

{name}

+
+

{name}

+

Used by {used_by}

"##, used_by = skill_used_by(&name), @@ -516,16 +526,17 @@ fn skills_section(html: &mut String) { for file in files { file_block(html, file, " "); } - html.push_str("
\n"); + html.push_str("
\n
\n \n"); } - html.push_str("
\n \n
\n"); + html.push_str(" \n \n \n\n"); } fn licence_section(html: &mut String) { html.push_str( r##"
-

Licence and credits

Whose skills these are

+
+ Licence and credits

Whose skills these are

Most Factory skills are adapted from Matt Pocock's skills, under the licence below. The thirdshift-pr skill credits Dex Horthy's show-me skill in its CREDITS.md. The thirdshift-security-audit skill is copied from Cloudflare's security-audit-skill, under its own MIT licence, with its upstream repository and commit recorded in CREDITS.md.

"##, ); @@ -539,7 +550,7 @@ fn licence_section(html: &mut String) { ); file_block(html, file, " "); } - html.push_str("
\n
\n"); + html.push_str(" \n \n\n"); } /// Every file under `dir`, at any depth. @@ -550,7 +561,7 @@ fn collect_files<'a>(dir: &'a Dir<'a>, files: &mut Vec<&'a File<'a>>) { } } -/// A file's path as a heading, then its raw text. +/// A file's path as a disclosure heading, then its raw text. fn file_block(html: &mut String, file: &File, indent: &str) { let path = file.path().to_string_lossy(); let text = file @@ -563,7 +574,7 @@ fn file_block(html: &mut String, file: &File, indent: &str) { .collect(); let _ = write!( html, - "{indent}

{path}

\n{indent}
{text}
\n", + "{indent}
\n{indent}

{path}

\n{indent}
{text}
\n{indent}
\n", path = escape(&path), text = escape(text), );