Organisation-neutral Claude Code skills for strategy, service definition, marketing, and pricing. Question-led, evidence-tagged, configurable per project.
Published by base2Services as base2Services/strategy-skills. Current version 1.3.0 — see the Changelog for what changed in each release.
Question-led method skills for working strategy across the stages of a services or product business, packaged as a Claude Code plugin and mirrored into .claude/skills/ so they also work in Cowork.
The skills carry no organisation's name, folders, brand or facts. All of that lives in a per-project config (.strategy-skills/config.json) written by the setup skill at first launch. That is what makes the plugin shareable: install it anywhere, run setup, and it adapts to that project.
| Skill | Purpose | Invoke (plugin) | Invoke (Cowork / auto) |
|---|---|---|---|
| setup | Initialise (or edit) the project config | /strategy-skills:setup |
/setup |
| north-star | Set the guiding goal everything aligns to | /strategy-skills:north-star |
/north-star |
| brainstorm | Open the option space, then converge to a shortlist | /strategy-skills:brainstorm |
/brainstorm |
| pain-point | Ground options in evidenced customer pain | /strategy-skills:pain-point |
/pain-point |
| wwwh | Structure a conclusion through the full 5W1H | /strategy-skills:wwwh |
/wwwh |
| tasks | Workflow register that runs the right skill per item, and routes review / input / validation / approval requests between people | /strategy-skills:tasks |
/tasks |
| diagram | Ongoing view of the strategy: a journey map (path to the north-star, milestones, critical path) and a coverage map (gaps), drawn from what is actually on disk | /strategy-skills:diagram |
/diagram |
More skills for marketing, pricing, and service definition are planned.
They chain: north-star → brainstorm → pain-point → wwwh, and each runs standalone. Run setup once before any of the others — they refuse to run without a config. diagram is cross-cutting: it reads every other skill's output and the tasks register to draw the maps, and is regenerated as those change (see "The diagram skill" below).
/strategy-skills:setup (or just: "set up strategy skills")
Setup asks for the organisation name, the products, where documents should live, the brand colour, the voice rules and the work stages, then writes .strategy-skills/config.json and creates the output folders. Re-run it any time to change a value.
.strategy-skills/config.json is the single source of truth every skill reads. The schema (with a description per key) ships at plugins/strategy-skills/reference/config.schema.json and is copied into the project as .strategy-skills/config.schema.json. Key sections:
organisation— name, short name, products, target market, buyer voices.paths—pluginRoot(for Cowork),research, andoutputs.<skill>folders.brand— palette injected into the HTML renderer (onlyprimaryis required).voiceRules— em-dash, Oxford comma and concision preferences.stages[]— the work stages a session can be scoped to, each with its research map.groundTruth[]— settled facts every session must respect (empty by default).
Every session is scoped to one stage from the config. The default stage model is:
- Define the services
- Service contents
- Business implementation
- Marketing direction
Setup lets you keep, rename, reorder or replace these.
WWWH structures a conclusion through the full Who / Why / What / When / Where / How (the classic 5W1H), with Who and Why carried from the locked pain-point. This is deliberately different from the 4W+H used by the separate business-definition-consultant skill. The two are not mixed.
The tasks skill is the team's control center. It does three things: keeps one register of work, runs the right strategy skill per item, and — this is the co-working part — routes requests between people. You operate all of it by talking to Claude in the project; some teammates need never touch GitHub or the CLI.
The register lives in the configured tasks/ folder as register.json (the source of truth), with people.json for names. The helper is python "${PLUGIN_ROOT}/scripts/tasks.py".
Because the register is shared, the skill has to know who is operating this checkout before it records a request against them — the requester is part of the permanent record and is never guessed. Your own identity is therefore stored locally, not in the shared register:
tasks.py whoami # who am I in this project?
tasks.py whoami --set arthur # set it once (a people.json key)It is saved per-user, outside the project, in ~/.claude/strategy-skills/identity.json (keyed by project; honours CLAUDE_CONFIG_DIR), or read from the STRATEGY_TASKS_ME env var. The home location is deliberate: a project shared by Dropbox or OneDrive syncs the whole folder and ignores .gitignore, so a file inside the project would carry one person's identity to the whole team. Keeping it in the home dir works whether the project is shared by git or by a folder-sync tool. With it set, request defaults --by to you and mine / inbox / awaiting default to you. If it is not set and not evident, the skill asks you rather than assuming. Each teammate sets it once on their own machine.
You ask a colleague by raising a request. Each kind matches a real ask:
| Kind | Use it when | --target is |
|---|---|---|
review-document |
someone should read and give feedback on a document | the document path |
review-session |
someone should review the outcome of a session | the session reference |
review-decision |
someone should review a decision before it stands | the decision |
input |
you are missing information a colleague holds | the question |
validate |
you want a colleague to validate your thinking | the reasoning |
approve |
a decision needs sign-off (a hard gate) | the decision |
A plain to-do (no one else involved) is just kind: task, the default.
# Ask Sarah for cost figures you are missing, and park the brainstorm it feeds.
# --by defaults to you (set once with `whoami --set`), so you rarely pass it:
tasks.py request --kind input --to sarah \
--target "AWS cost figures for the managed service" --due 2026-06-19 --feeds T-002
# What has been asked of me / what am I waiting on:
tasks.py inbox sarah # requests awaiting Sarah's response
tasks.py awaiting arthur # requests Arthur raised that are still pending
# Sarah answers; the parked item T-002 unblocks automatically:
tasks.py respond T-003 --outcome answered --response "On-demand ~$4.2k/mo; 1yr RI ~$2.7k/mo (AWS calc)."The returned fact is carried into the strategy artefact attributed and tagged — … [User-asserted: Sarah] — so a reader sees it was her assertion, not an assumption.
The headline pattern: during a brainstorm, you hit a claim you cannot evidence, or a direction you want a second pair of eyes on. The brainstorm raises an input or validate request, parks that thread as blocked, and you keep going on the rest. When the colleague responds, the thread unblocks and their answer folds into the Understanding and Evidence ledger, tagged to them. Nothing is lost and no claim slips through unproven.
An approve request is enforced, not advisory. A decision that needs sign-off cannot be locked as Trusted or carried into a downstream skill while its approval is outstanding:
tasks.py list --kind approve --target "wwwh pricing decision" --pending # anything here = gate closed
tasks.py respond T-004 --outcome approved --response "Signed off." # gate openschanges-requested and rejected do not open the gate.
In-project reminders only reach people who are in the project. A pending request carries everything an external production rules engine needs to chase someone who is not — who was asked, by whom, for what, by when — by reading register.json. GitHub Issues (gh-create, remind --post) is an optional extra for whoever is on GitHub. Neither is required.
tasks.py render writes a human register.md (with a Requests section showing who is asking whom for what) plus a brand-styled register.html.
The diagram skill draws the whole strategy as two maps in one run, from the artefacts that actually exist, so the picture is never asserted:
- Journey map — the path to the North Star. The
brainstorm → pain-point → wwwhsequence that serves the goal, the milestones along the way (derived from the method's own lock and approval gates: north-star set, brainstorm locked, pain locked per product, WWWH structured per stage, every open sign-off), and the critical path: the ordered set of milestones not yet reached, each annotated with what is blocking it, plus the longest blocking task chain walked from the register'sfeeds/blocked_onlinks. This answers where are we, and what is left to clear. - Coverage map — the services × stages matrix plus a pain + proof row, and a gap report of everything the config expects that is not yet on disk. This answers what is missing.
The scanner is scripts/build-diagram.py. It is deterministic and never guesses: a node, cell or milestone is filled only when a real file (or register item) maps to it by a literal match of a configured product, stage, voice, evidence tag or the lock-status line (locked / pending-locked / draft). Anything expected but absent is a dashed GAP; a file it cannot place is reported unclassified so the skill asks you rather than inventing a placement. Run it from a project that has a config:
python plugins/strategy-skills/scripts/build-diagram.pyIt writes YYYY-MM-DD-journey-map.svg, YYYY-MM-DD-coverage-map.svg, a coverage.json audit trail, and YYYY-MM-DD-strategy-map.md (which embeds both SVGs) — render that to brand HTML with generate-html.py. Output goes to paths.outputs.diagram, or a diagram/ folder beside the other outputs if that key is absent.
The maps are a mirror of the artefacts and the register, so they go stale the moment one changes. Two mechanisms keep them live:
-
At every skill's close-out (automatic, portable). Each strategy skill regenerates the maps as its final step (the shared backbone's Output protocol; the tasks skill does it after a status change). So after running the skills the maps are already fresh. This works everywhere, including Cowork.
-
A
PostToolUsehook (optional, opt-in). To regenerate automatically the moment a task completes, a brainstorm lands, or a document moves to locked or pending-locked, add a hook to the consuming project's.claude/settings.json. It is opt-in because it editssettings.jsonand hooks do not fire in Cowork. The build script self-locates its config and is safe to run any time, so the hook is a one-liner:{ "hooks": { "PostToolUse": [ { "matcher": "Write|Edit|Bash", "hooks": [ { "type": "command", "command": "python \"$CLAUDE_PROJECT_DIR/<pluginRoot>/scripts/build-diagram.py\" >/dev/null 2>&1 || true" } ] } ] } }Replace
<pluginRoot>withpaths.pluginRootfrom the project's config (or an absolute path to the installed plugin). The|| truekeeps the hook from ever blocking a tool call. It regenerates the SVGs and the report markdown on every relevant edit; re-render the HTML at the next skill close-out, or add a second hook line forgenerate-html.pyif you want the HTML refreshed too.
The states that move a milestone (and so the critical path) — a register status of done, a new file in the brainstorming folder, Lock status: Locked / Trusted, Lock status: Locked-pending — are all read straight from disk, so either mechanism keeps the view honest.
strategy-skills/
├── .claude-plugin/marketplace.json marketplace manifest
├── plugins/strategy-skills/ the plugin (SOURCE OF TRUTH)
│ ├── .claude-plugin/plugin.json plugin: "strategy-skills"
│ ├── skills/
│ │ ├── setup/SKILL.md writes .strategy-skills/config.json
│ │ ├── north-star/SKILL.md
│ │ ├── brainstorm/SKILL.md
│ │ ├── pain-point/SKILL.md
│ │ ├── wwwh/SKILL.md
│ │ ├── tasks/SKILL.md
│ │ └── diagram/SKILL.md journey + coverage maps from what is on disk
│ ├── scripts/
│ │ ├── generate-html.py Word-style HTML renderer (reads config for brand/org/author)
│ │ ├── html-template.html
│ │ ├── tasks.py tasks register helper (reads config for the data folder + org)
│ │ └── build-diagram.py deterministic scanner + journey/coverage SVG generator
│ └── reference/
│ ├── shared.md common backbone, read first by every skill
│ └── config.schema.json the config schema (copied into projects by setup)
├── sync_skills.py mirrors skills into .claude/skills/
└── README.md
- Cowork (and any cloud session): loads skills from
.claude/skills/automatically. The synced copies are what Cowork uses; no install step. Because${CLAUDE_PLUGIN_ROOT}is not set there, skills resolve the renderer and backbone viapaths.pluginRootin the config. - Desktop Claude Code: loads
.claude/skills/automatically too, so the synced copies work out of the box. You can additionally install the packaged plugin for the namespaced/strategy-skills:*commands, where${CLAUDE_PLUGIN_ROOT}resolves the plugin assets.
The plugin in plugins/strategy-skills/ is the source of truth. The .claude/skills/ copies are generated by sync_skills.py.
-
Edit the source under
plugins/strategy-skills/skills/<name>/SKILL.md. -
Run the sync so a consuming project (Cowork and auto-discovery) picks up the change. It mirrors into
<target>/.claude/skills/, where target is--target, then$CLAUDE_PROJECT_DIR, then the current directory:python sync_skills.py --target /path/to/your/project
-
Commit the plugin source here. In the consuming project, commit its regenerated
.claude/skills/copies.
Do not edit the .claude/skills/ copies directly. They are overwritten on every sync.
In Claude Code, point marketplace add at this repo (the folder holding .claude-plugin/marketplace.json), then install:
/plugin marketplace add https://github.com/base2Services/strategy-skills
/plugin install strategy-skills@base2services
base2services is the marketplace name in .claude-plugin/marketplace.json. Installing gives the namespaced /strategy-skills:* commands and sets ${CLAUDE_PLUGIN_ROOT} so the renderer and backbone resolve automatically.
- Install the plugin (above), or vendor this repo into the project (copy, git submodule, etc).
- Run
/strategy-skills:setupin the project to write its.strategy-skills/config.json. - If the plugin is vendored rather than installed (e.g. for Cowork, where
${CLAUDE_PLUGIN_ROOT}is not set), setpaths.pluginRootto where it lives and runsync_skills.py --target <project>. Setup detects and confirms this.
No skill text changes. Each project gets its own name, folders, brand and facts entirely through its config.
Keep operator identity out of the shared folder. Each person's identity lives in their home dir (
~/.claude/strategy-skills/identity.json), never in the project, so the tasks skill never writes it into shared files. Keep the.gitignorelinesetupadds (.strategy-skills/identity.local.json): it guards against someone hand-creating a project-local identity file and committing it. The helper also warns whenever it finds such a file, because a folder-sync tool (Dropbox/OneDrive) would carry it to the whole team regardless of.gitignore. If you see that warning, runtasks.py whoami --set <key>and delete the project copy.
The HTML renderer needs markdown-it-py:
pip install markdown-it-pyEvery release is recorded in CHANGELOG.md, written for the people who use the skills: what changed and what you can now do, newest first. The plugin follows semantic versioning, so a minor bump (e.g. 1.2 → 1.3) only adds things and a project on an older version keeps working until you update it. When you update the plugin, skim the changelog to see what is new.
Apache-2.0. See LICENSE and NOTICE. Copyright 2026 base2Services.