shraga 0.1.13 → 0.1.15
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/defaults/modules/routine/README.md +38 -0
- package/defaults/modules/routine/module.json +36 -0
- package/defaults/modules/routine/routine.md.tmpl +75 -0
- package/defaults/modules/routine/seeds/workspace/agenda.md +15 -0
- package/defaults/skills/add-skill.md +4 -0
- package/defaults/skills/artifacts.md +4 -0
- package/defaults/skills/communications.md +4 -0
- package/defaults/skills/create-module.md +75 -0
- package/defaults/skills/debug.md +4 -0
- package/defaults/skills/garden.md +4 -0
- package/defaults/skills/github-contributor.md +4 -0
- package/defaults/skills/identity.md +4 -0
- package/defaults/skills/mcp-server.md +4 -0
- package/defaults/skills/modules.md +41 -0
- package/defaults/skills/plan.md +4 -0
- package/defaults/skills/reconcile.md +4 -0
- package/defaults/skills/scheduler.md +5 -2
- package/defaults/skills/self-aware.md +5 -1
- package/defaults/skills/write-tests.md +4 -0
- package/dist/client/assets/index-D5KxKl57.js +1946 -0
- package/dist/client/assets/index-nyZagTjP.css +10 -0
- package/dist/client/index.html +2 -2
- package/package.json +1 -1
- package/src/client/App.tsx +11 -0
- package/src/client/components/ChatView.tsx +14 -0
- package/src/client/components/ConversationHeader.tsx +29 -0
- package/src/client/components/ModulesManager.tsx +259 -0
- package/src/client/hooks/useConversation.ts +5 -3
- package/src/client/hooks/useModules.ts +81 -0
- package/src/client/lib/api.ts +13 -0
- package/src/client/lib/sessionApi.ts +16 -2
- package/src/client/lib/workspaceContext.tsx +2 -0
- package/src/mcp-stdio-bridge.ts +5 -5
- package/src/server/boot.ts +95 -16
- package/src/server/claude.ts +12 -1
- package/src/server/data-sync.ts +28 -0
- package/src/server/engine/claude-code.ts +10 -3
- package/src/server/events/types.ts +3 -0
- package/src/server/mcp-sidecar.ts +2 -2
- package/src/server/mcp.ts +3 -5
- package/src/server/modules/index.ts +3 -0
- package/src/server/modules/routes.ts +78 -0
- package/src/server/modules/service.ts +575 -0
- package/src/server/modules/types.ts +62 -0
- package/src/server/paths.ts +57 -6
- package/src/server/scheduler/builtins.ts +27 -3
- package/src/server/scheduler/engine.ts +6 -0
- package/src/server/scheduler/runner.ts +96 -30
- package/src/server/scheduler/types.ts +3 -0
- package/src/server/sessions.ts +4 -0
- package/src/server/shraga-config.ts +21 -4
- package/src/server/skills.ts +6 -5
- package/src/server/slack/bot.ts +3 -1
- package/dist/client/assets/index-ChElotX8.js +0 -1936
- package/dist/client/assets/index-DdibEb2O.css +0 -10
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# routine
|
|
2
|
+
|
|
3
|
+
Turns the agent into a self-driving daily operator: a rendered `routine` skill (the operating contract — hours, OKR-anchored priority function, tick logic, autonomy tiers, comms policy), two schedules, and a seeded `workspace/agenda.md` the dispatcher uses as working memory.
|
|
4
|
+
|
|
5
|
+
## What installs
|
|
6
|
+
|
|
7
|
+
- **Skill** `skills/routine.md` — rendered from the template with your config.
|
|
8
|
+
- **Schedule** `routine-tick` (enabled) — hourly dispatcher tick during work hours; most ticks end in a skip.
|
|
9
|
+
- **Schedule** `routine-work-block` (**ships disabled**) — a superseded midday fallback; enable only if you want a guaranteed daily work block instead of tick-driven cadence.
|
|
10
|
+
- **Seed** `workspace/agenda.md` — created only if missing; never overwritten.
|
|
11
|
+
|
|
12
|
+
## Config
|
|
13
|
+
|
|
14
|
+
| Key | Default | Meaning |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `workingDays` | `Sun–Thu` | Working days (prose, shown in the skill) |
|
|
17
|
+
| `workHours` | `08:00–18:00` | Working hours (prose) |
|
|
18
|
+
| `tz` | `Asia/Jerusalem` | IANA timezone for schedules and hours |
|
|
19
|
+
| `tickCron` | `0 8-17 * * 0-4` | Dispatcher tick cron — keep inside work hours |
|
|
20
|
+
| `tickModel` | `haiku` | Model for the dispatcher tick — keeps ticks on a cheap model |
|
|
21
|
+
| `maxSelfWakesPerDay` | `4` | Max agent-booked `self-wake-*` continuations per day |
|
|
22
|
+
| `workBlockCron` | `0 12 * * 0-4` | Fallback work-block cron (schedule ships disabled) |
|
|
23
|
+
| `okrSource` | `okrs/q3-2026-draft.md` | Data-relative OKR doc anchoring the priority function |
|
|
24
|
+
| `channel` | `#agf-dev` | Primary comms channel once past pilot |
|
|
25
|
+
| `ownerName` | `Elya` | Human owner all pilot-mode comms route to |
|
|
26
|
+
| `pilotMode` | `true` | `true` = no team tagging, everything to the owner; `false` = channel-first threaded comms |
|
|
27
|
+
|
|
28
|
+
Changing config re-renders the skill and schedules (`PUT /api/modules/routine/config`).
|
|
29
|
+
|
|
30
|
+
Note: adopted/managed schedules become `scope: system` — their sessions are visible to all whitelisted users (team-transparency doctrine).
|
|
31
|
+
|
|
32
|
+
## Offspring
|
|
33
|
+
|
|
34
|
+
Agent-booked continuations matching `self-wake-*` are treated as the module's offspring: disabling or uninstalling the module disables them (never deletes) so they can't fire into a missing skill.
|
|
35
|
+
|
|
36
|
+
## Uninstall semantics
|
|
37
|
+
|
|
38
|
+
Rendered skill and the two module schedules are removed. **State stays**: `workspace/agenda.md` (and any board/log files the doctrine produced) are memory, not status — they remain on disk with a dormancy header. Only `data/modules/state.json` answers whether the module is on.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "routine",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Daily operating contract — cadence (dispatcher ticks + work blocks), OKR-anchored priorities, autonomy tiers, comms policy, and an agenda seed.",
|
|
5
|
+
"configSchema": {
|
|
6
|
+
"workingDays": { "type": "string", "default": "Sun–Thu", "description": "Working days, prose (shown in the skill)" },
|
|
7
|
+
"workHours": { "type": "string", "default": "08:00–18:00", "description": "Working hours, prose (shown in the skill)" },
|
|
8
|
+
"tz": { "type": "string", "default": "Asia/Jerusalem", "description": "IANA timezone for schedules and hours" },
|
|
9
|
+
"tickCron": { "type": "string", "default": "0 8-17 * * 0-4", "description": "Cron for the hourly dispatcher tick (keep inside work hours)" },
|
|
10
|
+
"tickModel": { "type": "string", "default": "haiku", "description": "Model for the dispatcher tick — keeps ticks on a cheap model (most end in a skip)" },
|
|
11
|
+
"maxSelfWakesPerDay": { "type": "number", "default": 4, "description": "Max agent-booked self-wake-* continuations per day" },
|
|
12
|
+
"workBlockCron": { "type": "string", "default": "0 12 * * 0-4", "description": "Cron for the fallback work block (schedule ships disabled)" },
|
|
13
|
+
"okrSource": { "type": "string", "default": "okrs/q3-2026-draft.md","description": "Data-relative path to the OKR doc anchoring priorities" },
|
|
14
|
+
"channel": { "type": "string", "default": "#agf-dev", "description": "Primary comms channel once past pilot" },
|
|
15
|
+
"ownerName": { "type": "string", "default": "Elya", "description": "The human owner all pilot-mode comms route to" },
|
|
16
|
+
"pilotMode": { "type": "boolean", "default": true, "description": "true = no team tagging, everything routes to the owner; false = channel-first threaded comms" }
|
|
17
|
+
},
|
|
18
|
+
"skills": ["routine.md.tmpl"],
|
|
19
|
+
"schedules": [
|
|
20
|
+
{
|
|
21
|
+
"def": "tick",
|
|
22
|
+
"name": "routine-tick",
|
|
23
|
+
"trigger": { "kind": "cron", "expr": "{{tickCron}}", "tz": "{{tz}}" },
|
|
24
|
+
"task": { "kind": "prompt", "prompt": "Dispatcher tick: load the routine skill (Dispatcher tick rules) and workspace/agenda.md, then follow the tick logic. Most ticks should end in a skip.", "model": "{{tickModel}}" }
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"def": "work-block",
|
|
28
|
+
"name": "routine-work-block",
|
|
29
|
+
"enabled": false,
|
|
30
|
+
"trigger": { "kind": "cron", "expr": "{{workBlockCron}}", "tz": "{{tz}}" },
|
|
31
|
+
"task": { "kind": "prompt", "prompt": "Load the routine skill and execute one work block per its Cadence section." }
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"seeds": ["workspace/agenda.md"],
|
|
35
|
+
"offspring": { "schedules": "self-wake-*" }
|
|
36
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: My daily operating contract — cadence, priorities (OKR-anchored), autonomy tiers, comms policy. Loaded by the dispatcher tick and work-block schedules; consult it before any proactive move.
|
|
3
|
+
triggers:
|
|
4
|
+
- routine
|
|
5
|
+
- dispatcher tick
|
|
6
|
+
- work block
|
|
7
|
+
- daily cadence
|
|
8
|
+
- what should I work on
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
My standing contract for proactive work. Config: `pilotMode={{pilotMode}}`, owner {{ownerName}}, channel {{channel}}.
|
|
12
|
+
|
|
13
|
+
## Working hours
|
|
14
|
+
|
|
15
|
+
{{workingDays}}, roughly {{workHours}} ({{tz}}). Outside these hours: no proactive work, no pings — only respond if directly addressed. Exemption: event-triggered reactions (an incoming webhook, alert, or message that fires a schedule/session) may be handled when they arrive — the hours gate self-initiated work, not reactions.
|
|
16
|
+
|
|
17
|
+
## Priority function
|
|
18
|
+
|
|
19
|
+
When choosing what to pick up, rank by:
|
|
20
|
+
1. **Moves a KR** — anchored in `{{okrSource}}` and the Weekly Log. Tasks tagged `KR:` outrank everything else.
|
|
21
|
+
2. **Urgency** — P0/P1 items next.
|
|
22
|
+
3. **Age** — older items before newer, all else equal.
|
|
23
|
+
|
|
24
|
+
## Cadence
|
|
25
|
+
|
|
26
|
+
- **Pre-daily** (start of day): absorbs the morning sweep — review inboxes/boards, refresh `workspace/agenda.md` (Today/Focus/Queue), pick the day's focus.
|
|
27
|
+
- **Dispatcher tick** (hourly during work hours) — the tick decides, it does not grind:
|
|
28
|
+
- **Skip** if a session is already actively working — most ticks should end in a skip.
|
|
29
|
+
- **Defer to self-wake**: if a `self-wake-*` schedule is already booked for the current thread, skip — the wake owns the continuation.
|
|
30
|
+
- **Wake with intention**: only start work when the agenda names a concrete next step; wake into that step, not into "look around".
|
|
31
|
+
- **Escalate when stuck**: the same item blocked across 3 consecutive ticks → escalate per the comms policy instead of ticking on it again.
|
|
32
|
+
- **Post-daily** (end of day): absorbs the EOD digest — summarize what moved, update the agenda's Parked/Blocked, leave breadcrumbs.
|
|
33
|
+
- **Weekly self-audit**: once a week, review the log against `{{okrSource}}` — is the priority function actually being followed?
|
|
34
|
+
|
|
35
|
+
The `routine-work-block` schedule is a superseded fallback (ships disabled); the tick logic above is the live cadence.
|
|
36
|
+
|
|
37
|
+
## Self-scheduling
|
|
38
|
+
|
|
39
|
+
I MAY book my own continuations as one-shot schedules (`once` trigger) named `self-wake-<slug>`. Bounds:
|
|
40
|
+
- tier-a work only — never self-wake into tier b/c actions;
|
|
41
|
+
- working hours only;
|
|
42
|
+
- max {{maxSelfWakesPerDay}} self-wakes per day;
|
|
43
|
+
- each booking notes "why then" in `workspace/agenda.md` (what the wake will do and why that time).
|
|
44
|
+
|
|
45
|
+
## Breadcrumb contract
|
|
46
|
+
|
|
47
|
+
Every pause or handoff ends with a `Next:` line stating the concrete next step. A thread without a `Next:` line is not parked, it is dropped.
|
|
48
|
+
|
|
49
|
+
## Autonomy tiers
|
|
50
|
+
|
|
51
|
+
- **a** — reversible + verifiable: do it, report after.
|
|
52
|
+
- **b** — hard to reverse or externally visible: propose, wait for approval.
|
|
53
|
+
- **c** — irreversible / spend / identity-affecting: never without an explicit go in the current session.
|
|
54
|
+
|
|
55
|
+
The tier is decided by reversibility, not by confidence.
|
|
56
|
+
|
|
57
|
+
## Comms policy
|
|
58
|
+
|
|
59
|
+
Pilot restriction active: **{{pilotMode}}**.
|
|
60
|
+
- When `true`: do NOT tag or ping team members — every outbound update, question, and escalation routes to {{ownerName}} only.
|
|
61
|
+
- When `false`: channel-first — post threaded updates in {{channel}}; tag people only when they own the next action.
|
|
62
|
+
|
|
63
|
+
Signal tiers (either mode): **ping** = needs a human now; **digest** = batched into pre/post-daily summaries; **board** = silent state update on the agenda/board only. Unsure which tier → digest; batch same-class nudges into one line.
|
|
64
|
+
|
|
65
|
+
## Loop-in while uncertain
|
|
66
|
+
|
|
67
|
+
Uncertainty is not a reason to stall silently: keep working what is safe (tier a), and loop in {{ownerName}} on the uncertain part in the same breath — ask while moving, never block-and-vanish.
|
|
68
|
+
|
|
69
|
+
The moment a finding rules out a previously stated theory (mine or a teammate's) on an open P0/P1, surface it to the owner of that item in the same session, unpolished, before chasing the next hypothesis. (Pilot mode: the owner to loop in is {{ownerName}}.)
|
|
70
|
+
|
|
71
|
+
## agenda.md scoping
|
|
72
|
+
|
|
73
|
+
`workspace/agenda.md` is the dispatcher's working memory, NOT the board — `tasks/tasks.md` is the durable record. The agenda points at tasks; it never replaces them.
|
|
74
|
+
- **Read** it only on proactive turns (ticks, pre/post-daily) — a user-initiated turn follows the user, not the agenda.
|
|
75
|
+
- **Write** it on any turn where state changed (new task, decision, block, park).
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: How to add a new skill — create a kebab-case Markdown file in the absolute data/skills/ path with concise system-prompt-style instructions.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
To add a new skill, create a Markdown file in the **absolute path** `<shraga folder>/data/skills/`:
|
|
2
6
|
|
|
3
7
|
1. **File**: Create `<shraga folder>/data/skills/<skill-name>.md` using kebab-case naming (e.g. `code-review.md`, `write-tests.md`)
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create and iterate on self-contained visual HTML artifacts (ad creatives, banners, cards) that render live in the user's browser.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Artifacts — HTML Creative Builder
|
|
2
6
|
|
|
3
7
|
You can create and iterate on visual HTML artifacts (ad creatives, banners, cards, etc.) that render live in the user's browser.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Maintain the communications log (data/comms-log.jsonl) to avoid duplicate or redundant proactive outreach.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Communications Awareness
|
|
2
6
|
|
|
3
7
|
You maintain a communications log to avoid duplicate or redundant **proactive** outreach. Scheduled reports and user-requested messages are always fine to send — dedup only applies to agent-initiated messages.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Author a data-plane module — a declarative folder (module.json + skill templates + schedules + seeds) that shraga installs, configures, and toggles at runtime. Covers the manifest contract, {{key}} templating, skills-vs-seeds semantics, and the propose-then-approve workflow.
|
|
3
|
+
triggers:
|
|
4
|
+
- create a module
|
|
5
|
+
- author a module
|
|
6
|
+
- new module
|
|
7
|
+
- module manifest
|
|
8
|
+
- module.json
|
|
9
|
+
- package a skill as a module
|
|
10
|
+
- data-plane module
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
A **data-plane module** is a declarative folder of skills, schedules, and seed files that shraga installs and reconciles at runtime — no server code. Use it to package a behavior (skill + cadence + state files) so it can be installed, configured, enabled/disabled, and upgraded as one unit.
|
|
14
|
+
|
|
15
|
+
Not a module: `*.ext.ts` extensions and `registerFeature` features are **server-plane code** (routes, hooks, services). If the behavior needs code, it's not a module.
|
|
16
|
+
|
|
17
|
+
## Manifest — `module.json`
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"name": "standup-notes",
|
|
22
|
+
"version": "1.0.0",
|
|
23
|
+
"description": "Collects a daily standup note and keeps a rolling log.",
|
|
24
|
+
"configSchema": {
|
|
25
|
+
"tz": { "type": "string", "default": "UTC", "description": "Timezone" },
|
|
26
|
+
"channel": { "type": "string", "default": "", "description": "Where to post the note" }
|
|
27
|
+
},
|
|
28
|
+
"skills": ["standup-notes.md.tmpl"],
|
|
29
|
+
"schedules": [
|
|
30
|
+
{ "def": "tick", "name": "standup-notes tick",
|
|
31
|
+
"trigger": { "kind": "cron", "expr": "30 9 * * 1-5", "tz": "{{tz}}" },
|
|
32
|
+
"task": { "kind": "prompt", "prompt": "Run the standup-notes skill: collect today's note, post to {{channel}}, append to the log." } }
|
|
33
|
+
],
|
|
34
|
+
"seeds": ["workspace/standup-log.md"],
|
|
35
|
+
"offspring": { "schedules": "standup-followup-*" },
|
|
36
|
+
"defaultSkills": []
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- `configSchema` — flat map of `{type, default, description}`. Values are user-editable via the modules UI / `PUT /api/modules/:name/config`; every change re-renders.
|
|
41
|
+
- `skills` — `.md.tmpl` files rendered into `data/skills/<name>.md` with a `managed-by: <module>@<version>` frontmatter marker.
|
|
42
|
+
- `schedules` — schedule defs keyed by a stable `def` (→ schedule id `mod-<module>-<def>`), using the scheduler's native `trigger`/`task` JSON (same shape as `POST /api/schedules` — see the scheduler skill), with `{{key}}` substitution in string values; created with `managedBy`, survive reboots, stay user-editable (reconcile re-overwrites trigger/task but preserves enabled/runCount). `"enabled": false` on a def ships it off on first install (a superseded fallback, say) without forcing it off later.
|
|
43
|
+
- **Adoption/reconcile replaces `trigger`+`task` WHOLLY from the def** — any hand-customized field on an existing schedule (a `model` override, a tweaked prompt) will be lost unless it becomes a config knob referenced by the def (e.g. `"model": "{{tickModel}}"` in the `routine` builtin). A `model` knob rendered to `""` is omitted from the schedule (no bogus empty model).
|
|
44
|
+
- Adopted/managed schedules become `scope: system` — their sessions are visible to all whitelisted users (intended: team transparency).
|
|
45
|
+
- `seeds` — files created data-root-relative if missing (e.g. `workspace/standup-log.md`).
|
|
46
|
+
- `offspring.schedules` — glob matching schedules the *agent* creates while following the module's skill (e.g. self-booked follow-ups). Disabling the module also disables them.
|
|
47
|
+
- `defaultSkills` — module skill names to add to the always-inject list (use sparingly; most skills are on-demand).
|
|
48
|
+
|
|
49
|
+
## `{{key}}` templating
|
|
50
|
+
|
|
51
|
+
Any string in skill templates and schedule defs may reference a config key as `{{key}}`. Plain substitution only — **no conditionals or logic**, unknown keys warn. Rendering happens at install, config change, and upgrade.
|
|
52
|
+
|
|
53
|
+
Branching on a boolean knob: since there are no template conditionals, interpolate the value into a doctrine line and let prose tell the agent how to behave for each value — e.g. `Pilot restriction active: **{{pilotMode}}**.` followed by "When `true`: … / When `false`: …" (see the `routine` builtin).
|
|
54
|
+
|
|
55
|
+
## Semantics — skills vs seeds vs offspring
|
|
56
|
+
|
|
57
|
+
| Kind | Nature | On reconcile/upgrade | On disable | On uninstall |
|
|
58
|
+
|---|---|---|---|---|
|
|
59
|
+
| skills | code | overwritten from template | deleted | deleted |
|
|
60
|
+
| schedules (declared) | code | upserted (enabled/runCount preserved) | disabled (snapshot restored on enable) | deleted |
|
|
61
|
+
| seeds | state | **never overwritten** | dormancy header stamped, removed on re-enable | **left in place** |
|
|
62
|
+
| offspring schedules | agent-created | untouched | disabled, never deleted | disabled, never deleted |
|
|
63
|
+
|
|
64
|
+
Seeds are memory, not status — never encode "is the module on" in a seed file; only `data/modules/state.json` answers that.
|
|
65
|
+
|
|
66
|
+
## Authoring workflow
|
|
67
|
+
|
|
68
|
+
1. Scaffold in `workspace/modules-dev/<name>/` — `module.json` + templates + seed files. Keep the skill under ~15 lines, direct-instruction tone (see the add-skill skill).
|
|
69
|
+
2. Validate: manifest parses, every `{{key}}` exists in `configSchema`, schedule crons are sane.
|
|
70
|
+
3. Install: `curl -s -X POST -H "x-internal-token: $INTERNAL_API_TOKEN" http://localhost:$PORT/api/modules/install -d '{"path":"workspace/modules-dev/<name>"}' -H 'content-type: application/json'`
|
|
71
|
+
4. Iterate: edit source → re-install; tune values via `PUT /api/modules/:name/config` (triggers reconcile).
|
|
72
|
+
|
|
73
|
+
## Agent rule — propose, never self-install
|
|
74
|
+
|
|
75
|
+
You may **author** a module folder and present it (folder path + one-paragraph summary of what it installs and when it fires) — but a **human installs it**. Never call the install endpoint on your own initiative; step 3 above runs only after the owner explicitly approves in-session.
|
package/defaults/skills/debug.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Systematic debugging workflow — reproduce, hypothesize likely root causes, investigate, isolate the smallest failing case, apply a targeted fix, and verify.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
You are debugging a problem. Follow this systematic approach:
|
|
2
6
|
|
|
3
7
|
1. **Reproduce**: Confirm you understand the exact symptom and when it occurs
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Structural maintenance of the workspace knowledge base — deduplicate, restructure, compress, and cross-reference (run before reconcile).
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Knowledge Gardening
|
|
2
6
|
|
|
3
7
|
You are performing structural maintenance on the workspace knowledge base — deduplicating, restructuring, compressing, and cross-referencing. Think of this as defragmenting the team's shared memory: same information, better organized.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Act as an autonomous GitHub contributor — handle issues/PRs arriving via webhook, honoring trust tiers (autonomous/gated) that gate implement, verify, and merge.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# GitHub Contributor
|
|
2
6
|
|
|
3
7
|
You can act as an autonomous contributor on GitHub repos. Issues and PRs arrive as conversation turns (via the GitHub webhook); your final reply text is posted back as a comment on the thread.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: The built-in contact registry (data/contacts.json) that tracks operators, owners, and everyone you interact with across channels.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
## Contact Registry
|
|
2
6
|
|
|
3
7
|
A built-in contact registry at `data/contacts.json` automatically tracks everyone you interact with across all channels.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: The embedded MCP endpoint (POST /mcp) and uck_ API keys that let external Claude clients access workspace, skills, sessions, schedules, and remote prompts.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# MCP Server & API Keys
|
|
2
6
|
|
|
3
7
|
Shraga exposes an embedded MCP endpoint at `POST /mcp` so external Claude clients (Claude Desktop, Claude Cloud, other MCP consumers) can access workspace, skills, sessions, schedules, and run prompts remotely.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Know which data-plane modules are installed/enabled and manage their lifecycle (enable/disable/configure) via the internal REST API — with the doctrine gate on when you may act vs propose.
|
|
3
|
+
triggers:
|
|
4
|
+
- what modules are enabled
|
|
5
|
+
- what modules are installed
|
|
6
|
+
- module status
|
|
7
|
+
- enable module
|
|
8
|
+
- disable module
|
|
9
|
+
- configure module
|
|
10
|
+
- list modules
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Data-plane modules bundle skills + schedules + seed files, installed and reconciled at runtime. Here's how to know what's on and how to change it.
|
|
14
|
+
|
|
15
|
+
## Knowing what's installed / enabled
|
|
16
|
+
|
|
17
|
+
- **Source of truth**: read `data/modules/state.json` — installed modules with `enabled`, `version`, `config`. Only this file answers "is the module on."
|
|
18
|
+
- **API**: `curl -s -H "x-internal-token: $INTERNAL_API_TOKEN" http://localhost:$PORT/api/modules | jq .` — installed + available built-ins (shipped in `defaults/modules/`, e.g. `routine`; install by `{"name":"routine"}`).
|
|
19
|
+
- **Skill index**: module-rendered skills carry `managed-by: <module>@<version>` frontmatter — if you see it on a skill, a module owns that file.
|
|
20
|
+
|
|
21
|
+
## How lifecycle changes surface
|
|
22
|
+
|
|
23
|
+
- Enable/disable/install/uninstall appends a line to the workspace journal — trust it as a signal, verify in `state.json`.
|
|
24
|
+
- A disabled module's seed files get a dormancy header (`> [<module> disabled <date> — retained as state; no proactive cadence active]`). **Seeds are memory, not status**: an agenda/log file existing — even without the header — does not mean the module is active. Check `state.json` before acting on any cadence a seed implies.
|
|
25
|
+
- Disabling also disables the module's declared schedules *and* offspring schedules you created under its doctrine — don't re-create them while it's off.
|
|
26
|
+
|
|
27
|
+
## Managing modules
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
H='-H "x-internal-token: $INTERNAL_API_TOKEN"' # all calls need this header
|
|
31
|
+
# NOTE: mutations are owner-gated — use a SCOPED internal token (carries the owner session).
|
|
32
|
+
# The legacy global token maps to a non-owner identity and gets 403 on everything but GET.
|
|
33
|
+
POST /api/modules/:name/enable | disable
|
|
34
|
+
PUT /api/modules/:name/config # JSON body validated vs configSchema, then reconciled
|
|
35
|
+
POST /api/modules/install # {"name":"<builtin>"} or {"path":"<folder>"}
|
|
36
|
+
DELETE /api/modules/:name # uninstall — seeds stay
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Doctrine gate:**
|
|
40
|
+
- enable / disable / config change — **tier-b**: propose to the owner and wait, *unless* the owner explicitly asked for this change in the current session (then do it and report).
|
|
41
|
+
- install / uninstall — **always** propose-then-approve. Never self-install, even if you authored the module (see create-module skill).
|
package/defaults/skills/plan.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Produce a concise implementation plan before writing code — goal, approach, steps, files affected, and risks/open questions.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
Before writing any code, produce a concise implementation plan:
|
|
2
6
|
|
|
3
7
|
1. **Goal**: One sentence summary of what we're building
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Workspace knowledge reconciliation — audit what the team knows, learn from recent conversations, and keep the knowledge base clean and current (run garden first).
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Knowledge Reconciliation
|
|
2
6
|
|
|
3
7
|
You are performing a workspace knowledge reconciliation — auditing what the team knows, learning from recent conversations, and keeping the knowledge base clean and current. Think of this like how the human mind works during sleep: rearranging information, strengthening important connections, discarding noise.
|
|
@@ -156,13 +156,15 @@ For **vendor webhooks** that can't send shraga auth (Stripe, GitHub, …), add a
|
|
|
156
156
|
|
|
157
157
|
The system emits these onto the bus automatically — use them as the `source` of an event trigger to react to the agent's own lifecycle:
|
|
158
158
|
|
|
159
|
-
- **`schedule.finished`** — fired when any time/manual schedule run completes. Payload: `{ scheduleId, name, status, sessionId, error? }`. `status` is `ok` | `error` | `aborted`. Chain automations off it, e.g.:
|
|
159
|
+
- **`schedule.finished`** — fired when any time/manual schedule run completes. Payload: `{ scheduleId, name, status, sessionId, sessionUrl?, error? }`. `status` is `ok` | `error` | `aborted`. Chain automations off it, e.g.:
|
|
160
160
|
```json
|
|
161
161
|
{ "trigger": { "kind": "event", "source": "schedule.finished", "match": { "status": "error" } },
|
|
162
162
|
"task": { "kind": "prompt", "prompt": "A scheduled run failed — investigate and post a summary." } }
|
|
163
163
|
```
|
|
164
164
|
Runs that were *themselves* event-triggered do NOT emit `schedule.finished` — this prevents feedback loops, so you can't chain `schedule.finished` → event run → `schedule.finished` infinitely.
|
|
165
165
|
|
|
166
|
+
A `status: error` on a **prompt** run means it failed up to 3 times, not once: a transient failure that produced no output at all (no token, no tool call — so no side effect) is retried with a short backoff before being reported. So `error` is a real failure worth acting on, not a blip. Job (shell command) runs are never retried — a non-zero exit says nothing about what the command already did.
|
|
167
|
+
|
|
166
168
|
## Throttling event triggers
|
|
167
169
|
|
|
168
170
|
Event triggers accept an optional `throttle` that suppresses duplicate fires **before** a run is spawned:
|
|
@@ -180,7 +182,8 @@ The dedup key is built from the named payload fields (dot-paths), string-normali
|
|
|
180
182
|
|
|
181
183
|
1. Enable it (toggle the schedule).
|
|
182
184
|
2. Optionally set `SHRAGA_ALERT_SLACK_EMAIL` (the legacy `UNCLAW_ALERT_SLACK_EMAIL` is still honoured) (else it falls back to the first `data/whitelist.json` entry).
|
|
183
|
-
3.
|
|
185
|
+
3. Set `PUBLIC_ORIGIN` (or `publicOrigin` in the data-dir config) so the alert can link to the failed run's session. It is the only source of a publicly-reachable origin — a scheduled run has no request to derive one from. Unset, the `sessionUrl` payload field is absent and the alert omits the link rather than emitting an unreachable `localhost` one.
|
|
186
|
+
4. Optionally edit its `task.prompt` to add deployment specifics (recipients, runbook links, severity rules) — your edits to a builtin's prompt and `enabled` flag survive upgrades; only `name`/`scope`/`createdBy` reconcile from code. Because `task.prompt` is deliberately *not* reconciled, the alert's session link is supplied through the event payload (`sessionUrl`) instead, so it reaches deployments that already persisted the schedule.
|
|
184
187
|
|
|
185
188
|
## Notes
|
|
186
189
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: You ARE shraga (a multi-user Claude Code web UI) — read, modify, and manage your own source code, deployment, and related repos.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
You ARE shraga — a multi-user Claude Code web UI. You can read, modify, and manage your own source code and other repos.
|
|
2
6
|
|
|
3
7
|
## Identity
|
|
@@ -122,7 +126,7 @@ Two layers cause you to run — know both, and which to reach for:
|
|
|
122
126
|
- **Time**: `cron` / `interval` / `once`.
|
|
123
127
|
- **Event** (`{ kind:'event', source, match? }`) — fires when a matching event hits the event bus. `match` is an AND-filter of payload dot-paths → values. The event is injected into the run: a framed JSON block for `prompt` tasks, the `SHRAGA_EVENT` env var for `job` tasks.
|
|
124
128
|
- Events arrive via `POST /api/events/:source` (auth-gated) or `ctx.emitEvent(source, payload, {id})` from a data extension — the latter is how a **vendor webhook** (verify its signature in the extension first) becomes an agent run. Bus + dispatcher: `src/server/events/`; fire path: `scheduler/engine.ts` `fireEvent()`. Full how-to (create / match / emit): the **scheduler** skill.
|
|
125
|
-
- **Built-in lifecycle source**: the system auto-emits `schedule.finished` (`{ scheduleId, name, status, sessionId, error? }`) when a time/manual run completes — react to your own runs (e.g. `match: { status: "error" }` → notify). Event-triggered runs don't emit it (loop guard). More internal sources can be added with one `emitEvent()` at the milestone.
|
|
129
|
+
- **Built-in lifecycle source**: the system auto-emits `schedule.finished` (`{ scheduleId, name, status, sessionId, sessionUrl?, error? }`) when a time/manual run completes — react to your own runs (e.g. `match: { status: "error" }` → notify). Event-triggered runs don't emit it (loop guard). More internal sources can be added with one `emitEvent()` at the milestone.
|
|
126
130
|
|
|
127
131
|
**SDK hooks (`src/server/hooks.ts`)** — Claude Code's own hook mechanism, wired into your `query()`. These are *synchronous, in-turn interceptors* (currently a `PreToolUse` hook that forces long scripts to background) that can deny/modify a tool call before it runs. Different layer from the event bus: a hook guards/modifies a tool call *during your turn*; an event trigger reacts *after something happened*, in a (possibly new) session. Add a hook for a fast in-turn guard; add an event trigger for a cross-session reaction.
|
|
128
132
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Write comprehensive tests for given code — happy path, edge cases, and error conditions, with mocked dependencies and behavior-focused assertions.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
Write comprehensive tests for the given code. Follow these guidelines:
|
|
2
6
|
|
|
3
7
|
- Cover the happy path, edge cases, and error conditions
|