
Autark
- 15 installs
- 1 repo stars
- Updated July 15, 2026
- kiluazen/kstack
Helps with ai & agent building tasks.
About
autark is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- autark
- AI & Agent Building
- AI-coding skill
Autark by the numbers
- 15 all-time installs (skills.sh)
- Ranked #11,187 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kiluazen/kstack --skill autarkAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 15 |
|---|---|
| repo stars | ★ 1 |
| Last updated | July 15, 2026 |
| Repository | kiluazen/kstack ↗ |
What it does
Helps with ai & agent building tasks.
Files
Autark
Use this skill to run market-discovery experiments for an Autark product. The job is to form narrow hypotheses and fill the lead sheet through the autark CLI: one deduped person plus one lead.angle for every prospect worth pursuing.
Operating Contract
You are permissionless inside the sourcing loop. If the next useful step is to search, read a repo, crawl a site, or dig up a first-party email, do it.
When you are genuinely blocked by credentials, payment, login, unclear judgment, or broken tooling, post to Plumcake and keep working through another channel. Plumcake is a bulletin board, not a pause button.
Data Model
product
has many hypotheses
has many people (person: one deduped human under one product)
has many leads (lead: person × hypothesis — the angle + the verdict)
has many channel_states (one per channel: the live stage on email / linkedin / …)
has many runs through hypothesesproduct: the thing being tested.hypothesis: a frozen bet. Create a newH##when the angle changes; do not rewrite old hypotheses.person: one deduped human — identity (full_name,primary_email,handles) plus enrichment (headline,bio,signals) andcompany_domain(the grouping key behind "who else do we know at <company>"). No stage or angle lives here.lead: one person under one hypothesis — carries theangle(why this human belongs under this bet) and anoutcome(open→landed/dead). Outcome is the verdict on the whole pursuit across every channel, and it is yours to set, not the machine's —openwhile you're still working it,landedwhen it converts,deadwhen it's over (opt-out / hard no). Outcome is what hides a lead from the action queues. The same human under two bets is one person, two leads.channel_state: the live per-channel rollup — one row per (lead, channel). It is derived from the touch log, not set by hand: each touch you record advances its channel'sstage. Stages by channel:- email:
ready(verified/sourced address, mailable now) →contacted→replied(+bounced) - linkedin:
reachable(handle known) →invited→accepted→contacted→replied(+withdrawn/blocked)
Each channel_state also tracks needs_reply (true = they sent the last word, the ball is in our court), last_out_at, last_in_at, attempt_count. A lead can be live on several channels at once — email:contacted and linkedin:invited side by side.
touch: one real interaction on one lead —channel,event(source/invite/accept/message/bounce/withdraw/block/note),direction(out|in),ref(AgentMail thread id, invite URL, the permalink of YOUR comment),summary. The append-only touch log is the source of truth; channel_state is its materialized rollup. Bodies stay external; the touch is a pointer.run: one work session under one hypothesis, sealed withnarrative_md: context, decisions, follow-ups, and what changed.
Migration note: the old singlelead.statusfield still exists and is kept in sync, but the real model is now per-channelstage+ leadoutcome. Read and write through the channel-aware commands below; reach forlead statusonly as a legacy override.
Re-sourcing the same email or handle under the same product updates the existing person instead of duplicating — ids are deterministic, so lead add is idempotent.
The CLI gives primitives, and every write is against an explicit id. Autark never guesses which lead an email or interaction belongs to — you name the lead_id, or nothing is recorded. Read ids from autark context before writing.
CLI Surface
The CLI talks to the Autark Worker. After autark login, credentials live in ~/.autark/credentials.json for about 30 days. Writes are ID-first: resolve ids from autark context, then pass --hypothesis-id / --run-id.
| Command | Purpose |
|---|---|
autark login send <email> | Send a 6-digit login code |
autark login verify <email> --code <code> | Verify and save local credentials |
autark me | Print signed-in user |
autark logout | Remove local credentials |
| `autark product upsert --slug <s> --name <n> [--url <u>] [--tagline <t>] [--visibility public\ | private]` |
autark product list | List owned products |
autark hypothesis create --product-id <id> --code H## --md @./hyp.md [--title <t>] | Create a frozen hypothesis |
| `autark hypothesis status <slug>/<H##> --status active\ | inactive\ |
autark run start --hypothesis-id <id> | Start a run and print RUN_ID |
autark lead template | Print the minimal lead payload shape |
autark lead add --hypothesis-id <id> --run-id <id> --input @/tmp/lead.json | Upsert a person + create a lead in one write |
autark mail send --lead-id <id> --to <email> --subject <s> --text @draft.txt | Send email AND record the touch AND advance the email channel, atomically |
| `autark touch record --lead-id <id> --channel <c> --event <e> [--direction out\ | in] [--ref <ref>]` |
autark lead list <slug>[/<H##>] [filters] | The front door: one line per lead, ids first. Filters (combine): `--channel email\ |
autark lead show <lead-id> | One lead fully loaded: person, bet, outcome, per-channel state, ordered touch log with ids — run this when handed a lead link or a bare id (https://autark.sh/<slug>?lead=<id> carries it in the query param) |
autark touch mute <touch-id> | Judge an inbound touch a non-reply (ticket bot, autoresponder); channel_state recomputes, sweep respects it |
| `autark lead outcome <lead-id> --set open\ | landed\ |
autark lead status <lead-id> --status <s> | Legacy single-channel status override — prefer touch record (advances a channel) + lead outcome (the verdict) |
autark run finish --run-id <id> --narrative @./run.md | Finish a run with a narrative |
autark context <slug>[/<H##>] | Product or hypothesis context: brief, feedback, hypotheses, leads, runs |
| `autark feedback record\ | delete` |
Use @./file for multi-line markdown or JSON values instead of inlining large strings.
Two Separate Jobs: Filling the Sheet, Draining the Sheet
Sourcing fills the sheet: find people, enrich them, write angles, record leads. A sourcing run sends nothing — no emails, no DMs, no posts, no comments.
A lead payload needs, at minimum, enough identity to dedupe (primary_email, a handle, or full_name) and a lead.angle that answers: why does this human belong under this bet? bio and signals are enrichment, not ceremony. If you cannot write a concrete angle, skip the person — one real prospect beats five padded rows.
`email_status` decides the email channel — set it honestly. The email channel reaches ready (mailable now) automatically when the person has an address with email_status: verified or sourced (a real first-party address from a commit, site, or published page). A guessed / unknown / none address is NOT sendable and creates no email:ready — found the person but not a real address yet is honest, not a failure. So your sourcing job is simply: set person.email_status truthfully, and email:ready falls out of it. (A LinkedIn handle on the person likewise seeds linkedin:reachable automatically.) The legacy lead.status payload field still works but you no longer need to micromanage it.
Promote with `enrich`, never re-add. When you later find the email (or a handle) for a lead already on the sheet, update it in place: autark lead enrich --lead-id <id> --input @enrich.json carrying the new person.primary_email + person.email_status: verified (the email channel flips to ready on its own). Do NOT run lead add again for someone you already sourced — person identity is keyed on one field (email > handle > name), so adding an email changes the key and a re-add creates a duplicate row instead of updating. enrich keeps the same row id. If a duplicate ever slips through, autark lead delete <id> removes it (zero-touch leads only; it refuses anything with outreach history).
Outreach drains the sheet, and only when the operator explicitly asks for it. Start from the sheet, not the context dump, and scope it to the work in front of you:
autark lead list <slug>/<H##> --channel email --stage ready— emails waiting to go out on this betautark lead list <slug> --needs-reply— conversations where the ball is in our court (any channel)autark lead list <slug> --channel linkedin --stage reachable— people to send a LinkedIn invite toautark lead list <slug> --channel linkedin --stage accepted— connections accepted, ready for a first messageautark lead list <slug> --silent-for 7— contacted, no reply, gone quiet 7+ days (follow-up candidates)
Each row carries the lead id, the company, and every channel's stage. Drill into one with autark lead show <id>, read the email conversation with autark mail thread <thread_ref>, then act against the explicit lead id:
autark mail send --lead-id "$LEAD_ID" --to person@example.com \
--subject "..." --text @draft.txtOne command does three things atomically: sends the email, records a touch (channel email, direction out, thread_ref = the AgentMail thread), and advances the lead ready → contacted. The send is the bookkeeping — never follow up with a separate status or logging command for the same send.
Following up when they have NOT replied yet: reply to your own latest message with an explicit `--to` — a plain reply addresses the sender of the target message, which is you, and the follow-up self-sends into your own inbox:
autark mail reply --lead-id "$LEAD_ID" --message-id <your-last-msg-id> \
--to person@example.com --text @followup.txtWhen answering THEIR message, plain mail reply --lead-id --message-id <their-msg-id> is correct — the sender you're addressing is them.
Non-email channels — do the action in the tool, then record the touch. Email is the only channel the CLI sends; everywhere else you act first (in chrome-relay for LinkedIn, on the site for a GitHub/Reddit comment) and record the touch after, so autark mirrors what you did. The touch write advances that channel's stage:
# LinkedIn, worked through chrome-relay, recorded step by step:
autark touch record --lead-id "$LEAD_ID" --channel linkedin --event invite --ref <invite-url>
autark touch record --lead-id "$LEAD_ID" --channel linkedin --event accept # they accepted
autark touch record --lead-id "$LEAD_ID" --channel linkedin --event message --ref <thread-url> --summary "first message"
autark touch record --lead-id "$LEAD_ID" --channel linkedin --event message --direction in # they replied
# a GitHub comment:
autark touch record --lead-id "$LEAD_ID" --channel github --ref <permalink-to-YOUR-comment>Record each LinkedIn step as you actually take it — invite, then accept when they connect, then message — so the reachable → invited → accepted → contacted → replied ladder reflects reality and lead list --channel linkedin --stage accepted surfaces exactly who's ready for a first message.
Email replies are captured automatically: a worker sweep polls the threads of contacted AND replied email leads twice a day, records each real inbound message as a direction: in touch, and flips the email channel to replied — no agent involvement. (LinkedIn has no such poll — you record inbound LinkedIn replies yourself with --event message --direction in when you see them.) The touch log keeps appending, so a lead's full history stays queryable via autark lead show <id>. If an email "reply" is a ticket bot or autoresponder, judge it with autark touch mute <touch-id>: that channel drops back to contacted and the sweep honors it permanently. A real human opt-out ("remove me from your list") is not a mute — it ends the pursuit: autark lead outcome <id> --set dead.
Run Workflow
1. Read the product brief and feedback via autark context <slug>. 2. Pick or create a hypothesis; resolve its id. 3. Start a run. 4. Source and enrich a cohort (≈8–15 people), recording each as you go. 5. Finish with a narrative: where you looked, what patterns you saw, where the next pass should go.
autark context <slug>
HYPOTHESIS_ID=$(autark hypothesis create --product-id <product_id> --code H## --md @./hyp.md)
RUN_ID=$(autark run start --hypothesis-id "$HYPOTHESIS_ID")
autark lead template > /tmp/lead-template.json # inspect the shape once
# for each good prospect: write /tmp/lead-N.json, then
autark lead add --hypothesis-id "$HYPOTHESIS_ID" --run-id "$RUN_ID" --input @/tmp/lead-1.json
autark run finish --run-id "$RUN_ID" --narrative @./run.mdHypotheses
A hypothesis has two short paragraphs:
- Story: why this product matters to this cohort.
- Who: the narrow audience, where to source them, and why they are identifiable.
If either paragraph is broad or vague, the hypothesis is not ready to run. Autark should test many small, sharp hypotheses rather than one fuzzy thesis.
Create a new hypothesis when the bet changes. Mark bad bets dead instead of deleting them:
autark hypothesis status <slug>/H07 --status deadGuardrails
- Quality gates inclusion. Skip anyone whose angle you cannot write concretely.
- Keep hypotheses immutable after creation.
- Prefer first-party emails (commit email, personal-site mailto, published address); mark
email_statushonestly (verified/guessed/none). - During sourcing, never send or message anything — just record people. Outreach happens only when the operator asks, and always against an explicit
--lead-id. - Do not blast. Ten well-researched touches beat hundreds of generic sends.
- Channel stage moves with touches, not by hand — record what you actually did and the stage follows.
outcome(landed/dead) is the one human verdict you set explicitly; never mirror a send you just made — the send already recorded it. - Keep narratives public-safe: what happened, why it mattered, and what should happen next. On public products, hypothesis text, run narratives, and lead angles are readable by anyone — never put an email address in any of them. Emails belong on the person record (owner-only) and nowhere else.
- Post stuck states to Plumcake instead of holding them in your head.
Reference
| Thing | Location |
|---|---|
| Dashboard | https://autark.sh |
| API | https://autark-api.kushalsokke.workers.dev |
| CLI | npm i -g autark-cli or node /path/to/autark/cli/autark.mjs |
| Credentials | ~/.autark/credentials.json |
Staying current
If any autark command prints [autark] update available on stderr, run autark update before continuing:
autark updateThe update is idempotent — running it when you are already current is a no-op, and many odd CLI problems are solved by simply being on the latest version.
Autark Skill
Agent skill for Autark, a permissionless market-discovery loop. The agent forms hypotheses, runs outreach, and records actions through the autark CLI.
Install
npx skills add kiluazen/kstack@autarkThe skill teaches agents how to use the autark CLI. Install the CLI separately:
npm i -g autark
autark login send <your-email>
# check inbox, then:
autark login verify <your-email> --code <6-digit-code>What this skill teaches
- Data model: products -> hypotheses -> runs -> actions
autarkCLI commands for products, hypotheses, runs, and actions- Permissionless operating contract
- Plumcake escalation when blocked
- Public-safe run narratives and follow-up discipline