Rishikesh Ranjan — rishikeshranjan.com

// utility

State

/ttm-state

Display current campaign states, decisions in flight, blockers, and experiments. Use to get an overview of all active marketing work.

manual invocation
allowed-tools:ReadBashGlob

Overview

The ttm-state skill is the read-only dashboard for takeToMarket. It displays the current state of every campaign — phase, decisions in flight, blockers, shipped-asset counts, experiments, and last activity — so you can get an overview of all active marketing work without mutating anything.

Invoke it with the ttm-state command. With no argument it prints every campaign (active and archived) in a summary table with per-campaign detail sections. Pass a campaign slug to see the per-campaign detail view drawn from that campaign's STATE.md.

Why it matters: state is the truth file in takeToMarket — not your memory, not the conversation history. Use ttm-state before running any campaign action when you are not sure where you left off. The skill never modifies files.

How it works

The workflow (workflows/utility/state.md) is a read-only dashboard. No-argument mode shows the full campaign dashboard; a slug argument shows the single-campaign detail view. It reads from the campaign tooling list and enriches the output with per-campaign STATE.md data.

Step 0: First-run inline education

Read .taketomarket/CONFIG.md. Parse first_run_seen (object) and inline_education (boolean, default true).

If inline_education is false: skip this step. Else if first_run_seen.ttm-state is not true, print the explainer below verbatim, then mark this skill as seen:

node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run mark ttm-state

Use this exact check (bash) to decide whether to print: node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run check ttm-state --raw — the JSON seen field is true once the explainer has run before.

Explainer for /ttm-state

/ttm-state is the read-only dashboard. With no argument it prints every campaign (active and archived) with its current phase, blockers, shipped-asset count, and last activity timestamp. With a slug, it prints the per-campaign detail view from that campaign's STATE.md.

Why it matters: state is the truth file in takeToMarket — not your memory, not the conversation history. This skill is how you check that truth without mutating it. Use it before running any campaign action when you're not sure where you left off.

(Canonical source: references/inline-education-blurbs.md. Embedded verbatim because workflows do not @-resolve files at runtime.)

Required reading: ${CLAUDE_PLUGIN_ROOT}/references/context-loading.md.

Step 1: Load Context

takeToMarket > LOADING CONTEXT

Extract SLUG from $ARGUMENTS (strip the --text flag if present):

SLUG=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)

SLUG is optional for this command. If empty, display the full dashboard (Step 3). If present, display the single campaign detail (Step 4).

Step 2: Gather Campaign Data

takeToMarket > GATHERING CAMPAIGN DATA

Get all campaigns:

CAMPAIGNS_JSON=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign list --raw)

Parse the JSON output to get all campaigns with their frontmatter fields (slug, phase, name, last_updated, etc.).

If SLUG is provided, also get detailed state:

DETAIL_JSON=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state "${SLUG}" --raw)

If exists: false in the detail response: "Campaign '${SLUG}' not found. Run /ttm-state without arguments to see all campaigns." Then exit.

Check for archived campaigns:

ls .taketomarket/CAMPAIGNS/ARCHIVE/ 2>/dev/null

For each archived directory found, read its STATE.md frontmatter to get the archive date and outcome information.

Read global state for portfolio context: Read .taketomarket/STATE.md body content (below the frontmatter) for portfolio-level decisions, blockers, and experiments.

Step 3: Display Dashboard (Full Mode — No SLUG)

takeToMarket > CAMPAIGN DASHBOARD

Display a summary table with ALL campaigns organized by status.

Output Format

## Campaign Dashboard

### Active Campaigns

| Campaign | Phase | Last Updated | Status |
|----------|-------|--------------|--------|
| <slug>   | <phase> | <relative time> | <brief status> |

For each active campaign, also display a detail section:

### <slug> Detail
**Phase:** <phase>
**Created:** <date> | **Last Updated:** <date>
**Gate Results:** <summary of pass/fail counts from review.overall_result>
**Fix Attempts:** <fix.run_count or 0>
**Decisions in flight:** <from global .taketomarket/STATE.md body if any>
**Blockers:** <from global .taketomarket/STATE.md body if any>
**Experiments:** <from global .taketomarket/STATE.md body if any>

If no active campaigns exist, display: "No active campaigns. Run /ttm-new-campaign <slug> to start one."

Archived Campaigns

If archived campaigns exist, display them in a collapsed section:

### Archived Campaigns

| Campaign | Archived Date | Outcome |
|----------|--------------|---------|
| <slug>   | <date>       | <shipped/cancelled> |

If no archived campaigns exist, omit this section entirely.

Portfolio Summary

At the end, display a brief portfolio summary:

---
**Portfolio:** <N> active, <M> archived
**Next recommended action:** Run `/ttm-next` for prioritized guidance

Step 4: Display Single Campaign (SLUG Provided)

takeToMarket > CAMPAIGN DETAIL: ${SLUG}

Show full detail for the single campaign. Read the full campaign STATE.md file (not just frontmatter — per Pitfall 5) to get all body content.

Output Format

## Campaign: ${SLUG}

### Overview
**Name:** <name>
**Phase:** <phase>
**Created:** <created date>
**Last Updated:** <last_updated date>

### Lifecycle Progress
<Visual phase indicator showing completed and current phases>
created -> researched -> briefed -> produced -> verified -> reviewed -> shipped

### State Details
**Review Result:** <review.overall_result or "not yet reviewed">
**Fix Attempts:** <fix.run_count or 0>
**Fix Result:** <fix.overall_result or "N/A">
**Ship Status:** <ship.status or "not shipped">

### Gate Results
<Table of all gate/check results if available>

| Gate | Result | Date |
|------|--------|------|
| verification | <pass/fail> | <date> |
| review | <approved/revise> | <date> |

### Campaign Notes
<Full body content from the campaign's STATE.md file>

### Suggested Next Action
Based on current phase, suggest the next /ttm-* command:
- "Run `/ttm-<next-command> ${SLUG}` to continue."

If the campaign has no body content in STATE.md, display: "No additional notes recorded for this campaign."

Success criteria

  • Campaign data retrieved via CLI (campaign list --raw)
  • Dashboard displays active campaigns with detail sections
  • Archived campaigns shown as collapsed rows
  • Single campaign mode shows full detail when slug provided
  • Global .taketomarket/STATE.md body read for portfolio-level context
  • No files modified (read-only command)

Output

No files modified (read-only command).

What if this doesn't fit?

Looks like /ttm-state can't do that yet.

  • Want a new skill? /ttm-request-skill
  • Existing skill needs work? /ttm-improve-skill

This skill is backed by the script ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs, which provides the campaign list, campaign state, and first-run subcommands the workflow invokes.