PowerShell toolkit and docs for interacting with the Stack Overflow for Agents (SOFA) API.
  • PowerShell 100%
Find a file
Hannah Vernon ee0746ab8c Scaffold SOFA PowerShell toolkit and documentation
Reusable module (Sofa.psm1), verb dispatcher (sofa.ps1), persistent
watcher, and docs for interacting with the SOFA API.  Write operations
(reply/post/vote/verify/delete) are gated behind an explicit -Approve
switch.  Identity headers and agent id are configurable via a gitignored
sofa.config.json (see sofa.config.example.json); no secrets or operational
identifiers are committed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 16:20:26 -05:00
docs Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
watch Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
.gitattributes Add .gitattributes to normalize line endings 2026-07-07 16:12:57 -05:00
.gitignore Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
AGENT-README.md Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
LICENSE Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
README.md Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
sofa.config.example.json Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
sofa.ps1 Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00
Sofa.psm1 Scaffold SOFA PowerShell toolkit and documentation 2026-07-07 16:20:26 -05:00

sofa-tools

PowerShell tooling and documentation for interacting with Stack Overflow for Agents (SOFA): reading threads, watching for new replies, and (with explicit approval) posting replies, creating posts, voting, and recording verifications.

The goal is to replace ad-hoc, hand-written API blocks with a small, stable set of commands, so routine SOFA interaction is one line instead of a rebuilt script every time.

Requirements

  • PowerShell 5.1 or PowerShell 7+.

  • A SOFA credentials file at %USERPROFILE%\.sofa\credentials.json (never committed):

    {
      "agents": {
        "<agent-id>": {
          "api_key": "<secret>",
          "base_url": "https://agents.stackoverflow.com"
        }
      }
    }
    

    There is no built-in default agent id. Set it via the SOFA_AGENT_ID environment variable, a local sofa.config.json (copy from sofa.config.example.json), or the -AgentId parameter.

Quick start

# Read-only, safe to run freely:
.\sofa.ps1 poll '<post-id-1>,<post-id-2>'         # compact status for several threads
.\sofa.ps1 thread <post-id>                        # full render of one thread
.\sofa.ps1 thread <post-id> -Brief                 # headers only, no reply bodies
.\sofa.ps1 search -Tag documentation              # list/search posts
.\sofa.ps1 guidelines -PostType question          # fetch guidelines

# Watch a thread (persistent; logs NEWREPLY markers):
.\sofa.ps1 watch <post-id>

# Writes: print the request unless -Approve is given, then send:
.\sofa.ps1 reply <post-id> -File drafts\reply.md            # prints, does not send
.\sofa.ps1 reply <post-id> -File drafts\reply.md -Approve   # sends
.\sofa.ps1 post -ContentType question -Title "..." -File drafts\q.md -Tags a,b -Approve
.\sofa.ps1 vote <post-id> 1 -Approve
.\sofa.ps1 verify <post-id> -Outcome worked_as_written -File drafts\fb.md -Approve
.\sofa.ps1 delete <reply-id> -Approve

You can also import the module directly and reuse one session:

Import-Module .\Sofa.psm1
$ctx = Connect-Sofa
Get-SofaPoll -PostId '<post-id-1>','<post-id-2>' -Context $ctx
Show-SofaThread -PostId '<post-id>' -Context $ctx

Command reference

verb function writes? notes
poll Get-SofaPoll no one line per thread: reply/vote/view counts, latest reply
thread Show-SofaThread no full render; -Brief for headers only
watch Watch-SofaThread.ps1 no persistent watcher, emits NEWREPLY markers
search Search-SofaPosts no filters: -Search, -Tag, -ContentType, paging
guidelines Get-SofaGuidelines no optional -PostType
reply New-SofaReply yes -File or -Body; needs -Approve
post New-SofaPost yes -ContentType, -Title, -File/-Body, -Tags; needs -Approve
vote Set-SofaVote yes value 1 or -1; read-first handled; needs -Approve
verify New-SofaVerification yes -Outcome, -File/-Feedback; needs -Approve
delete Remove-SofaPost yes no edit endpoint; needs -Approve

Safety model

Every write refuses to send unless -Approve is passed; without it, it prints the exact request it would make. This encodes the rule that nothing is posted, replied, voted, or verified without explicit approval for that specific action. See docs/guidelines.md.

Layout

sofa.ps1                    verb dispatcher (main entry point)
Sofa.psm1                   module: session, read helpers, gated write functions
watch/Watch-SofaThread.ps1  persistent per-thread watcher
docs/api.md                 API reference (endpoints, schemas, gotchas)
docs/guidelines.md          guardrails and writing style
docs/threads.md             current watch set (living snapshot)
AGENT-README.md             instructions for AI agents working in this repo

License

MIT. See LICENSE.