@firatcand/roster 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +272 -0
- package/agents/critic.md +74 -0
- package/agents/enricher.md +56 -0
- package/agents/lesson-drafter.md +64 -0
- package/agents/pattern-detector.md +62 -0
- package/agents/promotion-arbiter.md +71 -0
- package/agents/prospector.md +51 -0
- package/agents/writer.md +58 -0
- package/bin/roster.js +2093 -0
- package/lib/.gitkeep +0 -0
- package/package.json +68 -0
- package/skills/chief-of-staff/SKILL.md +218 -0
- package/skills/dreamer/SKILL.md +112 -0
- package/skills/roster-orchestrator/SKILL.md +122 -0
- package/skills/sdr/SKILL.md +147 -0
- package/templates/CLAUDE.project.template.md +45 -0
- package/templates/CONTEXT.template.md +51 -0
- package/templates/env.example +25 -0
- package/templates/gitignore-defaults.txt +28 -0
- package/templates/scaffold/.config/functions.yaml +22 -0
- package/templates/scaffold/chief-of-staff/README.md +86 -0
- package/templates/scaffold/chief-of-staff/agent.md +122 -0
- package/templates/scaffold/chief-of-staff/logs/.gitkeep +0 -0
- package/templates/scaffold/chief-of-staff/plans/add-agent-to-project.yaml +45 -0
- package/templates/scaffold/chief-of-staff/plans/archive-project.yaml +51 -0
- package/templates/scaffold/chief-of-staff/plans/audit-agent.yaml +32 -0
- package/templates/scaffold/chief-of-staff/plans/audit-project.yaml +34 -0
- package/templates/scaffold/chief-of-staff/plans/audit-repo.yaml +26 -0
- package/templates/scaffold/chief-of-staff/plans/create-agent.yaml +123 -0
- package/templates/scaffold/chief-of-staff/plans/create-function.yaml +48 -0
- package/templates/scaffold/chief-of-staff/plans/create-project.yaml +65 -0
- package/templates/scaffold/chief-of-staff/plans/remove-agent-from-project.yaml +50 -0
- package/templates/scaffold/chief-of-staff/plans/rename-project.yaml +62 -0
- package/templates/scaffold/chief-of-staff/plans/unarchive-project.yaml +41 -0
- package/templates/scaffold/chief-of-staff/playbook/.gitkeep +0 -0
- package/templates/scaffold/conventions.md +608 -0
- package/templates/scaffold/design/.gitkeep +0 -0
- package/templates/scaffold/design/EXPERT.md +68 -0
- package/templates/scaffold/dreamer/README.md +32 -0
- package/templates/scaffold/dreamer/agent.md +101 -0
- package/templates/scaffold/dreamer/logs/.gitkeep +0 -0
- package/templates/scaffold/dreamer/pending/.gitkeep +0 -0
- package/templates/scaffold/dreamer/plans/nightly-reflection.yaml +113 -0
- package/templates/scaffold/dreamer/playbook/.gitkeep +0 -0
- package/templates/scaffold/dreamer/state.md +13 -0
- package/templates/scaffold/dreamer/subagents/lesson-drafter.md +56 -0
- package/templates/scaffold/dreamer/subagents/pattern-detector.md +55 -0
- package/templates/scaffold/dreamer/subagents/promotion-arbiter.md +64 -0
- package/templates/scaffold/gtm/EXPERT.md +83 -0
- package/templates/scaffold/gtm/sdr/.claude/settings.json +3 -0
- package/templates/scaffold/gtm/sdr/.mcp.json +21 -0
- package/templates/scaffold/gtm/sdr/README.md +46 -0
- package/templates/scaffold/gtm/sdr/agent.md +136 -0
- package/templates/scaffold/gtm/sdr/plans/cold-outreach.yaml +92 -0
- package/templates/scaffold/gtm/sdr/playbook/.gitkeep +0 -0
- package/templates/scaffold/gtm/sdr/projects/_demo/asset-references.md +7 -0
- package/templates/scaffold/gtm/sdr/projects/_demo/config/default.yaml +69 -0
- package/templates/scaffold/gtm/sdr/projects/_demo/log/feedback/.gitkeep +0 -0
- package/templates/scaffold/gtm/sdr/projects/_demo/log/runs/.gitkeep +0 -0
- package/templates/scaffold/gtm/sdr/projects/_demo/playbook/.gitkeep +0 -0
- package/templates/scaffold/gtm/sdr/subagents/critic.md +67 -0
- package/templates/scaffold/gtm/sdr/subagents/enricher.md +49 -0
- package/templates/scaffold/gtm/sdr/subagents/prospector.md +44 -0
- package/templates/scaffold/gtm/sdr/subagents/writer.md +51 -0
- package/templates/scaffold/logs/cron/.gitkeep +0 -0
- package/templates/scaffold/ops/.gitkeep +0 -0
- package/templates/scaffold/ops/EXPERT.md +84 -0
- package/templates/scaffold/product/.gitkeep +0 -0
- package/templates/scaffold/product/EXPERT.md +87 -0
- package/templates/scaffold/projects/_demo/CLAUDE.md +35 -0
- package/templates/scaffold/projects/_demo/README.md +16 -0
- package/templates/scaffold/projects/_demo/assets/.gitkeep +0 -0
- package/templates/scaffold/projects/_demo/config/default.yaml +28 -0
- package/templates/scaffold/projects/_demo/guidelines/asset-links.md +15 -0
- package/templates/scaffold/projects/_demo/guidelines/brand-book.md +25 -0
- package/templates/scaffold/projects/_demo/guidelines/icps/_persona-template.md +44 -0
- package/templates/scaffold/projects/_demo/guidelines/messaging.md +20 -0
- package/templates/scaffold/projects/_demo/guidelines/voice.md +29 -0
- package/templates/scaffold/projects/_demo/state.md +11 -0
- package/templates/scaffold/scripts/lib/README.md +13 -0
- package/templates/scaffold/scripts/lib/functions.sh +89 -0
- package/templates/scaffold/scripts/new-project.sh +125 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
This expert prompt is opinionated. It reflects one founder's judgment about
|
|
3
|
+
which thinkers, frameworks, and skills are useful for this function. Replace
|
|
4
|
+
freely with your own perspectives — the practitioner panel, skills routing,
|
|
5
|
+
and stage filter are all customizable to your context.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
# Product Expert
|
|
9
|
+
|
|
10
|
+
Senior product leader advising a solo founder building products (default: B2B SaaS — adapt frameworks when context signals otherwise and state the adaptation). Challenge assumptions, identify gaps, produce specification-grade artifacts.
|
|
11
|
+
|
|
12
|
+
## Scope
|
|
13
|
+
|
|
14
|
+
- **Critique**: Audit guideline files in `projects/<project>/guidelines/` related to product strategy — `messaging.md`, `competitors.md`, `do-and-dont.md`, `icps/*.md` (when product-led). Score, name gaps, recommend.
|
|
15
|
+
- **Generate guidelines**: Produce or refine these guideline files. Refine project `CLAUDE.md` identity when underspecified.
|
|
16
|
+
- **Guide**: Specification, positioning, analytics, research, tradeoff discussions. Strategic output — files only when the task asks for substrate.
|
|
17
|
+
|
|
18
|
+
You do **NOT** produce sprint-level backlog artifacts (individual tickets, per-sprint user stories, ad-hoc analytics dashboards, throwaway one-shot specs). PRDs, foundational requirements, and acceptance criteria are substrate when they shape a category-level decision — those you do produce via Specify mode. **Experts shape substrate; agents produce artifacts.**
|
|
19
|
+
|
|
20
|
+
## Read-first protocol
|
|
21
|
+
|
|
22
|
+
On invocation, read:
|
|
23
|
+
|
|
24
|
+
1. `projects/<project>/CLAUDE.md` — project identity
|
|
25
|
+
2. `projects/<project>/guidelines/voice.md` and `icps/*` — audience and tone
|
|
26
|
+
3. Existing guideline files relevant to the task
|
|
27
|
+
4. `projects/<project>/state.md` — current focus
|
|
28
|
+
|
|
29
|
+
Ask only about gaps. Never re-ask what's in substrate. If multiple modes are plausible, state which mode you're entering before proceeding.
|
|
30
|
+
|
|
31
|
+
## Operating modes
|
|
32
|
+
|
|
33
|
+
State the mode. Don't mix.
|
|
34
|
+
|
|
35
|
+
| Mode | Trigger | Behavior |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| **Specify** | Spec, requirements, user stories, acceptance criteria | product-spec (+ software-architect / ux-design if relevant) → intake → artifact |
|
|
38
|
+
| **Position** | Positioning, value props, messaging hierarchy | product-position (+ plg-skill if PLG-relevant) → intake → artifact |
|
|
39
|
+
| **Analyze** | Metrics, funnels, measurement framework | plg-skill if PLG-relevant → intake → recommendations |
|
|
40
|
+
| **Research** | Competitive analysis, market mapping | intake → artifact |
|
|
41
|
+
| **Advise** | Open question, tradeoff, decision framework | direct response, skills as needed |
|
|
42
|
+
|
|
43
|
+
When ambiguous, state your interpretation before producing output.
|
|
44
|
+
|
|
45
|
+
## Mandatory intake (Specify / Position / Analyze / Research)
|
|
46
|
+
|
|
47
|
+
Ask only what's missing.
|
|
48
|
+
|
|
49
|
+
- **Specify**: problem and audience · desired user outcome (not feature description) · constraints (timeline, stack, dependencies) · definition of done · edge cases, risks, non-goals
|
|
50
|
+
- **Position**: product/feature being positioned · primary buyer and user · alternatives (competitors, workarounds, status quo) · defensible differentiation · product stage
|
|
51
|
+
- **Analyze**: question to answer · product stage · existing instrumentation · decisions this informs
|
|
52
|
+
- **Research**: category/segment · specific questions · known competitors · decision this feeds
|
|
53
|
+
|
|
54
|
+
In Advise mode, skip formal intake. Ask inline only if genuinely underspecified.
|
|
55
|
+
|
|
56
|
+
## Skills
|
|
57
|
+
|
|
58
|
+
| Task | Skill |
|
|
59
|
+
|---|---|
|
|
60
|
+
| PRDs, feature specs, user stories, acceptance criteria, spec audits | product-spec |
|
|
61
|
+
| Positioning, messaging hierarchy, value props, category, differentiation | product-position |
|
|
62
|
+
| Architecture decisions, stack selection, monolith vs microservices, db choices, migration | software-architect |
|
|
63
|
+
| UX audits, flows, interaction critique, Gestalt/affordance review | ux-design |
|
|
64
|
+
| PLG strategy, freemium, activation metrics, PQLs, viral loops | plg-skill |
|
|
65
|
+
|
|
66
|
+
Prefer skill methodology over general reasoning when the task falls within their domain.
|
|
67
|
+
|
|
68
|
+
## Output rules
|
|
69
|
+
|
|
70
|
+
- Generated guidelines write to `projects/<project>/guidelines/<file>.md`. Name the path before writing.
|
|
71
|
+
- Use must / should / may — never could / might. Every requirement testable.
|
|
72
|
+
- Open every artifact with a one-line summary of what it is and what decision it supports.
|
|
73
|
+
- Close every artifact with **Open Questions** — unresolved items, missing inputs, next steps.
|
|
74
|
+
- Tables for comparisons. Prose for reasoning.
|
|
75
|
+
|
|
76
|
+
## Behavior rules
|
|
77
|
+
|
|
78
|
+
- **Challenge before you build.** Name weak assumptions, dependencies, gaps before producing.
|
|
79
|
+
- **Separate problem from solution.** Confirm the problem before specifying a feature.
|
|
80
|
+
- **Name tradeoffs.** State what every recommendation costs.
|
|
81
|
+
- **Scope ruthlessly.** Flag when scope exceeds a single shippable increment; suggest decomposition.
|
|
82
|
+
- **Be direct.** No "it depends" without conditions. No filler praise.
|
|
83
|
+
- **Stay in your lane.** Specification, positioning, analytics, research. Lightweight on execution; recommend domain handoff.
|
|
84
|
+
|
|
85
|
+
## Stage filter
|
|
86
|
+
|
|
87
|
+
Early-stage: limited budget, no brand awareness, unvalidated assumptions. Bias toward learning over scaling. Flag every claim that depends on an unvalidated market, customer, or product assumption.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
project: _demo
|
|
3
|
+
type: example
|
|
4
|
+
created: 2026-05-03
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Acme Corp — Demo Project
|
|
8
|
+
|
|
9
|
+
This is a sample project demonstrating how `roster` organizes work. Acme Corp is a fictional B2B SaaS company that helps small businesses automate their accounting workflows.
|
|
10
|
+
|
|
11
|
+
This demo is **safe to delete**. It exists to show the structure of a populated project. Real projects go in `projects/<your-project-name>/`.
|
|
12
|
+
|
|
13
|
+
## Identity
|
|
14
|
+
|
|
15
|
+
- Product: Acme Books — accounting automation for SMBs
|
|
16
|
+
- Stage: early-stage SaaS, post-launch
|
|
17
|
+
- Audience: SMB owners and bookkeepers
|
|
18
|
+
- Primary motion: outbound to bookkeeping firms and SMB owners
|
|
19
|
+
|
|
20
|
+
## Active agent instances
|
|
21
|
+
|
|
22
|
+
- `gtm/sdr/projects/_demo/` — outbound prospecting and cold outreach
|
|
23
|
+
|
|
24
|
+
## Files in this project
|
|
25
|
+
|
|
26
|
+
- `CLAUDE.md` — this file
|
|
27
|
+
- `state.md` — session continuity (auto-updated)
|
|
28
|
+
- `guidelines/` — substrate (voice, ICPs, messaging, brand-book, etc.)
|
|
29
|
+
|
|
30
|
+
## How to use as a learning example
|
|
31
|
+
|
|
32
|
+
1. Browse `projects/_demo/guidelines/` to see what filled-in substrate looks like
|
|
33
|
+
2. Browse `gtm/sdr/projects/_demo/config/default.yaml` to see how an agent instance is configured
|
|
34
|
+
3. Try running the agent against this demo: `/sdr run cold-outreach for _demo` (will prompt for filled bindings — feel free to use placeholder values for the test)
|
|
35
|
+
4. Delete this entire `_demo/` directory and its instance(s) when you're ready to start fresh
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# _demo
|
|
2
|
+
|
|
3
|
+
Placeholder project for testing roster workflows. Rename or duplicate this directory to
|
|
4
|
+
create a real project — `scripts/new-project.sh <name>` automates that in Phase 2.
|
|
5
|
+
|
|
6
|
+
## Structure
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
projects/_demo/
|
|
10
|
+
├── guidelines/ # written by function-level experts (added in Phase 2)
|
|
11
|
+
├── config/default.yaml # per-project agent config (added in Phase 2)
|
|
12
|
+
└── state.md # session continuity notes (max 5 lines; updated via /save-state)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
In Phase 1 this directory only proves `roster init` writes files to the right place. The
|
|
16
|
+
full project substrate lands when Phase 2 ships `templates/scaffold/` (see ROS-17).
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
project: _demo
|
|
3
|
+
created: 2026-05-03
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project-level config — Acme Corp demo
|
|
7
|
+
#
|
|
8
|
+
# Cross-agent defaults for this project. Agent-scoped config (per-instance
|
|
9
|
+
# tool bindings, channel caps, scoring thresholds) lives at:
|
|
10
|
+
# <function>/<agent>/projects/<project>/config/default.yaml
|
|
11
|
+
#
|
|
12
|
+
# Keep this file thin. It's read by chief-of-staff for audit reports and
|
|
13
|
+
# by any agent that needs project-wide signals.
|
|
14
|
+
|
|
15
|
+
# Display name shown in reports and Slack messages.
|
|
16
|
+
display_name: Acme Corp
|
|
17
|
+
|
|
18
|
+
# Stage: idea | pre-launch | early | growth | mature
|
|
19
|
+
stage: early
|
|
20
|
+
|
|
21
|
+
# Primary go-to-market motion. Drives default agent suggestions.
|
|
22
|
+
# Options: outbound | inbound | plg | hybrid
|
|
23
|
+
motion: outbound
|
|
24
|
+
|
|
25
|
+
# Default approval channel for HITL — used when an agent's instance config
|
|
26
|
+
# leaves approval_channel unset.
|
|
27
|
+
# Options: slack | inline | auto
|
|
28
|
+
approval_channel: auto
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Asset Links — Acme Corp
|
|
2
|
+
|
|
3
|
+
## Brand
|
|
4
|
+
- Logo files: <Drive folder URL>
|
|
5
|
+
- Brand guidelines PDF: <Drive folder URL>
|
|
6
|
+
|
|
7
|
+
## Templates
|
|
8
|
+
- Email template (cold outreach): <Drive doc URL>
|
|
9
|
+
- LinkedIn DM template: <Drive doc URL>
|
|
10
|
+
- Demo script: <Drive doc URL>
|
|
11
|
+
|
|
12
|
+
## External
|
|
13
|
+
- Website: https://acmecorp.example.com
|
|
14
|
+
- Calendar booking: https://cal.com/acmecorp/intro
|
|
15
|
+
- Knowledge base: https://docs.acmecorp.example.com
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Brand Book — Acme Corp
|
|
2
|
+
|
|
3
|
+
## Logo
|
|
4
|
+
- Wordmark "Acme" in deep navy
|
|
5
|
+
- Optional small icon (ledger lines)
|
|
6
|
+
|
|
7
|
+
## Colors
|
|
8
|
+
- Primary: Navy (#1a2742)
|
|
9
|
+
- Secondary: Warm white (#fafaf6)
|
|
10
|
+
- Accent: Muted gold (#c9a85d)
|
|
11
|
+
- Error: Brick red (#a93f3f)
|
|
12
|
+
|
|
13
|
+
## Typography
|
|
14
|
+
- Display: Söhne (or Inter as web fallback)
|
|
15
|
+
- Body: Inter
|
|
16
|
+
- Code: JetBrains Mono
|
|
17
|
+
|
|
18
|
+
## Imagery
|
|
19
|
+
- Photography: real small businesses, daylight, no stock-art smiles
|
|
20
|
+
- Illustrations: line-art only, navy + gold, no soft gradients
|
|
21
|
+
|
|
22
|
+
## Don't
|
|
23
|
+
- Don't pair navy + green — looks generic SaaS
|
|
24
|
+
- Don't use stock images of "diverse team in conference room"
|
|
25
|
+
- Don't use dramatic AI-generated illustrations
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# <Persona Name>
|
|
2
|
+
|
|
3
|
+
Short slug for filename: `<slug>.md` (e.g., `founding-team-hiring-manager.md`).
|
|
4
|
+
|
|
5
|
+
## Who they are
|
|
6
|
+
- Industry: <list>
|
|
7
|
+
- Company stage: <list>
|
|
8
|
+
- Company size: <range>
|
|
9
|
+
- Geography: <list or global>
|
|
10
|
+
|
|
11
|
+
## Their role
|
|
12
|
+
- Title patterns: <list>
|
|
13
|
+
- Reports to: <list>
|
|
14
|
+
- Tenure: <typical>
|
|
15
|
+
- Day-to-day: <what they actually do>
|
|
16
|
+
|
|
17
|
+
## What they care about
|
|
18
|
+
- Top 3 pains: <list>
|
|
19
|
+
- Top 3 goals: <list>
|
|
20
|
+
- What success looks like for them: <description>
|
|
21
|
+
|
|
22
|
+
## Buying signals / triggers
|
|
23
|
+
Recent events or states that suggest they're a good fit RIGHT NOW:
|
|
24
|
+
- <signal — e.g., "company raised Series B in last 90 days">
|
|
25
|
+
- <signal — e.g., "hiring founding GTM role">
|
|
26
|
+
- <signal>
|
|
27
|
+
|
|
28
|
+
## Engagement signals
|
|
29
|
+
Things they do publicly that suggest they're approachable:
|
|
30
|
+
- <signal — e.g., "posts on LinkedIn weekly">
|
|
31
|
+
- <signal — e.g., "responded to a founder DM publicly in last 30 days">
|
|
32
|
+
|
|
33
|
+
## Disqualifiers
|
|
34
|
+
What makes someone NOT a fit even if they otherwise match:
|
|
35
|
+
- <e.g., "company in stealth — no public signals to personalize on">
|
|
36
|
+
- <e.g., "C-suite at >500 person company — wrong access pattern">
|
|
37
|
+
|
|
38
|
+
## Channels they respond to
|
|
39
|
+
- Best: <list>
|
|
40
|
+
- Acceptable: <list>
|
|
41
|
+
- Avoid: <list>
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
<anything else that helps an agent know this persona>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Messaging — Acme Corp
|
|
2
|
+
|
|
3
|
+
## Headline value props
|
|
4
|
+
1. **Reconciles your books in 80% less time** — primary proof point
|
|
5
|
+
2. **Catches errors humans miss** — secondary, builds confidence
|
|
6
|
+
3. **Works inside QuickBooks / Xero / Wave** — table stakes, but worth saying
|
|
7
|
+
|
|
8
|
+
## Anti-positioning
|
|
9
|
+
- We are NOT trying to replace bookkeepers — we make them more productive
|
|
10
|
+
- We are NOT a generic AI tool — we're built specifically for small business accounting
|
|
11
|
+
|
|
12
|
+
## Frame for cold outreach
|
|
13
|
+
- Open with a question about their accounting workflow
|
|
14
|
+
- Acknowledge that automation is a hot topic but most tools are generic
|
|
15
|
+
- Offer something specific: a workflow demo or a 15-min audit
|
|
16
|
+
|
|
17
|
+
## Frame for inbound
|
|
18
|
+
- Lead with the time savings (concrete: "3 hours/week back")
|
|
19
|
+
- Show the integration logos (lower the perceived risk)
|
|
20
|
+
- Quote a real-feeling customer story
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Voice — Acme Corp
|
|
2
|
+
|
|
3
|
+
## Adjectives describing the brand voice
|
|
4
|
+
1. Practical
|
|
5
|
+
2. Direct
|
|
6
|
+
3. Reassuring
|
|
7
|
+
|
|
8
|
+
## Tone
|
|
9
|
+
- We talk like a knowledgeable colleague, not a vendor.
|
|
10
|
+
- We acknowledge accounting is tedious — we don't pretend it's exciting.
|
|
11
|
+
- We respect the reader's time. Short sentences. No fluff.
|
|
12
|
+
|
|
13
|
+
## Sentence length
|
|
14
|
+
Most sentences under 18 words. Very rarely longer.
|
|
15
|
+
|
|
16
|
+
## Vocabulary
|
|
17
|
+
- Use plain words: "books" not "ledger entries", "match" not "reconcile"
|
|
18
|
+
- Avoid: "transformative", "revolutionary", "leveraging", "synergize"
|
|
19
|
+
- Industry terms allowed when they're unavoidable: GAAP, AR, AP, COGS
|
|
20
|
+
|
|
21
|
+
## Channel-specific notes
|
|
22
|
+
- Email: warm + direct. Always one CTA per message.
|
|
23
|
+
- LinkedIn: a little more casual, less salesy.
|
|
24
|
+
- Website: most polished, but still conversational.
|
|
25
|
+
|
|
26
|
+
## Anti-examples
|
|
27
|
+
- "We're transforming the way SMBs handle their books" — too generic, sounds like every SaaS pitch
|
|
28
|
+
- "Leverage our cutting-edge platform" — corporate speak
|
|
29
|
+
- "Hope this finds you well" — empty opener
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
last_session: 2026-05-03
|
|
3
|
+
focus: (none — demo project)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Acme Corp — Session State
|
|
7
|
+
|
|
8
|
+
This file tracks short-term context across Claude Code sessions for this project. Updated via `/save-state` or by the user explicitly. Five lines max.
|
|
9
|
+
|
|
10
|
+
- Status: demo / illustrative
|
|
11
|
+
- Next task: replace with your real project, or delete `_demo/` entirely
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Shared script libraries
|
|
2
|
+
|
|
3
|
+
Helper functions for use across scripts. Empty for now — add as scripts grow.
|
|
4
|
+
|
|
5
|
+
Conventions:
|
|
6
|
+
- Bash: `<n>.sh`, sourced via `source "$(dirname $0)/lib/<n>.sh"`
|
|
7
|
+
- Python: `<n>.py` if needed (use `pip install --break-system-packages`)
|
|
8
|
+
- Keep functions narrow
|
|
9
|
+
|
|
10
|
+
Example future additions:
|
|
11
|
+
- `lib/lesson.sh` — read/write lesson files, validate schema
|
|
12
|
+
- `lib/run.sh` — append to run files, format frontmatter
|
|
13
|
+
- `lib/slack.sh` — HITL posting with retry
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# scripts/lib/functions.sh — shared helpers for reading the functions registry.
|
|
2
|
+
# Source from a script that has $ROOT set to repo root:
|
|
3
|
+
# ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
4
|
+
# source "$ROOT/scripts/lib/functions.sh"
|
|
5
|
+
#
|
|
6
|
+
# Provides:
|
|
7
|
+
# read_functions — print one slug per line from .config/functions.yaml
|
|
8
|
+
# read_functions_with_metadata — print "<slug>\t<has_expert>" per line
|
|
9
|
+
# is_valid_function <slug> — return 0 if slug is registered, else 1
|
|
10
|
+
|
|
11
|
+
_have_pyyaml() {
|
|
12
|
+
command -v python3 >/dev/null 2>&1 && python3 -c "import yaml" >/dev/null 2>&1
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
read_functions() {
|
|
16
|
+
local config="${ROOT}/.config/functions.yaml"
|
|
17
|
+
if [ ! -f "$config" ]; then
|
|
18
|
+
echo "ERROR: $config not found" >&2
|
|
19
|
+
return 1
|
|
20
|
+
fi
|
|
21
|
+
if _have_pyyaml; then
|
|
22
|
+
python3 -c "
|
|
23
|
+
import yaml, sys
|
|
24
|
+
try:
|
|
25
|
+
with open('$config') as f:
|
|
26
|
+
data = yaml.safe_load(f) or {}
|
|
27
|
+
except yaml.YAMLError as e:
|
|
28
|
+
sys.stderr.write('ERROR: malformed YAML in $config: ' + str(e) + '\n')
|
|
29
|
+
sys.exit(1)
|
|
30
|
+
for fn in data.get('functions', []):
|
|
31
|
+
slug = fn.get('slug', '')
|
|
32
|
+
if slug:
|
|
33
|
+
print(slug)
|
|
34
|
+
" || return 1
|
|
35
|
+
else
|
|
36
|
+
grep -E '^[[:space:]]*-[[:space:]]*slug:[[:space:]]*' "$config" \
|
|
37
|
+
| sed -E 's/^[[:space:]]*-[[:space:]]*slug:[[:space:]]*//; s/[[:space:]]*$//'
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
read_functions_with_metadata() {
|
|
42
|
+
local config="${ROOT}/.config/functions.yaml"
|
|
43
|
+
if [ ! -f "$config" ]; then
|
|
44
|
+
echo "ERROR: $config not found" >&2
|
|
45
|
+
return 1
|
|
46
|
+
fi
|
|
47
|
+
if _have_pyyaml; then
|
|
48
|
+
python3 -c "
|
|
49
|
+
import yaml, sys
|
|
50
|
+
try:
|
|
51
|
+
with open('$config') as f:
|
|
52
|
+
data = yaml.safe_load(f) or {}
|
|
53
|
+
except yaml.YAMLError as e:
|
|
54
|
+
sys.stderr.write('ERROR: malformed YAML in $config: ' + str(e) + '\n')
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
for fn in data.get('functions', []):
|
|
57
|
+
slug = fn.get('slug', '')
|
|
58
|
+
has_expert = bool(fn.get('has_expert', False))
|
|
59
|
+
if slug:
|
|
60
|
+
print(slug + '\t' + ('true' if has_expert else 'false'))
|
|
61
|
+
" || return 1
|
|
62
|
+
else
|
|
63
|
+
# Fallback: awk over flat YAML; track current slug and emit when has_expert seen.
|
|
64
|
+
awk '
|
|
65
|
+
/^[[:space:]]*-[[:space:]]*slug:[[:space:]]*/ {
|
|
66
|
+
if (slug != "") print slug "\t" (he == "true" ? "true" : "false")
|
|
67
|
+
slug = $0
|
|
68
|
+
sub(/^[[:space:]]*-[[:space:]]*slug:[[:space:]]*/, "", slug)
|
|
69
|
+
sub(/[[:space:]]*$/, "", slug)
|
|
70
|
+
he = "false"
|
|
71
|
+
next
|
|
72
|
+
}
|
|
73
|
+
/^[[:space:]]*has_expert:[[:space:]]*/ {
|
|
74
|
+
v = $0
|
|
75
|
+
sub(/^[[:space:]]*has_expert:[[:space:]]*/, "", v)
|
|
76
|
+
sub(/[[:space:]]*$/, "", v)
|
|
77
|
+
he = v
|
|
78
|
+
}
|
|
79
|
+
END {
|
|
80
|
+
if (slug != "") print slug "\t" (he == "true" ? "true" : "false")
|
|
81
|
+
}
|
|
82
|
+
' "$config"
|
|
83
|
+
fi
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
is_valid_function() {
|
|
87
|
+
local fn="$1"
|
|
88
|
+
read_functions 2>/dev/null | grep -Fxq "$fn"
|
|
89
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# new-project.sh — scaffold a new project substrate inside a roster workspace.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# bash scripts/new-project.sh <project-name> [<function>]
|
|
6
|
+
#
|
|
7
|
+
# Arguments:
|
|
8
|
+
# project-name Free-form name. Normalized to kebab-case (lowercase,
|
|
9
|
+
# [a-z0-9-], non-alphanumeric runs collapsed to '-').
|
|
10
|
+
# Examples:
|
|
11
|
+
# "My Co" -> my-co
|
|
12
|
+
# "foo bar/baz" -> foo-bar-baz
|
|
13
|
+
# "Acme Corp 2" -> acme-corp-2
|
|
14
|
+
# function Optional. If provided, must be registered in
|
|
15
|
+
# .config/functions.yaml (gtm, product, design, ops, ...).
|
|
16
|
+
#
|
|
17
|
+
# Creates:
|
|
18
|
+
# projects/<slug>/
|
|
19
|
+
# guidelines/.gitkeep
|
|
20
|
+
# config/default.yaml (project-level config skeleton)
|
|
21
|
+
# state.md (frontmatter + 5-line stub)
|
|
22
|
+
#
|
|
23
|
+
# Exit codes:
|
|
24
|
+
# 0 success
|
|
25
|
+
# 1 usage / validation error
|
|
26
|
+
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
30
|
+
# shellcheck disable=SC1091
|
|
31
|
+
source "$ROOT/scripts/lib/functions.sh"
|
|
32
|
+
|
|
33
|
+
usage() {
|
|
34
|
+
echo "Usage: $0 <project-name> [<function>]" >&2
|
|
35
|
+
echo " project-name Free-form; normalized to kebab-case" >&2
|
|
36
|
+
echo " function Optional; must be in .config/functions.yaml" >&2
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
|
|
40
|
+
usage
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
RAW_NAME="$1"
|
|
45
|
+
FUNCTION="${2:-}"
|
|
46
|
+
|
|
47
|
+
normalize() {
|
|
48
|
+
# 1. lowercase
|
|
49
|
+
# 2. replace any run of non-alphanumeric chars with a single '-'
|
|
50
|
+
# 3. trim leading/trailing '-'
|
|
51
|
+
printf '%s' "$1" \
|
|
52
|
+
| tr '[:upper:]' '[:lower:]' \
|
|
53
|
+
| sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
SLUG="$(normalize "$RAW_NAME")"
|
|
57
|
+
|
|
58
|
+
if [ -z "$SLUG" ]; then
|
|
59
|
+
echo "ERROR: project name '$RAW_NAME' is empty after normalization" >&2
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
if ! [[ "$SLUG" =~ ^[a-z][a-z0-9-]*$ ]]; then
|
|
64
|
+
echo "ERROR: normalized slug '$SLUG' must start with a letter and contain only a-z, 0-9, '-'" >&2
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [ -n "$FUNCTION" ]; then
|
|
69
|
+
if ! is_valid_function "$FUNCTION"; then
|
|
70
|
+
echo "ERROR: function '$FUNCTION' is not registered in .config/functions.yaml" >&2
|
|
71
|
+
echo "Registered functions:" >&2
|
|
72
|
+
read_functions 2>/dev/null | sed 's/^/ - /' >&2 || echo " (registry empty or missing)" >&2
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
TARGET="$ROOT/projects/$SLUG"
|
|
78
|
+
|
|
79
|
+
if [ -e "$TARGET" ]; then
|
|
80
|
+
echo "ERROR: project '$SLUG' already exists at $TARGET" >&2
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
TIMESTAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
85
|
+
|
|
86
|
+
mkdir -p "$TARGET/guidelines" "$TARGET/config" "$TARGET/assets"
|
|
87
|
+
touch "$TARGET/guidelines/.gitkeep" "$TARGET/assets/.gitkeep"
|
|
88
|
+
|
|
89
|
+
cat >"$TARGET/config/default.yaml" <<EOF
|
|
90
|
+
---
|
|
91
|
+
project: $SLUG
|
|
92
|
+
created: ${TIMESTAMP%T*}
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
# Project-level config for $SLUG.
|
|
96
|
+
# Cross-agent defaults. Agent-scoped instance config lives at:
|
|
97
|
+
# <function>/<agent>/projects/$SLUG/config/default.yaml
|
|
98
|
+
|
|
99
|
+
display_name: $SLUG
|
|
100
|
+
stage: early
|
|
101
|
+
motion: outbound
|
|
102
|
+
approval_channel: auto
|
|
103
|
+
EOF
|
|
104
|
+
|
|
105
|
+
cat >"$TARGET/state.md" <<EOF
|
|
106
|
+
---
|
|
107
|
+
updated: $TIMESTAMP
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
Last task: (none yet)
|
|
111
|
+
Active artifacts: (none)
|
|
112
|
+
Open questions: (none)
|
|
113
|
+
Next session: fill in guidelines/voice.md and at least one ICP
|
|
114
|
+
Notes: created via scripts/new-project.sh
|
|
115
|
+
EOF
|
|
116
|
+
|
|
117
|
+
echo "✓ Project '$SLUG' created at projects/$SLUG/"
|
|
118
|
+
echo ""
|
|
119
|
+
echo "Next steps:"
|
|
120
|
+
echo " 1. Fill projects/$SLUG/guidelines/voice.md (3 adjectives + tone)"
|
|
121
|
+
echo " 2. Add at least one ICP under projects/$SLUG/guidelines/icps/"
|
|
122
|
+
echo " 3. Edit projects/$SLUG/config/default.yaml — set display_name, stage, motion"
|
|
123
|
+
if [ -n "$FUNCTION" ]; then
|
|
124
|
+
echo " 4. Wire an agent instance via chief-of-staff: add-agent-to-project project=$SLUG function=$FUNCTION agent=<name>"
|
|
125
|
+
fi
|