@firatcand/roster 0.4.0 → 1.0.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/README.md +77 -220
- package/agents/lesson-drafter.md +3 -8
- package/agents/pattern-detector.md +0 -1
- package/bin/roster.js +168 -57
- package/package.json +2 -3
- package/skills/chief-of-staff/SKILL.md +62 -78
- package/skills/dreamer/SKILL.md +8 -7
- package/skills/roster-orchestrator/SKILL.md +53 -25
- package/templates/CLAUDE.project.template.md +1 -1
- package/templates/CONTEXT.template.md +2 -2
- package/templates/gitignore-defaults.txt +2 -0
- package/templates/scaffold/chief-of-staff/README.md +16 -24
- package/templates/scaffold/chief-of-staff/agent.md +22 -32
- package/templates/scaffold/chief-of-staff/plans/audit-agent.yaml +4 -4
- package/templates/scaffold/chief-of-staff/plans/audit-repo.yaml +5 -4
- package/templates/scaffold/chief-of-staff/plans/create-agent.yaml +5 -34
- package/templates/scaffold/config/project.yaml.template +10 -0
- package/templates/scaffold/conventions.md +159 -171
- package/templates/scaffold/dreamer/README.md +2 -2
- package/templates/scaffold/dreamer/agent.md +0 -1
- package/templates/scaffold/dreamer/plans/nightly-reflection.yaml +23 -37
- package/templates/scaffold/dreamer/subagents/lesson-drafter.md +2 -7
- package/templates/scaffold/{projects/_demo/guidelines → guidelines}/asset-links.md +4 -0
- package/templates/scaffold/{projects/_demo/guidelines → guidelines}/brand-book.md +4 -0
- package/templates/scaffold/{projects/_demo/guidelines → guidelines}/messaging.md +4 -0
- package/templates/scaffold/{projects/_demo/guidelines → guidelines}/voice.md +4 -0
- package/templates/scaffold/scripts/audit-agent.sh +74 -47
- package/templates/scaffold/scripts/audit-repo.sh +27 -49
- package/templates/scaffold/scripts/create-function.sh +1 -1
- package/templates/scaffold/scripts/lib/README.md +1 -1
- package/templates/scaffold/scripts/lib/bindings-prompt.sh +41 -124
- package/templates/scaffold/scripts/new-agent.sh +97 -91
- package/templates/scaffold/scripts/rename-agent.sh +91 -0
- package/templates/scaffold/scripts/save-state.sh +32 -0
- package/agents/critic.md +0 -74
- package/agents/enricher.md +0 -56
- package/agents/promotion-arbiter.md +0 -71
- package/agents/prospector.md +0 -51
- package/agents/writer.md +0 -58
- package/skills/sdr/SKILL.md +0 -147
- package/templates/scaffold/chief-of-staff/plans/add-agent-to-project.yaml +0 -45
- package/templates/scaffold/chief-of-staff/plans/archive-project.yaml +0 -51
- package/templates/scaffold/chief-of-staff/plans/audit-project.yaml +0 -34
- package/templates/scaffold/chief-of-staff/plans/create-project.yaml +0 -65
- package/templates/scaffold/chief-of-staff/plans/remove-agent-from-project.yaml +0 -50
- package/templates/scaffold/chief-of-staff/plans/rename-project.yaml +0 -62
- package/templates/scaffold/chief-of-staff/plans/unarchive-project.yaml +0 -41
- package/templates/scaffold/dreamer/subagents/promotion-arbiter.md +0 -64
- package/templates/scaffold/gtm/sdr/.claude/settings.json +0 -3
- package/templates/scaffold/gtm/sdr/.mcp.json +0 -21
- package/templates/scaffold/gtm/sdr/README.md +0 -41
- package/templates/scaffold/gtm/sdr/agent.md +0 -136
- package/templates/scaffold/gtm/sdr/plans/cold-outreach.yaml +0 -92
- package/templates/scaffold/gtm/sdr/projects/_demo/asset-references.md +0 -7
- package/templates/scaffold/gtm/sdr/projects/_demo/config/default.yaml +0 -69
- 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 +0 -67
- package/templates/scaffold/gtm/sdr/subagents/enricher.md +0 -49
- package/templates/scaffold/gtm/sdr/subagents/prospector.md +0 -44
- package/templates/scaffold/gtm/sdr/subagents/writer.md +0 -51
- package/templates/scaffold/projects/_demo/CLAUDE.md +0 -35
- package/templates/scaffold/projects/_demo/README.md +0 -16
- package/templates/scaffold/projects/_demo/assets/.gitkeep +0 -0
- package/templates/scaffold/projects/_demo/config/default.yaml +0 -28
- package/templates/scaffold/projects/_demo/state.md +0 -11
- package/templates/scaffold/scripts/archive-project.sh +0 -98
- package/templates/scaffold/scripts/audit-project.sh +0 -361
- package/templates/scaffold/scripts/new-agent-instance.sh +0 -114
- package/templates/scaffold/scripts/new-project.sh +0 -125
- package/templates/scaffold/scripts/remove-agent-from-project.sh +0 -67
- package/templates/scaffold/scripts/rename-project.sh +0 -118
- package/templates/scaffold/scripts/unarchive-project.sh +0 -115
- /package/templates/scaffold/gtm/{sdr/playbook/.gitkeep → .gitkeep} +0 -0
- /package/templates/scaffold/{projects/_demo/guidelines → guidelines}/icps/_persona-template.md +0 -0
|
@@ -1,136 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# bindings-prompt.sh —
|
|
2
|
+
# bindings-prompt.sh — DISABLED in v1.0 (ROS-78).
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# Pre-v1.0 behavior: read `## Tools and bindings` from agent.md (legacy
|
|
5
|
+
# two-level `tool: key: {required, description}` schema), prompt the user
|
|
6
|
+
# for binding values, and append a `tools:` block to a project-instance
|
|
7
|
+
# config at `projects/<inst>/config/default.yaml`.
|
|
7
8
|
#
|
|
8
|
-
#
|
|
9
|
-
# 1.
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
9
|
+
# Both inputs change in v1.0:
|
|
10
|
+
# 1. The shipped `## Tools and bindings` block in agent.md is now a flat
|
|
11
|
+
# schema (`tool: { env_var, required, description }` per
|
|
12
|
+
# conventions.md). The legacy parser silently emits an empty
|
|
13
|
+
# `tools.<tool>:` block when it encounters scalar values where it
|
|
14
|
+
# expects a mapping.
|
|
15
|
+
# 2. The instance-config target is gone — agent config lives at
|
|
16
|
+
# `<function>/<agent>/config.yaml`, and env-var values belong in
|
|
17
|
+
# workspace `/.env` (overridable in `<agent>/.env`).
|
|
13
18
|
#
|
|
14
|
-
#
|
|
19
|
+
# The proper v1.0 flow (read agent.md flat schema → write metadata to
|
|
20
|
+
# config.yaml `tools:` block → prompt for required env-var values and
|
|
21
|
+
# append to `/.env`) requires the env-merge loader that ships in Phase 2.
|
|
22
|
+
# Rather than ship a script whose advertised behavior is broken against
|
|
23
|
+
# the new schema, this script aborts with manual-configuration instructions
|
|
24
|
+
# (edit agent.md schema → mirror to config.yaml → fill /.env).
|
|
25
|
+
#
|
|
26
|
+
# Tracking: re-enable as part of the Phase 2 cli-plumbing reshape
|
|
27
|
+
# (env-merge loader + doctor checks 13-15).
|
|
15
28
|
|
|
16
29
|
set -euo pipefail
|
|
17
30
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if [ -z "$AGENT_MD" ] || [ -z "$INSTANCE_CONFIG" ]; then
|
|
22
|
-
echo "Usage: $0 <agent.md> <instance-config/default.yaml>" >&2
|
|
23
|
-
exit 1
|
|
24
|
-
fi
|
|
25
|
-
|
|
26
|
-
if [ ! -f "$AGENT_MD" ]; then
|
|
27
|
-
echo "ERROR: agent.md not found at $AGENT_MD" >&2
|
|
28
|
-
exit 1
|
|
29
|
-
fi
|
|
30
|
-
if [ ! -f "$INSTANCE_CONFIG" ]; then
|
|
31
|
-
echo "ERROR: instance config not found at $INSTANCE_CONFIG" >&2
|
|
32
|
-
exit 1
|
|
33
|
-
fi
|
|
34
|
-
|
|
35
|
-
if ! command -v python3 >/dev/null 2>&1; then
|
|
36
|
-
echo "ERROR: python3 is required for bindings-prompt.sh" >&2
|
|
37
|
-
exit 1
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
# Drive prompts + YAML emission via python; pass file paths via env to avoid quoting hell.
|
|
41
|
-
export AGENT_MD INSTANCE_CONFIG
|
|
42
|
-
|
|
43
|
-
FINAL_YAML=$(python3 << 'PYEOF'
|
|
44
|
-
import os, re, sys
|
|
45
|
-
|
|
46
|
-
agent_md = os.environ["AGENT_MD"]
|
|
47
|
-
with open(agent_md) as f:
|
|
48
|
-
content = f.read()
|
|
49
|
-
|
|
50
|
-
m = re.search(r'## Tools and bindings.*?\n```yaml\n(.*?)\n```', content, re.DOTALL)
|
|
51
|
-
if not m:
|
|
52
|
-
sys.stderr.write(f"ERROR: no '## Tools and bindings' YAML block in {agent_md}\n")
|
|
53
|
-
sys.exit(1)
|
|
54
|
-
|
|
55
|
-
schema_text = m.group(1)
|
|
56
|
-
|
|
57
|
-
try:
|
|
58
|
-
import yaml
|
|
59
|
-
except ImportError:
|
|
60
|
-
sys.stderr.write("ERROR: pyyaml required (pip3 install --user pyyaml)\n")
|
|
61
|
-
sys.exit(1)
|
|
62
|
-
|
|
63
|
-
try:
|
|
64
|
-
schema = yaml.safe_load(schema_text)
|
|
65
|
-
except Exception as e:
|
|
66
|
-
sys.stderr.write(f"ERROR parsing bindings schema: {e}\n")
|
|
67
|
-
sys.exit(1)
|
|
68
|
-
|
|
69
|
-
if not isinstance(schema, dict):
|
|
70
|
-
sys.stderr.write("Bindings schema is not a YAML mapping\n")
|
|
71
|
-
sys.exit(1)
|
|
72
|
-
|
|
73
|
-
# Try to open /dev/tty for interactive input. Fall back to all-TODO if unavailable.
|
|
74
|
-
try:
|
|
75
|
-
tty = open("/dev/tty", "r")
|
|
76
|
-
interactive = True
|
|
77
|
-
except OSError:
|
|
78
|
-
tty = None
|
|
79
|
-
interactive = False
|
|
80
|
-
sys.stderr.write("(non-interactive environment — all bindings will be TODO placeholders)\n")
|
|
81
|
-
|
|
82
|
-
def yaml_quote(value: str) -> str:
|
|
83
|
-
if value == "":
|
|
84
|
-
return '""'
|
|
85
|
-
if any(c in value for c in [":", "#", "@", "{", "}", "[", "]", ",", "&", "*", "!", "|", ">", "'", '"', "%", "`"]):
|
|
86
|
-
escaped = value.replace('\\', '\\\\').replace('"', '\\"')
|
|
87
|
-
return f'"{escaped}"'
|
|
88
|
-
return value
|
|
89
|
-
|
|
90
|
-
out_lines = []
|
|
91
|
-
out_lines.append("")
|
|
92
|
-
out_lines.append("# Tool bindings (filled via chief-of-staff scaffolding prompt)")
|
|
93
|
-
out_lines.append("tools:")
|
|
94
|
-
|
|
95
|
-
for tool, bindings in schema.items():
|
|
96
|
-
if not isinstance(bindings, dict):
|
|
97
|
-
continue
|
|
98
|
-
out_lines.append(f" {tool}:")
|
|
99
|
-
for key, meta in bindings.items():
|
|
100
|
-
if not isinstance(meta, dict):
|
|
101
|
-
continue
|
|
102
|
-
required = bool(meta.get("required", False))
|
|
103
|
-
description = str(meta.get("description", "") or "")
|
|
104
|
-
marker = "(required)" if required else "(optional)"
|
|
105
|
-
|
|
106
|
-
value = ""
|
|
107
|
-
if interactive:
|
|
108
|
-
sys.stderr.write(f"\n {tool}.{key} {marker}\n")
|
|
109
|
-
sys.stderr.write(f" {description}\n")
|
|
110
|
-
sys.stderr.write(f" > ")
|
|
111
|
-
sys.stderr.flush()
|
|
112
|
-
try:
|
|
113
|
-
value = tty.readline().strip()
|
|
114
|
-
except (OSError, KeyboardInterrupt):
|
|
115
|
-
value = ""
|
|
31
|
+
cat >&2 <<'MSG'
|
|
32
|
+
bindings-prompt.sh is disabled in Roster v1.0.
|
|
116
33
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
34
|
+
The legacy two-level schema parser this script uses is incompatible with
|
|
35
|
+
the flat ## Tools and bindings schema documented in conventions.md
|
|
36
|
+
("Tool bindings" section). The Phase 2 reshape (env-merge loader +
|
|
37
|
+
config.yaml/.env split) will rebuild this flow.
|
|
121
38
|
|
|
122
|
-
|
|
39
|
+
Until Phase 2 lands, configure tool bindings by hand:
|
|
123
40
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
41
|
+
1. Open <function>/<agent>/agent.md and confirm the ## Tools and
|
|
42
|
+
bindings YAML block lists each tool with env_var, required, and
|
|
43
|
+
description fields (see conventions.md § "Tool bindings").
|
|
44
|
+
2. Mirror that block as the tools: mapping in
|
|
45
|
+
<function>/<agent>/config.yaml.
|
|
46
|
+
3. Add the corresponding env var values to workspace /.env (or, for
|
|
47
|
+
agent-scoped overrides, <function>/<agent>/.env).
|
|
128
48
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
echo "$FINAL_YAML"
|
|
133
|
-
} >> "$INSTANCE_CONFIG"
|
|
49
|
+
(The chief-of-staff guided create-agent flow shipped in v0.4 is also on
|
|
50
|
+
the pre-v1 shape; it will be updated alongside the env-merge loader.)
|
|
51
|
+
MSG
|
|
134
52
|
|
|
135
|
-
|
|
136
|
-
echo "✓ Tool bindings appended to $INSTANCE_CONFIG" >&2
|
|
53
|
+
exit 2
|
|
@@ -62,7 +62,7 @@ description: "$fn agent — TODO: fill in description"
|
|
|
62
62
|
|
|
63
63
|
# /$name
|
|
64
64
|
|
|
65
|
-
You are operating the \`$fn/$name\` agent. Load \`$fn/$name/agent.md\` and the
|
|
65
|
+
You are operating the \`$fn/$name\` agent. Load \`$fn/$name/agent.md\` and the workspace's relevant context.
|
|
66
66
|
|
|
67
67
|
The user request is: \$ARGUMENTS
|
|
68
68
|
|
|
@@ -70,28 +70,25 @@ The user request is: \$ARGUMENTS
|
|
|
70
70
|
|
|
71
71
|
Parse the user request:
|
|
72
72
|
|
|
73
|
-
1. **If it matches \`run <plan-name
|
|
73
|
+
1. **If it matches \`run <plan-name>\`**:
|
|
74
74
|
- Load \`$fn/$name/plans/<plan-name>.yaml\`. If it doesn't exist, list available plans and ask user to pick.
|
|
75
|
-
- Load
|
|
76
|
-
- Load
|
|
77
|
-
- Validate that all required tool bindings
|
|
78
|
-
- Execute the plan steps. Substitute \`\${tools.X.
|
|
79
|
-
- Log to \`$fn/$name/
|
|
80
|
-
- Surface HITL approvals per the plan's approval_channel
|
|
81
|
-
|
|
82
|
-
2. **If
|
|
75
|
+
- Load \`$fn/$name/config.yaml\` and resolve env via \`resolveAgentEnv\` (\`$fn/$name/.env\` overrides workspace \`/.env\`).
|
|
76
|
+
- Load workspace guidelines referenced under \`config.yaml\` \`guideline_refs:\` (e.g., \`/guidelines/voice.md\`, \`/guidelines/icps/\`, \`/guidelines/messaging.md\`).
|
|
77
|
+
- Validate that all required tool bindings have non-empty env vars. Abort with a clear message if not.
|
|
78
|
+
- Execute the plan steps. Substitute \`\${tools.X.env_var}\`, \`\${inputs.X}\`, \`\${config.X}\`.
|
|
79
|
+
- Log to \`$fn/$name/logs/runs/<YYYY-MM>/<YYYY-MM-DD-HHMM>.md\`.
|
|
80
|
+
- Surface HITL approvals per the plan's \`approval_channel\`.
|
|
81
|
+
|
|
82
|
+
2. **If no plan is named**:
|
|
83
83
|
- List available plans from \`$fn/$name/plans/\` with descriptions. Ask user to pick.
|
|
84
84
|
|
|
85
|
-
3. **
|
|
86
|
-
- List available projects and plans. Ask user to specify both.
|
|
87
|
-
|
|
88
|
-
4. **For ad-hoc strategic work**: suggest invoking \`$fn/EXPERT.md\` instead.
|
|
85
|
+
3. **For ad-hoc strategic work**: suggest invoking \`$fn/EXPERT.md\` instead.
|
|
89
86
|
|
|
90
87
|
## Constraints
|
|
91
88
|
|
|
92
89
|
- Only run plans that exist as files in \`$fn/$name/plans/\`.
|
|
93
90
|
- Don't bypass approval gates.
|
|
94
|
-
- File writes go to
|
|
91
|
+
- File writes go to \`$fn/$name/logs/runs/\` unless the plan explicitly writes elsewhere.
|
|
95
92
|
EOF
|
|
96
93
|
}
|
|
97
94
|
|
|
@@ -137,7 +134,7 @@ fi
|
|
|
137
134
|
|
|
138
135
|
echo "Creating agent: $FN/$NAME"
|
|
139
136
|
|
|
140
|
-
mkdir -p "$TARGET"/{subagents,playbook,logs,
|
|
137
|
+
mkdir -p "$TARGET"/{subagents,playbook,pending,logs/runs,logs/feedback,.claude/skills,.claude/plugins}
|
|
141
138
|
|
|
142
139
|
# agent.md stub
|
|
143
140
|
cat > "$TARGET/agent.md" << EOF
|
|
@@ -149,45 +146,36 @@ cat > "$TARGET/agent.md" << EOF
|
|
|
149
146
|
|
|
150
147
|
## Inputs
|
|
151
148
|
|
|
152
|
-
The orchestrator expects
|
|
153
|
-
|
|
154
|
-
- \`project\`: project slug
|
|
155
|
-
- <other inputs>
|
|
149
|
+
The orchestrator expects per-plan inputs (declared in each plan's \`inputs:\` block).
|
|
156
150
|
|
|
157
151
|
Read at runtime:
|
|
158
152
|
|
|
159
153
|
- \`agent.md\` (this file)
|
|
160
|
-
- \`
|
|
161
|
-
- \`
|
|
162
|
-
- \`
|
|
163
|
-
- <other guidelines this agent uses>
|
|
164
|
-
- \`<this-agent>/projects/<project>/playbook/\` — project-scoped lessons
|
|
165
|
-
- \`<this-agent>/playbook/\` — global lessons
|
|
154
|
+
- \`config.yaml\` (workspace-root-relative guideline refs + tool bindings)
|
|
155
|
+
- Workspace guidelines referenced under \`config.yaml\` \`guideline_refs:\` (e.g., \`/guidelines/voice.md\`, \`/guidelines/icps/\`, \`/guidelines/messaging.md\`)
|
|
156
|
+
- \`playbook/\` — validated lessons (single playbook per agent)
|
|
166
157
|
|
|
167
|
-
|
|
158
|
+
Env resolution: \`<this-agent>/.env\` overrides workspace \`/.env\`. Required tool env vars validated before the plan runs.
|
|
168
159
|
|
|
169
|
-
|
|
170
|
-
2. <step>
|
|
171
|
-
3. <step>
|
|
160
|
+
## Plans
|
|
172
161
|
|
|
173
|
-
|
|
162
|
+
Named plans this agent runs (files in \`plans/<plan>.yaml\`). One-line description per plan.
|
|
163
|
+
No default plan — invoking without a plan triggers an interactive "which plan?" prompt.
|
|
174
164
|
|
|
175
|
-
- <
|
|
165
|
+
- <plan-name>: <one-liner>
|
|
176
166
|
|
|
177
|
-
##
|
|
178
|
-
|
|
179
|
-
Agent-scoped MCPs at \`<this-agent>/.mcp.json\`:
|
|
180
|
-
- <tool/MCP> — <purpose>
|
|
167
|
+
## Subagents
|
|
181
168
|
|
|
182
|
-
|
|
169
|
+
- <subagent-name>.md — <one-liner>
|
|
183
170
|
|
|
184
171
|
## Outputs
|
|
185
172
|
|
|
186
|
-
Run file at \`
|
|
173
|
+
Run file at \`logs/runs/<YYYY-MM>/<YYYY-MM-DD-HHMM>.md\`. See \`conventions.md\` § "Run file format".
|
|
174
|
+
Per-plan output schemas live in each plan's \`outputs:\` block.
|
|
187
175
|
|
|
188
176
|
## Approval
|
|
189
177
|
|
|
190
|
-
\`approval_channel: auto\` — in-session if interactive, Slack \`#${FN}\` if cron (resolved via \`SLACK_HITL_CHANNEL_$(echo "$FN" | tr '[:lower:]-' '[:upper:]_')\` in
|
|
178
|
+
\`approval_channel: auto\` — in-session if interactive, Slack \`#${FN}\` if cron (resolved via \`SLACK_HITL_CHANNEL_$(echo "$FN" | tr '[:lower:]-' '[:upper:]_')\` in workspace \`/.env\`).
|
|
191
179
|
|
|
192
180
|
## Lessons protocol
|
|
193
181
|
|
|
@@ -206,39 +194,49 @@ cat > "$TARGET/README.md" << EOF
|
|
|
206
194
|
|
|
207
195
|
## Files
|
|
208
196
|
|
|
209
|
-
- \`agent.md\` — orchestrator contract
|
|
197
|
+
- \`agent.md\` — orchestrator contract (behavioral prompt, plans list, tool bindings schema)
|
|
198
|
+
- \`config.yaml\` — guideline refs + tool bindings (workspace-root paths)
|
|
199
|
+
- \`.env\` — agent-scoped env overrides (gitignored, 0600 — optional, inherits from workspace \`/.env\`)
|
|
200
|
+
- \`plans/\` — named workflows (\`<plan>.yaml\`)
|
|
210
201
|
- \`subagents/\` — specialized roles
|
|
211
|
-
- \`playbook/\` —
|
|
212
|
-
- \`
|
|
213
|
-
-
|
|
214
|
-
-
|
|
215
|
-
-
|
|
202
|
+
- \`playbook/\` — validated lessons (single playbook per agent)
|
|
203
|
+
- \`pending/\` — HITL items awaiting approval
|
|
204
|
+
- \`logs/runs/\`, \`logs/feedback/\` — run outputs + mirrored feedback
|
|
205
|
+
- \`asset-references.md\` — which workspace assets this agent uses (thin pointer)
|
|
206
|
+
- \`.claude/\` — agent-scoped Claude Code config (skills, plugins, settings)
|
|
207
|
+
- \`.mcp.json\` — agent-scoped MCPs
|
|
216
208
|
|
|
217
209
|
## Invocation
|
|
218
210
|
|
|
219
|
-
From
|
|
211
|
+
From the workspace root:
|
|
220
212
|
|
|
221
213
|
\`\`\`bash
|
|
222
|
-
cd $FN/$NAME/projects/<project>/
|
|
223
214
|
claude
|
|
224
|
-
|
|
215
|
+
> /$NAME run <plan-name>
|
|
225
216
|
\`\`\`
|
|
226
217
|
|
|
227
|
-
|
|
218
|
+
Or via natural language:
|
|
219
|
+
|
|
220
|
+
\`\`\`
|
|
221
|
+
"Run $FN/$NAME using the <plan-name> plan"
|
|
222
|
+
\`\`\`
|
|
223
|
+
|
|
224
|
+
From cron: see ADR-0001 (subscription-billed scheduling via native local schedulers). Install via \`roster schedule install $FN/$NAME <plan> --cron "<expr>" --tool claude|codex\`.
|
|
228
225
|
|
|
229
226
|
## Configuration
|
|
230
227
|
|
|
231
|
-
|
|
228
|
+
\`config.yaml\` (this agent) — guideline refs + tool bindings.
|
|
229
|
+
Workspace \`/.env\` (root) + optional \`<this-agent>/.env\` for agent-scoped overrides.
|
|
232
230
|
|
|
233
231
|
## Outputs
|
|
234
232
|
|
|
235
|
-
\`
|
|
233
|
+
\`logs/runs/<YYYY-MM>/<YYYY-MM-DD-HHMM>.md\` — one file per invocation.
|
|
236
234
|
EOF
|
|
237
235
|
|
|
238
236
|
# .mcp.json stub
|
|
239
237
|
cat > "$TARGET/.mcp.json" << EOF
|
|
240
238
|
{
|
|
241
|
-
"_comment": "Agent-scoped MCPs for $NAME. Available when working in this agent's tree
|
|
239
|
+
"_comment": "Agent-scoped MCPs for $NAME. Available when working in this agent's tree. Add MCPs this agent specifically needs. Universal MCPs (Slack, Google Drive) are inherited from the workspace .mcp.json.",
|
|
242
240
|
"mcpServers": {}
|
|
243
241
|
}
|
|
244
242
|
EOF
|
|
@@ -273,41 +271,48 @@ cat > "$TARGET/subagents/_template.md" << 'EOF'
|
|
|
273
271
|
<Specific criteria for acceptable output.>
|
|
274
272
|
EOF
|
|
275
273
|
|
|
276
|
-
#
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
#
|
|
293
|
-
#
|
|
274
|
+
# config.yaml — agent config (guideline refs + tool bindings)
|
|
275
|
+
# Minimal stub. Until the Phase 2 env-merge loader lands, bindings are
|
|
276
|
+
# hand-edited: copy the ## Tools and bindings YAML block from agent.md
|
|
277
|
+
# into the tools: mapping below, then fill the corresponding env vars
|
|
278
|
+
# in workspace /.env (or this agent's .env).
|
|
279
|
+
cat > "$TARGET/config.yaml" << EOF
|
|
280
|
+
agent: $FN/$NAME
|
|
281
|
+
plans_dir: ./plans/
|
|
282
|
+
|
|
283
|
+
# Workspace-root-relative refs. Loader rejects literal absolute fs paths
|
|
284
|
+
# like /Users/, /home/, /etc/, /var/, /tmp/, /opt/.
|
|
285
|
+
guideline_refs:
|
|
286
|
+
voice: /guidelines/voice.md
|
|
287
|
+
icps: /guidelines/icps/
|
|
288
|
+
messaging: /guidelines/messaging.md
|
|
289
|
+
# add more as needed:
|
|
290
|
+
# brand_book: /guidelines/brand-book.md
|
|
291
|
+
# do_and_dont: /guidelines/do-and-dont.md
|
|
292
|
+
# compliance: /guidelines/compliance.md
|
|
293
|
+
# competitors: /guidelines/competitors.md
|
|
294
|
+
|
|
295
|
+
# Tool bindings. Each tool entry names the env var, required flag, and a
|
|
296
|
+
# short description. Env vars themselves live in workspace /.env (or are
|
|
297
|
+
# overridden in this agent's .env).
|
|
298
|
+
tools: {}
|
|
294
299
|
EOF
|
|
295
300
|
|
|
296
|
-
|
|
297
|
-
|
|
301
|
+
# asset-references.md — thin pointer at agent root
|
|
302
|
+
cat > "$TARGET/asset-references.md" << EOF
|
|
303
|
+
# Asset references — $FN/$NAME
|
|
298
304
|
|
|
299
|
-
This agent uses these assets from \`
|
|
305
|
+
This agent uses these assets from \`guidelines/asset-links.md\`:
|
|
300
306
|
|
|
301
307
|
- <e.g., specific asset by name>
|
|
302
308
|
EOF
|
|
303
309
|
|
|
304
310
|
touch "$TARGET/playbook/.gitkeep"
|
|
305
|
-
touch "$TARGET/
|
|
311
|
+
touch "$TARGET/pending/.gitkeep"
|
|
312
|
+
touch "$TARGET/logs/runs/.gitkeep"
|
|
313
|
+
touch "$TARGET/logs/feedback/.gitkeep"
|
|
306
314
|
touch "$TARGET/.claude/skills/.gitkeep"
|
|
307
315
|
touch "$TARGET/.claude/plugins/.gitkeep"
|
|
308
|
-
touch "$TARGET/projects/_template/playbook/.gitkeep"
|
|
309
|
-
touch "$TARGET/projects/_template/log/runs/.gitkeep"
|
|
310
|
-
touch "$TARGET/projects/_template/log/feedback/.gitkeep"
|
|
311
316
|
|
|
312
317
|
# === Tool bindings prompt (added by tool-bindings workflow) ===
|
|
313
318
|
# Ask the user whether to define tools now. If yes, collect tool names and scaffold
|
|
@@ -346,24 +351,25 @@ if [ -t 0 ] && [ "${AGENT_TEAM_NO_CONFIRM:-0}" != "1" ]; then
|
|
|
346
351
|
echo ""
|
|
347
352
|
echo "## Tools and bindings"
|
|
348
353
|
echo ""
|
|
349
|
-
echo "
|
|
354
|
+
echo "Tool bindings expected by this agent. Until the Phase 2 env-merge loader ships, configure them by hand: mirror the YAML block below into \`<agent>/config.yaml\` under a \`tools:\` key, and put the env var values in workspace \`/.env\` (or \`<agent>/.env\` for agent-scoped overrides)."
|
|
350
355
|
echo ""
|
|
351
|
-
echo "Fill in each tool's bindings below. Schema: each
|
|
356
|
+
echo "Fill in each tool's bindings below. Schema per conventions.md § \"Tool bindings\": each tool has a \`env_var\` (the env-var name the runtime reads), a \`required\` flag (true/false), and a one-line \`description\`."
|
|
352
357
|
echo ""
|
|
353
358
|
echo '```yaml'
|
|
354
359
|
for tool in "${TOOL_NAMES[@]}"; do
|
|
360
|
+
tool_env=$(echo "$tool" | tr '[:lower:]-' '[:upper:]_')
|
|
355
361
|
echo "$tool:"
|
|
356
|
-
echo " # TODO:
|
|
357
|
-
echo " #
|
|
358
|
-
echo " #
|
|
359
|
-
echo " # description: \"...\""
|
|
362
|
+
echo " env_var: ${tool_env}_API_KEY # TODO: confirm env var name"
|
|
363
|
+
echo " required: true # TODO: confirm required vs optional"
|
|
364
|
+
echo " description: \"\" # TODO: one-line description"
|
|
360
365
|
done
|
|
361
366
|
echo '```'
|
|
362
367
|
} >> "$NEW_AGENT_MD"
|
|
363
368
|
|
|
364
369
|
echo ""
|
|
365
370
|
echo "✓ Added '## Tools and bindings' to $NEW_AGENT_MD with stubs for: ${TOOL_NAMES[*]}"
|
|
366
|
-
echo " Edit agent.md to fill in
|
|
371
|
+
echo " Edit agent.md to fill in env_var names + descriptions, then mirror the tools: block into <agent>/config.yaml by hand."
|
|
372
|
+
echo " (Phase 2 will add an env-merge loader + automated config.yaml/.env wiring; until then this step is manual.)"
|
|
367
373
|
else
|
|
368
374
|
echo " No valid tool names provided. Skipping section."
|
|
369
375
|
fi
|
|
@@ -399,12 +405,12 @@ echo ""
|
|
|
399
405
|
echo "✓ Agent '$FN/$NAME' created at $TARGET"
|
|
400
406
|
echo ""
|
|
401
407
|
echo "Next steps:"
|
|
402
|
-
echo " 1. Fill in $TARGET/agent.md (purpose, inputs,
|
|
403
|
-
echo " 2.
|
|
404
|
-
echo " 3. Add
|
|
405
|
-
echo " 4.
|
|
406
|
-
echo " 5.
|
|
407
|
-
echo " 6.
|
|
408
|
-
echo " 7.
|
|
408
|
+
echo " 1. Fill in $TARGET/agent.md (purpose, inputs, plans, subagents, tools, outputs)"
|
|
409
|
+
echo " 2. Fill in $TARGET/config.yaml (guideline_refs, tools)"
|
|
410
|
+
echo " 3. Add subagents: cp $TARGET/subagents/_template.md $TARGET/subagents/<name>.md and fill in"
|
|
411
|
+
echo " 4. Add agent-scoped MCPs to $TARGET/.mcp.json if needed (HeyReach, Apollo, etc.)"
|
|
412
|
+
echo " 5. Update $TARGET/README.md with a real description"
|
|
413
|
+
echo " 6. Add at least one plan to $TARGET/plans/ (e.g., $TARGET/plans/<plan-name>.yaml)"
|
|
414
|
+
echo " 7. Edit .claude/commands/$NAME.md to fill in the description"
|
|
409
415
|
echo ""
|
|
410
416
|
echo "Reference: see gtm/sdr/ for a complete example."
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# rename-agent.sh — renames a global agent everywhere it appears
|
|
3
|
+
# Usage: bash scripts/rename-agent.sh <function> <old> <new>
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
if [ $# -ne 3 ]; then
|
|
8
|
+
echo "Usage: $0 <function> <old> <new>"
|
|
9
|
+
exit 1
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
FN="$1"
|
|
13
|
+
OLD="$2"
|
|
14
|
+
NEW="$3"
|
|
15
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
16
|
+
|
|
17
|
+
if ! [[ "$NEW" =~ ^[a-z][a-z0-9-]*$ ]]; then
|
|
18
|
+
echo "ERROR: New slug must be lowercase, alphanumeric + hyphens, starting with a letter."
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
OLD_DIR="$ROOT/$FN/$OLD"
|
|
23
|
+
NEW_DIR="$ROOT/$FN/$NEW"
|
|
24
|
+
|
|
25
|
+
if [ ! -d "$OLD_DIR" ]; then
|
|
26
|
+
echo "ERROR: Agent '$FN/$OLD' not found at $OLD_DIR"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
if [ -d "$NEW_DIR" ]; then
|
|
31
|
+
echo "ERROR: Agent '$FN/$NEW' already exists at $NEW_DIR"
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
36
|
+
|
|
37
|
+
mv "$OLD_DIR" "$NEW_DIR"
|
|
38
|
+
echo " Moved: $FN/$OLD/ → $FN/$NEW/"
|
|
39
|
+
|
|
40
|
+
SED_INPLACE=(-i)
|
|
41
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
42
|
+
SED_INPLACE=(-i '')
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Broad replace on prose files only — these are markdown stubs where the
|
|
46
|
+
# old slug appears in headings / paths and we want every reference updated.
|
|
47
|
+
for f in "$NEW_DIR"/agent.md "$NEW_DIR"/README.md "$NEW_DIR"/asset-references.md; do
|
|
48
|
+
[ -f "$f" ] && sed "${SED_INPLACE[@]}" "s|$OLD|$NEW|g" "$f"
|
|
49
|
+
done
|
|
50
|
+
|
|
51
|
+
# config.yaml: only the identity field. A broad replace would corrupt env-var
|
|
52
|
+
# names, comments, and any value that legitimately contains $OLD.
|
|
53
|
+
CFG="$NEW_DIR/config.yaml"
|
|
54
|
+
if [ -f "$CFG" ]; then
|
|
55
|
+
sed "${SED_INPLACE[@]}" "s|^agent: $FN/$OLD$|agent: $FN/$NEW|" "$CFG"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
while IFS= read -r f; do
|
|
59
|
+
case "$f" in
|
|
60
|
+
*"_archive/"*) continue ;;
|
|
61
|
+
*"/logs/"*) continue ;;
|
|
62
|
+
*"/log/runs/"*) continue ;;
|
|
63
|
+
*"/log/feedback/"*) continue ;;
|
|
64
|
+
*"/playbook/"*) continue ;;
|
|
65
|
+
*) sed "${SED_INPLACE[@]}" "s|$FN/$OLD|$FN/$NEW|g" "$f" ;;
|
|
66
|
+
esac
|
|
67
|
+
done < <(grep -rl "$FN/$OLD" --include='*.md' --include='*.yaml' --include='*.json' --include='*.sh' --include='*.txt' "$ROOT" 2>/dev/null)
|
|
68
|
+
|
|
69
|
+
OLD_CMD="$ROOT/.claude/commands/$OLD.md"
|
|
70
|
+
NEW_CMD="$ROOT/.claude/commands/$NEW.md"
|
|
71
|
+
if [ -f "$OLD_CMD" ]; then
|
|
72
|
+
mv "$OLD_CMD" "$NEW_CMD"
|
|
73
|
+
sed "${SED_INPLACE[@]}" "s|$OLD|$NEW|g" "$NEW_CMD"
|
|
74
|
+
echo " Renamed slash command: .claude/commands/$OLD.md → $NEW.md"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
LOG_DIR="$ROOT/chief-of-staff/logs/$(date +%Y-%m)"
|
|
78
|
+
mkdir -p "$LOG_DIR"
|
|
79
|
+
LOG_FILE="$LOG_DIR/operations-$(date +%Y-%m-%d).md"
|
|
80
|
+
{
|
|
81
|
+
echo ""
|
|
82
|
+
echo "## $TIMESTAMP — rename-agent: $FN/$OLD → $FN/$NEW"
|
|
83
|
+
} >> "$LOG_FILE"
|
|
84
|
+
|
|
85
|
+
echo ""
|
|
86
|
+
echo "Files mentioning '$OLD' that were NOT auto-updated (review manually):"
|
|
87
|
+
grep -rln "$OLD" "$ROOT" 2>/dev/null | grep -v "_archive\|/logs/\|/log/runs/\|/log/feedback/\|/playbook/" | sed "s|$ROOT/| - |" || echo " (none found)"
|
|
88
|
+
|
|
89
|
+
echo ""
|
|
90
|
+
echo "✓ Rename complete."
|
|
91
|
+
echo " Operation log: $LOG_FILE"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# save-state.sh — write workspace state.md
|
|
3
|
+
#
|
|
4
|
+
# In v1, workspace = project. state.md lives at workspace root.
|
|
5
|
+
# Format: see conventions.md § "State file format". Normally Claude writes
|
|
6
|
+
# state.md directly when asked. This script exists for external invocation
|
|
7
|
+
# or scripted updates.
|
|
8
|
+
#
|
|
9
|
+
# Usage: bash scripts/save-state.sh "<state notes (multiline OK)>"
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
if [ $# -lt 1 ]; then
|
|
14
|
+
echo "Usage: $0 \"<state notes>\""
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
NOTES="$*"
|
|
19
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
20
|
+
STATE_FILE="$ROOT/state.md"
|
|
21
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
22
|
+
|
|
23
|
+
cat > "$STATE_FILE" << EOF
|
|
24
|
+
---
|
|
25
|
+
updated: $TIMESTAMP
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
$NOTES
|
|
29
|
+
EOF
|
|
30
|
+
|
|
31
|
+
echo "✓ Saved workspace state"
|
|
32
|
+
echo " $STATE_FILE"
|