shraga 0.0.3 → 0.1.1
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 +82 -23
- package/defaults/agents/summarizer.md +16 -0
- package/defaults/agents/trace-extractor.md +84 -0
- package/defaults/bin/claude +45 -0
- package/defaults/bin/claude-revive +17 -0
- package/defaults/extensions/README.md +70 -0
- package/defaults/extensions/selftest.ext.ts +43 -0
- package/defaults/extensions/stripe-webhook.ext.ts +58 -0
- package/defaults/gmail-triage-prompt.md +42 -0
- package/defaults/scripts/README +4 -0
- package/defaults/scripts/agent-once.ts +67 -0
- package/defaults/scripts/backfill-slack-usernames.ts +82 -0
- package/defaults/scripts/notifier-throttle.ts +44 -0
- package/defaults/scripts/summarize-conversations.ts +5 -0
- package/defaults/shraga.config.ts +29 -0
- package/defaults/skills/add-skill.md +14 -0
- package/defaults/skills/artifacts.md +116 -0
- package/defaults/skills/code-review.md +26 -0
- package/defaults/skills/communications.md +54 -0
- package/defaults/skills/context-audit.md +87 -0
- package/defaults/skills/debug.md +10 -0
- package/defaults/skills/garden.md +179 -0
- package/defaults/skills/github-contributor.md +35 -0
- package/defaults/skills/identity.md +30 -0
- package/defaults/skills/mcp-server.md +62 -0
- package/defaults/skills/mcps-sync.md +105 -0
- package/defaults/skills/plan.md +9 -0
- package/defaults/skills/platform.md +177 -0
- package/defaults/skills/reconcile.md +239 -0
- package/defaults/skills/scheduler.md +192 -0
- package/defaults/skills/self-aware.md +136 -0
- package/defaults/skills/shraga-know.md +333 -0
- package/defaults/skills/stripe.md +55 -0
- package/defaults/skills/write-tests.md +10 -0
- package/defaults/skills-defaults.json +1 -0
- package/defaults/system-prompt.md +46 -0
- package/defaults/workspace/context.md +28 -0
- package/defaults/workspace.md +50 -0
- package/defaults/zdotdir/.gitignore +8 -0
- package/defaults/zdotdir/.zlogin +3 -0
- package/defaults/zdotdir/.zprofile +1 -0
- package/defaults/zdotdir/.zshenv +4 -0
- package/defaults/zdotdir/.zshrc +3 -0
- package/dist/client/assets/index-BoHttkMt.js +1940 -0
- package/dist/client/assets/index-DdibEb2O.css +10 -0
- package/dist/client/index.html +22 -0
- package/package.json +59 -14
- package/src/cli.ts +71 -46
- package/src/client/App.tsx +510 -0
- package/src/client/components/ArtifactCard.tsx +26 -0
- package/src/client/components/ArtifactPanel.tsx +138 -0
- package/src/client/components/AuthedImage.tsx +85 -0
- package/src/client/components/AutocompleteTextarea.tsx +149 -0
- package/src/client/components/ChatView.tsx +866 -0
- package/src/client/components/CliAuthConsent.tsx +98 -0
- package/src/client/components/ConfigPanel.tsx +328 -0
- package/src/client/components/ConversationHeader.tsx +156 -0
- package/src/client/components/ConversationPane.tsx +277 -0
- package/src/client/components/LoginPage.tsx +81 -0
- package/src/client/components/MachineStats.tsx +77 -0
- package/src/client/components/McpManager.tsx +209 -0
- package/src/client/components/MessageInput.tsx +263 -0
- package/src/client/components/OAuthConsent.tsx +103 -0
- package/src/client/components/SchedulesManager.tsx +99 -0
- package/src/client/components/Sidebar.tsx +235 -0
- package/src/client/components/SkillsManager.tsx +280 -0
- package/src/client/components/SmartChart.tsx +167 -0
- package/src/client/components/Toast.tsx +54 -0
- package/src/client/components/WorkspaceTree.tsx +313 -0
- package/src/client/components/ZoomableImage.tsx +123 -0
- package/src/client/components/artifact-presets.ts +10 -0
- package/src/client/components/schedules/ScheduleEditor.tsx +264 -0
- package/src/client/components/schedules/ScheduleList.tsx +271 -0
- package/src/client/components/ui/accordion.tsx +50 -0
- package/src/client/components/ui/button.tsx +43 -0
- package/src/client/components/ui/dialog.tsx +82 -0
- package/src/client/components/ui/input.tsx +19 -0
- package/src/client/components/ui/scroll-area.tsx +39 -0
- package/src/client/components/ui/textarea.tsx +18 -0
- package/src/client/globals.css +51 -0
- package/src/client/hooks/useAgentSocket.ts +79 -0
- package/src/client/hooks/useArtifacts.ts +89 -0
- package/src/client/hooks/useAuth.ts +127 -0
- package/src/client/hooks/useConversation.ts +412 -0
- package/src/client/hooks/useDarkMode.ts +57 -0
- package/src/client/hooks/useIsMobile.ts +23 -0
- package/src/client/hooks/usePush.ts +127 -0
- package/src/client/hooks/useSchedules.ts +73 -0
- package/src/client/hooks/useUnread.ts +238 -0
- package/src/client/lib/desktopAttention.ts +75 -0
- package/src/client/lib/firebase.ts +32 -0
- package/src/client/lib/googleAuthNative.ts +94 -0
- package/src/client/lib/native.ts +43 -0
- package/src/client/lib/schedule-types.ts +34 -0
- package/src/client/lib/sessionApi.ts +58 -0
- package/src/client/lib/slots.tsx +79 -0
- package/src/client/lib/storage.ts +39 -0
- package/src/client/lib/utils.ts +26 -0
- package/src/client/lib/workspaceContext.tsx +54 -0
- package/src/client/lib/ws.ts +203 -0
- package/src/client/main.tsx +14 -0
- package/src/mcp-stdio-bridge.ts +70 -0
- package/src/scripts/summarize-conversations.ts +5 -0
- package/src/scripts/typecheck.ts +43 -0
- package/src/server/agents.ts +54 -0
- package/src/server/api-keys.ts +63 -0
- package/src/server/artifacts/artifacts.export.ts +85 -0
- package/src/server/artifacts/artifacts.handler.ts +93 -0
- package/src/server/artifacts/artifacts.routes.ts +43 -0
- package/src/server/artifacts/artifacts.service.ts +100 -0
- package/src/server/artifacts/artifacts.types.ts +31 -0
- package/src/server/auth.ts +262 -0
- package/src/server/claude.ts +394 -0
- package/src/server/commands.ts +21 -0
- package/src/server/contacts.ts +177 -0
- package/src/server/conversation-summarizer.ts +204 -0
- package/src/server/data-sync.ts +664 -0
- package/src/server/directives.ts +91 -0
- package/src/server/engine/claude-code.ts +514 -0
- package/src/server/engine/index.ts +41 -0
- package/src/server/engine/registry.ts +21 -0
- package/src/server/engine/shared.ts +47 -0
- package/src/server/engine/types.ts +48 -0
- package/src/server/env-resolve.ts +71 -0
- package/src/server/env-sanitize.ts +9 -0
- package/src/server/events/bus.ts +29 -0
- package/src/server/events/dispatcher.ts +48 -0
- package/src/server/events/routes.ts +19 -0
- package/src/server/events/types.ts +9 -0
- package/src/server/extensions.ts +101 -0
- package/src/server/features.ts +109 -0
- package/src/server/file-inject.ts +45 -0
- package/src/server/hooks.ts +142 -0
- package/src/server/idempotency.ts +25 -0
- package/src/server/index.ts +1715 -0
- package/src/server/integrity-audit.ts +132 -0
- package/src/server/mcp-catalog.ts +70 -0
- package/src/server/mcp-oauth.ts +198 -0
- package/src/server/mcp-progress.ts +45 -0
- package/src/server/mcp-server.ts +456 -0
- package/src/server/mcp-sidecar.ts +87 -0
- package/src/server/mcp.ts +291 -0
- package/src/server/model-aliases.ts +76 -0
- package/src/server/paths.ts +24 -0
- package/src/server/polls.ts +175 -0
- package/src/server/push/apns.ts +113 -0
- package/src/server/push/fcm.ts +108 -0
- package/src/server/push/push.ts +66 -0
- package/src/server/push/store.ts +84 -0
- package/src/server/push/triggers.ts +99 -0
- package/src/server/scheduler/builtins.ts +157 -0
- package/src/server/scheduler/engine.ts +432 -0
- package/src/server/scheduler/index.ts +4 -0
- package/src/server/scheduler/runner.ts +334 -0
- package/src/server/scheduler/storage.ts +98 -0
- package/src/server/scheduler/timing.ts +70 -0
- package/src/server/scheduler/types.ts +62 -0
- package/src/server/sdk-utils.ts +45 -0
- package/src/server/seed.ts +174 -0
- package/src/server/session-bus.ts +18 -0
- package/src/server/sessions.ts +559 -0
- package/src/server/shraga-config.ts +167 -0
- package/src/server/skills.ts +372 -0
- package/src/server/slack/api.ts +37 -0
- package/src/server/slack/bot.ts +391 -0
- package/src/server/slack/context-cache.ts +42 -0
- package/src/server/slack/feature.ts +59 -0
- package/src/server/slack/mention-rewrite.ts +59 -0
- package/src/server/slack/oauth.ts +102 -0
- package/src/server/slack/questions.ts +112 -0
- package/src/server/slack/sessions.ts +139 -0
- package/src/server/stats.ts +106 -0
- package/src/server/summarize.ts +11 -0
- package/src/server/turn-context.ts +61 -0
- package/src/server/unclaw-config.ts +19 -0
- package/src/server/unread.ts +79 -0
- package/src/server/user-context.ts +33 -0
- package/src/server/vendor-sync.ts +52 -0
- package/src/server/voice-provider.ts +74 -0
- package/src/server/workspace.ts +249 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* One-shot backfill: resolve missing userName on DM slack sessions.
|
|
4
|
+
* Reads slack-sessions.json to find DM channels, calls Slack API to get the user.
|
|
5
|
+
* Run: bun run scripts/backfill-slack-usernames.ts
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { dataPath } from '../src/server/paths.ts';
|
|
9
|
+
|
|
10
|
+
const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN || '';
|
|
11
|
+
if (!SLACK_BOT_TOKEN) { console.error('SLACK_BOT_TOKEN required'); process.exit(1); }
|
|
12
|
+
|
|
13
|
+
async function slackGet(method: string, params: Record<string, string>): Promise<any> {
|
|
14
|
+
const url = new URL(`https://slack.com/api/${method}`);
|
|
15
|
+
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
|
|
16
|
+
const res = await fetch(url, { headers: { Authorization: `Bearer ${SLACK_BOT_TOKEN}` } });
|
|
17
|
+
return res.json();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function getUserName(userId: string): Promise<string | null> {
|
|
21
|
+
const data = await slackGet('users.info', { user: userId });
|
|
22
|
+
return data.user?.profile?.display_name || data.user?.real_name || data.user?.name || null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const sessionsPath = dataPath('sessions.json');
|
|
26
|
+
const slackMappingPath = dataPath('slack-sessions.json');
|
|
27
|
+
|
|
28
|
+
const sessions = JSON.parse(readFileSync(sessionsPath, 'utf-8'));
|
|
29
|
+
const slackMapping: Record<string, { sessionId: string; channel: string }> = JSON.parse(readFileSync(slackMappingPath, 'utf-8'));
|
|
30
|
+
|
|
31
|
+
const dmChannelToSession = new Map<string, any>();
|
|
32
|
+
for (const s of sessions) {
|
|
33
|
+
if (s.slackContext?.type === 'dm' && !s.slackContext.userName) {
|
|
34
|
+
for (const [, v] of Object.entries(slackMapping)) {
|
|
35
|
+
const entry = v as { sessionId: string; channel: string };
|
|
36
|
+
if (entry.sessionId === s.sessionId && entry.channel.startsWith('D')) {
|
|
37
|
+
dmChannelToSession.set(entry.channel, s);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Also find slack- sessions with no slackContext at all (legacy)
|
|
45
|
+
for (const s of sessions) {
|
|
46
|
+
if (s.sessionId.startsWith('slack-') && !s.slackContext) {
|
|
47
|
+
for (const [, v] of Object.entries(slackMapping)) {
|
|
48
|
+
const entry = v as { sessionId: string; channel: string };
|
|
49
|
+
if (entry.sessionId === s.sessionId) {
|
|
50
|
+
if (entry.channel.startsWith('D')) {
|
|
51
|
+
s.slackContext = { type: 'dm' };
|
|
52
|
+
dmChannelToSession.set(entry.channel, s);
|
|
53
|
+
} else {
|
|
54
|
+
s.slackContext = { type: 'channel' };
|
|
55
|
+
}
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log(`Found ${dmChannelToSession.size} DM sessions to backfill`);
|
|
63
|
+
|
|
64
|
+
const botAuth = await slackGet('auth.test', {});
|
|
65
|
+
const botUserId = botAuth.user_id;
|
|
66
|
+
|
|
67
|
+
for (const [channel, session] of dmChannelToSession) {
|
|
68
|
+
const history = await slackGet('conversations.history', { channel, limit: '5' });
|
|
69
|
+
if (!history.ok) { console.log(` skip ${channel}: ${history.error}`); continue; }
|
|
70
|
+
|
|
71
|
+
const userMsg = (history.messages || []).find((m: any) => m.user && m.user !== botUserId && !m.bot_id);
|
|
72
|
+
if (!userMsg) { console.log(` skip ${channel}: no user message found`); continue; }
|
|
73
|
+
|
|
74
|
+
const name = await getUserName(userMsg.user);
|
|
75
|
+
if (name) {
|
|
76
|
+
session.slackContext.userName = name;
|
|
77
|
+
console.log(` ${session.sessionId.slice(0, 20)}... → ${name}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
writeFileSync(sessionsPath, JSON.stringify(sessions, null, 2));
|
|
82
|
+
console.log('Done. sessions.json updated.');
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Generic alert throttle — dedups repeated alerts for the same key within a window.
|
|
3
|
+
// Use from any prompt/job/bash task that wants to avoid alert floods (event-trigger
|
|
4
|
+
// schedules can instead use the built-in `trigger.throttle`, which suppresses BEFORE
|
|
5
|
+
// an agent is spawned — see defaults/skills/scheduler.md).
|
|
6
|
+
// Prints exactly one line: `DECISION=alert` or `DECISION=suppress`.
|
|
7
|
+
// Usage: bun run data/scripts/notifier-throttle.ts --job "<name>" --error "<error>" [--window-hours 6]
|
|
8
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
9
|
+
import { dirname, join } from 'node:path';
|
|
10
|
+
|
|
11
|
+
function arg(name: string): string | undefined {
|
|
12
|
+
const i = process.argv.indexOf(`--${name}`);
|
|
13
|
+
return i >= 0 ? process.argv[i + 1] : undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const job = (arg('job') || 'unknown').trim();
|
|
17
|
+
const error = (arg('error') || '').trim();
|
|
18
|
+
const windowMs = Number(arg('window-hours') || 6) * 3600_000;
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
|
|
21
|
+
// Signature: collapse whitespace, drop digits (timestamps/ids vary run-to-run),
|
|
22
|
+
// lowercase, cap length — so "token expired on <date A>" == "<date B>".
|
|
23
|
+
const sig = error.toLowerCase().replace(/\d+/g, '#').replace(/\s+/g, ' ').trim().slice(0, 120);
|
|
24
|
+
const key = `${job}::${sig}`;
|
|
25
|
+
|
|
26
|
+
const STATE = join(process.env.DATA_DIR || join(process.cwd(), 'data'), 'state', 'notifier-throttle.json');
|
|
27
|
+
let state: Record<string, number> = {};
|
|
28
|
+
try { if (existsSync(STATE)) state = JSON.parse(readFileSync(STATE, 'utf8')); }
|
|
29
|
+
catch (e) { console.error('[notifier-throttle] read failed, starting fresh:', (e as Error).message); }
|
|
30
|
+
|
|
31
|
+
// Self-maintaining prune: drop entries older than the window.
|
|
32
|
+
for (const k of Object.keys(state)) if (now - state[k] > windowMs) delete state[k];
|
|
33
|
+
|
|
34
|
+
const last = state[key];
|
|
35
|
+
const suppress = last !== undefined && now - last < windowMs;
|
|
36
|
+
|
|
37
|
+
if (!suppress) {
|
|
38
|
+
state[key] = now;
|
|
39
|
+
try { mkdirSync(dirname(STATE), { recursive: true }); writeFileSync(STATE, JSON.stringify(state, null, 2)); }
|
|
40
|
+
catch (e) { console.error('[notifier-throttle] write failed:', (e as Error).message); }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log(`DECISION=${suppress ? 'suppress' : 'alert'}`);
|
|
44
|
+
process.exit(0);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { summarizeConversations } from '../src/server/conversation-summarizer.ts';
|
|
2
|
+
|
|
3
|
+
const force = process.argv.includes('--force');
|
|
4
|
+
const result = await summarizeConversations({ force });
|
|
5
|
+
console.log(`Done: ${result.summarized} summarized, ${result.skipped} skipped, ${result.errors} errors`);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shraga deployment config — org-specific, lives in data/shraga.config.ts (gitignored).
|
|
3
|
+
*
|
|
4
|
+
* Global MCP servers are declared here — they apply to all users (read-only in UI).
|
|
5
|
+
* Users can add their own MCPs via the UI (stored per-user in mcps/{uid}.json).
|
|
6
|
+
*
|
|
7
|
+
* Two entry styles:
|
|
8
|
+
* - Shorthand (vendor dir): { env: ['KEY1'] } → auto-resolves vendor/{name}/src/mcp/cli.ts
|
|
9
|
+
* - Full: { command: 'bunx', args: ['@stripe/mcp'], env: { STRIPE_KEY: '' } }
|
|
10
|
+
*
|
|
11
|
+
* Env values resolve from process.env at startup (via .env or system env).
|
|
12
|
+
*/
|
|
13
|
+
import { defineConfig } from '../src/server/shraga-config.ts';
|
|
14
|
+
|
|
15
|
+
// Agent settings (model, engine, thinking, effort, etc.) live in agent-config.json — UI-editable and the single source of truth.
|
|
16
|
+
export default defineConfig({
|
|
17
|
+
mcps: {
|
|
18
|
+
// Shorthand — vendor dir convention (vendor/mcp-example/src/mcp/cli.ts):
|
|
19
|
+
// 'mcp-example': {
|
|
20
|
+
// env: ['EXAMPLE_API_KEY', 'EXAMPLE_MODE'],
|
|
21
|
+
// },
|
|
22
|
+
|
|
23
|
+
// Full — explicit command/args:
|
|
24
|
+
// 'mixpanel': {
|
|
25
|
+
// command: 'bunx',
|
|
26
|
+
// args: ['mcp-remote', 'https://mcp.mixpanel.com/mcp', '--allow-http'],
|
|
27
|
+
// },
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
To add a new skill, create a Markdown file in the **absolute path** `<shraga folder>/data/skills/`:
|
|
2
|
+
|
|
3
|
+
1. **File**: Create `<shraga folder>/data/skills/<skill-name>.md` using kebab-case naming (e.g. `code-review.md`, `write-tests.md`)
|
|
4
|
+
- ⚠️ Do NOT use workspace-relative paths like `data/skills/` — they won't be picked up by the app
|
|
5
|
+
- ⚠️ Do NOT use `.claude/skills/<name>/SKILL.md` — that structure is ignored
|
|
6
|
+
2. **Content**: Write a concise system-prompt-style instruction that tells the agent *how* to perform the skill. Keep it short — ideally under 15 lines
|
|
7
|
+
3. **Structure tips**:
|
|
8
|
+
- Start with a one-line summary of what the skill does
|
|
9
|
+
- Use bullet points or numbered steps for the procedure
|
|
10
|
+
- Include guidelines, constraints, or best practices the agent should follow
|
|
11
|
+
- End with any follow-up actions (e.g. "explain what you did")
|
|
12
|
+
4. **Tone**: Write as direct instructions to the agent ("Do X", "Follow Y"), not as documentation for a human reader
|
|
13
|
+
|
|
14
|
+
Reference existing skills in `<shraga folder>/data/skills/` for examples of the expected format and level of detail.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Artifacts — HTML Creative Builder
|
|
2
|
+
|
|
3
|
+
You can create and iterate on visual HTML artifacts (ad creatives, banners, cards, etc.) that render live in the user's browser.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
Write a self-contained HTML file using the `Write` tool. Include an artifact metadata comment as the **first line**:
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<!-- artifact: {"title": "Summer Sale Banner", "dimensions": [1080, 1080]} -->
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The system detects this comment, registers the artifact, and shows it in a live preview panel.
|
|
14
|
+
|
|
15
|
+
## To Update an Existing Artifact
|
|
16
|
+
|
|
17
|
+
**Full rewrite** — use `Write` with the artifact `id` in the metadata:
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<!-- artifact: {"title": "Summer Sale Banner", "dimensions": [1080, 1080], "id": "art_xxx"} -->
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Incremental edit** — use the `Edit` tool on the same file path. The system re-reads the file after edit and refreshes the preview. The `<!-- artifact: ... -->` comment must remain in the file. This is the preferred approach for small changes (tweaking colors, text, spacing).
|
|
24
|
+
|
|
25
|
+
The artifact ID is returned to you after creation. Always include it when doing a full rewrite.
|
|
26
|
+
|
|
27
|
+
## Visual Feedback
|
|
28
|
+
|
|
29
|
+
After creating or updating an artifact, export a screenshot to verify the visual result:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
curl -s -o /tmp/artifact-preview.png -X POST \
|
|
33
|
+
"http://localhost:${PORT}/api/artifacts/${SHRAGA_SESSION_ID}/${ARTIFACT_ID}/export" \
|
|
34
|
+
-H 'Content-Type: application/json' \
|
|
35
|
+
-H "x-internal-token: $INTERNAL_API_TOKEN" \
|
|
36
|
+
-d '{"dimensions": [1080, 1080]}'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- `$PORT`, `$SHRAGA_SESSION_ID`, and `$INTERNAL_API_TOKEN` are already in your environment.
|
|
40
|
+
- Replace `$ARTIFACT_ID` with the actual artifact ID (e.g. `art_mpmgeqrw_o7tn8r`).
|
|
41
|
+
- The `x-internal-token` header is **required** — without it you get `{"error":"Missing token"}`.
|
|
42
|
+
|
|
43
|
+
Then read `/tmp/artifact-preview.png` to see the rendered output. This gives you visual context to self-correct layout issues, color contrast, etc.
|
|
44
|
+
|
|
45
|
+
**Always screenshot after creation** to verify the result before telling the user it's ready.
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
|
|
49
|
+
1. **Self-contained HTML** — everything in one file. No external dependencies except CDN links.
|
|
50
|
+
2. **Always include Tailwind** — add this in `<head>`:
|
|
51
|
+
```html
|
|
52
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
53
|
+
```
|
|
54
|
+
3. **Set exact dimensions** — the HTML `<body>` should match the artifact dimensions. Use:
|
|
55
|
+
```html
|
|
56
|
+
<body class="m-0 p-0 overflow-hidden" style="width: {W}px; height: {H}px;">
|
|
57
|
+
```
|
|
58
|
+
4. **Use web fonts from Google Fonts CDN** when needed.
|
|
59
|
+
5. **Images**: use placeholder services (picsum.photos, placehold.co) or inline SVG/data URIs. Never reference local files.
|
|
60
|
+
6. **File path**: keep it consistent for the same artifact so `Edit` works. Default to the user's folder: `{WORKSPACE_DIR}/users/{SHRAGA_USER_UID}/artifacts/{title-slug}.html`. To make an artifact visible to all users, use the shared root: `{WORKSPACE_DIR}/artifacts/{title-slug}.html` — only do this when explicitly asked.
|
|
61
|
+
|
|
62
|
+
## Dimension Presets
|
|
63
|
+
|
|
64
|
+
| Preset | Dimensions | Use Case |
|
|
65
|
+
|--------|-----------|----------|
|
|
66
|
+
| fb-feed | 1080×1080 | Facebook/Instagram feed post |
|
|
67
|
+
| fb-story | 1080×1920 | Facebook/Instagram story |
|
|
68
|
+
| fb-landscape | 1200×628 | Facebook link ad |
|
|
69
|
+
| ig-square | 1080×1080 | Instagram square post |
|
|
70
|
+
| ig-landscape | 1080×566 | Instagram landscape |
|
|
71
|
+
| banner-leaderboard | 728×90 | Website banner |
|
|
72
|
+
| banner-medium | 300×250 | Medium rectangle |
|
|
73
|
+
|
|
74
|
+
## Template
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<!-- artifact: {"title": "My Creative", "dimensions": [1080, 1080]} -->
|
|
78
|
+
<!DOCTYPE html>
|
|
79
|
+
<html>
|
|
80
|
+
<head>
|
|
81
|
+
<meta charset="utf-8">
|
|
82
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
83
|
+
<style>
|
|
84
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
|
|
85
|
+
body { font-family: 'Inter', sans-serif; }
|
|
86
|
+
</style>
|
|
87
|
+
</head>
|
|
88
|
+
<body class="m-0 p-0 overflow-hidden" style="width: 1080px; height: 1080px;">
|
|
89
|
+
<!-- Your creative content here -->
|
|
90
|
+
</body>
|
|
91
|
+
</html>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Export
|
|
95
|
+
|
|
96
|
+
Artifacts can be exported to PNG via `POST /api/artifacts/$SHRAGA_SESSION_ID/$ARTIFACT_ID/export` (with `x-internal-token: $INTERNAL_API_TOKEN` header). The export uses Puppeteer server-side at the exact dimensions specified.
|
|
97
|
+
|
|
98
|
+
## Iteration Flow
|
|
99
|
+
|
|
100
|
+
1. Create the initial artifact with `Write`
|
|
101
|
+
2. Screenshot it to verify the visual result
|
|
102
|
+
3. Wait for user feedback
|
|
103
|
+
4. Apply changes with `Edit` (preferred) or `Write` (full rewrite)
|
|
104
|
+
5. Screenshot again to verify
|
|
105
|
+
6. Repeat until approved
|
|
106
|
+
7. Export to PNG when ready
|
|
107
|
+
|
|
108
|
+
## Tips for Ad Creatives
|
|
109
|
+
|
|
110
|
+
- Use bold, high-contrast text — it must be readable at small sizes
|
|
111
|
+
- Keep copy short: headline (5-7 words max), subtext (1 line)
|
|
112
|
+
- Strong CTA button with contrasting color
|
|
113
|
+
- Use brand colors if provided
|
|
114
|
+
- Leave breathing room — don't fill every pixel
|
|
115
|
+
- Test with both light and dark backgrounds
|
|
116
|
+
- For FB ads: text overlay should be <20% of image area
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Thorough code review of a file/diff/PR — correctness, security, performance, style; output as Issues/Suggestions/Nits.
|
|
3
|
+
triggers:
|
|
4
|
+
- review this code
|
|
5
|
+
- code review
|
|
6
|
+
- review this diff
|
|
7
|
+
- review the PR
|
|
8
|
+
- review my changes
|
|
9
|
+
- check for bugs
|
|
10
|
+
- security review
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are performing a thorough code review. For each file or diff provided:
|
|
14
|
+
|
|
15
|
+
1. Check for correctness, edge cases, and potential bugs
|
|
16
|
+
2. Identify security issues (injections, auth bypasses, data exposure)
|
|
17
|
+
3. Flag performance concerns (N+1 queries, unnecessary re-renders, blocking calls)
|
|
18
|
+
4. Note style inconsistencies vs the surrounding codebase
|
|
19
|
+
5. Suggest improvements — be specific, reference line numbers when possible
|
|
20
|
+
|
|
21
|
+
Format your review as:
|
|
22
|
+
- **Issues** (must fix): critical bugs or security problems
|
|
23
|
+
- **Suggestions** (should fix): quality improvements
|
|
24
|
+
- **Nits** (optional): minor style or naming tweaks
|
|
25
|
+
|
|
26
|
+
Be concise. Skip praise. Focus on actionable feedback.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Communications Awareness
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## Communications Log
|
|
6
|
+
|
|
7
|
+
File: `data/comms-log.jsonl` — append-only JSONL, one entry per outbound message.
|
|
8
|
+
|
|
9
|
+
### Before sending a PROACTIVE message
|
|
10
|
+
|
|
11
|
+
Dedup applies only when **you** decide to reach out (not when fulfilling a user request or running a scheduled job).
|
|
12
|
+
|
|
13
|
+
1. **Read the comms log** — `Read data/comms-log.jsonl` (tail last 50-100 lines if large). If the file exceeds 500 lines, only read the last 100.
|
|
14
|
+
2. **Check for recent similar outreach** — same recipient + similar topic within the last 24h = skip or significantly alter the message
|
|
15
|
+
3. **For Slack** — the mcp-slack skill already requires reading channel history before posting (rule #6). That check + this log together cover both same-session and cross-session duplicates.
|
|
16
|
+
|
|
17
|
+
### What counts as a duplicate (proactive only)
|
|
18
|
+
|
|
19
|
+
- Same recipient + same topic/intent within 24h → **skip entirely**
|
|
20
|
+
- Same recipient + related topic within 24h → **reference the prior message** instead of repeating context
|
|
21
|
+
- Same channel + same information within 48h → **skip or reply in thread** to the original
|
|
22
|
+
|
|
23
|
+
### After sending a message
|
|
24
|
+
|
|
25
|
+
Append one line to `data/comms-log.jsonl`:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{"ts":"2026-05-20T10:30:00Z","channel":"#general","channelId":"C123","recipient":"@alice","via":"slack","trigger":"proactive","summary":"Asked about Q1 report status"}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Fields:
|
|
32
|
+
- **ts** — ISO timestamp
|
|
33
|
+
- **channel** — human-readable channel/thread name
|
|
34
|
+
- **channelId** — Slack channel ID (or email address for email, or E.164 phone number for phone/sms)
|
|
35
|
+
- **recipient** — who the message is directed at (can be "channel" for broadcast)
|
|
36
|
+
- **via** — `slack` | `slack-dm` | `email` | `phone` | `sms` (phone/sms via mcp-twilio)
|
|
37
|
+
- **trigger** — `proactive` (agent-initiated), `scheduled` (cron/scheduled job), or `requested` (user asked for it). **Dedup only applies to `proactive`.**
|
|
38
|
+
- **summary** — one-line summary of what was communicated (not the full message)
|
|
39
|
+
|
|
40
|
+
### Housekeeping
|
|
41
|
+
|
|
42
|
+
The log is append-only and can grow. When it exceeds ~500 lines, trim entries older than 7 days — recent history is what matters for dedup.
|
|
43
|
+
|
|
44
|
+
### Rules (proactive messages)
|
|
45
|
+
|
|
46
|
+
- **Never send the same information twice** to the same person/channel within 24h
|
|
47
|
+
- **Never nag** — if you've already asked someone for something and they haven't responded, don't ask again the same day
|
|
48
|
+
- **Consolidate** — if you have multiple things to tell the same person, batch them into one message
|
|
49
|
+
- **Phone calls and SMS are real-world interruptions** — only place a proactive call/SMS (mcp-twilio) when explicitly asked or for a genuine, time-sensitive reason. Never cold-call or text someone you weren't told to contact, and never dial multiple people without being asked.
|
|
50
|
+
|
|
51
|
+
### General
|
|
52
|
+
|
|
53
|
+
- **Always log** — append to the comms log after every outbound message, regardless of trigger type
|
|
54
|
+
- **Be self-aware** — read the log at the start of any task that involves communication to understand your recent activity
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-audit
|
|
3
|
+
description: "Investigate agent context path issues — trace what's hot-loaded vs cold-loaded, find knowledge gaps, test fixes via API replay. Use when an agent session shows wrong behavior due to missing context."
|
|
4
|
+
argument-hint: "[session URL or description of the failure]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Context Audit
|
|
8
|
+
|
|
9
|
+
Diagnose *why* the agent didn't know something it should have, and fix the right layer.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- Agent gave a wrong/confused answer despite the knowledge existing somewhere
|
|
14
|
+
- A skill or rule was ignored — need to determine if it was even loaded
|
|
15
|
+
- After adding new knowledge, to verify it reaches the agent at the right time
|
|
16
|
+
- Reviewing a prod session for context path failures
|
|
17
|
+
|
|
18
|
+
## Shraga Context Architecture
|
|
19
|
+
|
|
20
|
+
### Hot Path (always injected, every prompt)
|
|
21
|
+
- `data/skills/{name}.md` where name is in `skills-defaults.json` — personality, identity, self-aware, pr-review
|
|
22
|
+
- `<current_user>` block (uid, email, display name)
|
|
23
|
+
- `<known_contacts>` from `data/contacts.json`
|
|
24
|
+
- Workspace tree listing + `data/workspace/context.md` (full, uncapped)
|
|
25
|
+
- User's `data/workspace/users/{uid}/user-context.md` (capped ~3000 chars)
|
|
26
|
+
- MCP skill hint lines (name + resource URI, one line each)
|
|
27
|
+
- Trigger-matched skills (via `matchTriggeredSkillNames` — prompt text matched against `triggers:` frontmatter; sticky per session — once matched, re-injected on every later turn via `SessionMeta.triggeredSkills`)
|
|
28
|
+
- Skill index block (names + descriptions of all skills)
|
|
29
|
+
|
|
30
|
+
### Cold Path (agent must explicitly Read or be triggered)
|
|
31
|
+
- Non-default skills in `data/skills/` — loaded via trigger match, @mention, or manual Read
|
|
32
|
+
- `data/workspace/knowledge/*.md` — domain deep-dives
|
|
33
|
+
- Full MCP skill docs (`skill://name/workflow` resources)
|
|
34
|
+
- Workspace files beyond context.md
|
|
35
|
+
|
|
36
|
+
### Trigger Bridge (cold skill, hot injection)
|
|
37
|
+
Skills with `triggers:` frontmatter get auto-injected when the user's prompt text matches any trigger string. This bridges hot/cold — the skill is cold by default but becomes hot when relevant.
|
|
38
|
+
|
|
39
|
+
## Audit Process
|
|
40
|
+
|
|
41
|
+
### 1. Reproduce the failure
|
|
42
|
+
Read the session messages. Identify the exact moment the agent went wrong. Note:
|
|
43
|
+
- What did the user ask?
|
|
44
|
+
- What did the agent do instead?
|
|
45
|
+
- What knowledge would have prevented the mistake?
|
|
46
|
+
|
|
47
|
+
### 2. Trace the context path
|
|
48
|
+
For the missing knowledge, determine:
|
|
49
|
+
- **Does it exist anywhere?** (skill, workspace file, knowledge file, context.md)
|
|
50
|
+
- **Is it hot or cold?** Check `skills-defaults.json`, trigger frontmatter, workspace injection
|
|
51
|
+
- **If cold, should it have been triggered?** Check if user prompt text matches any trigger
|
|
52
|
+
- **If triggered, did injection fire?** Check server logs for `[skills] Trigger matched:`
|
|
53
|
+
|
|
54
|
+
### 3. Identify the gap type
|
|
55
|
+
|
|
56
|
+
| Gap | Symptom | Fix Layer |
|
|
57
|
+
|-----|---------|-----------|
|
|
58
|
+
| Knowledge doesn't exist | Agent can't know it | Add to appropriate file (skill, context.md, knowledge/) |
|
|
59
|
+
| Knowledge exists but is cold | Agent didn't load it | Add triggers to skill frontmatter, or move to hot path |
|
|
60
|
+
| Knowledge is hot but ignored | Agent saw it, acted wrong | Strengthen wording, resolve contradictions, test with different models |
|
|
61
|
+
| Wrong mental model | Agent misinterpreted the request | Add disambiguation rules to relevant skill |
|
|
62
|
+
| Seed overwrites org data | Restart wipes customizations | Remove from `defaults/skills/` (org-only skills shouldn't have a defaults counterpart) |
|
|
63
|
+
|
|
64
|
+
### 4. Apply fixes at the right layer
|
|
65
|
+
- **Hot path** (personality.md, context.md): Generic behavioral rules, team/product basics
|
|
66
|
+
- **Cold skill with triggers**: Domain-specific tool guidance (Slack, Firebase, Stripe)
|
|
67
|
+
- **Knowledge files**: Deep reference material the agent loads on demand
|
|
68
|
+
- **context.md pointers**: Keep context.md lean — point to cold files for details
|
|
69
|
+
|
|
70
|
+
### 5. Verify via API replay
|
|
71
|
+
Test the fix by replaying the failing prompt through `/api/chat`:
|
|
72
|
+
```bash
|
|
73
|
+
TOKEN=$(cat .tmp/.internal-token)
|
|
74
|
+
curl -s http://localhost:3032/api/chat \
|
|
75
|
+
-H "Content-Type: application/json" \
|
|
76
|
+
-H "x-internal-token: $TOKEN" \
|
|
77
|
+
-d '{"prompt":"<the original failing prompt>","sessionId":"test-context-audit"}'
|
|
78
|
+
```
|
|
79
|
+
Check the response: did the agent now handle it correctly? If not, iterate.
|
|
80
|
+
|
|
81
|
+
## Key Gotchas
|
|
82
|
+
|
|
83
|
+
- **Seed overwrites**: `seedDefaults()` copies `defaults/skills/*.md` → `data/skills/` on every restart. Org-specific skills must NOT exist in `defaults/` or they'll be wiped.
|
|
84
|
+
- **Token rotation**: Dev server `--watch` restarts regenerate `.tmp/.internal-token`. Re-read before each API call.
|
|
85
|
+
- **Model sensitivity**: A fix that works on Opus may not work on Sonnet. Test on the prod model.
|
|
86
|
+
- **Trigger matching is substring**: `" dm "` (with spaces) avoids false positives on words containing "dm". Design triggers carefully.
|
|
87
|
+
- **Hot path budget**: Every hot-loaded skill consumes prompt tokens on every message. Keep hot content lean; use triggers for domain skills.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
You are debugging a problem. Follow this systematic approach:
|
|
2
|
+
|
|
3
|
+
1. **Reproduce**: Confirm you understand the exact symptom and when it occurs
|
|
4
|
+
2. **Hypothesize**: List the 2-3 most likely root causes, ranked by probability
|
|
5
|
+
3. **Investigate**: Read relevant code, logs, and error messages before drawing conclusions
|
|
6
|
+
4. **Isolate**: Narrow down to the smallest failing case
|
|
7
|
+
5. **Fix**: Propose a targeted fix — don't refactor unrelated code
|
|
8
|
+
6. **Verify**: Explain how to confirm the fix works
|
|
9
|
+
|
|
10
|
+
Think out loud. Show your reasoning. If you need more information, ask specific questions rather than guessing.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Knowledge Gardening
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
**Budget: stay under 40 tool calls total.** Subagents handle the heavy reading.
|
|
6
|
+
|
|
7
|
+
**Run garden BEFORE reconcile.** Garden cleans the house (dedup, compress, stale removal), then reconcile furnishes it (new content from conversations). Adding new content to a messy workspace compounds the mess.
|
|
8
|
+
|
|
9
|
+
**Approval goes to owners.** Look up contacts tagged `owner` (i.e. `isOwner: true`) in `<known_contacts>` and send the report to their Slack DMs.
|
|
10
|
+
|
|
11
|
+
## Phase 1: Snapshot & Checkpoint
|
|
12
|
+
|
|
13
|
+
Create a git checkpoint so any changes can be reverted with `cd data && git revert HEAD`.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd data && git add -A && git commit -m "garden: pre-checkpoint $(date +%Y-%m-%d)" --allow-empty
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Read all workspace files to build your mental model:
|
|
20
|
+
- `data/workspace/context.md`
|
|
21
|
+
- `data/workspace/tasks.md`
|
|
22
|
+
- `data/workspace/open-questions.md`
|
|
23
|
+
- All `data/workspace/knowledge/*.md`
|
|
24
|
+
- `ls data/workspace/users/` (just list, don't read all)
|
|
25
|
+
|
|
26
|
+
Note file sizes. Files over 120 lines are split candidates.
|
|
27
|
+
|
|
28
|
+
## Phase 2: Diagnose (parallel subagents)
|
|
29
|
+
|
|
30
|
+
Spawn 3 Explore agents in parallel. Each gets a focused checklist and returns a short structured report.
|
|
31
|
+
|
|
32
|
+
**Agent A — Duplication & cross-ref scan:**
|
|
33
|
+
> Read data/workspace/context.md and every data/workspace/knowledge/*.md file. Report:
|
|
34
|
+
> 1. Content that appears in BOTH context.md AND a knowledge file (quote both)
|
|
35
|
+
> 2. Facts in knowledge/ files not indexed in context.md's knowledge table
|
|
36
|
+
> 3. Cross-references that should exist between knowledge files but don't
|
|
37
|
+
> Format: numbered list, each with file paths and quoted evidence.
|
|
38
|
+
|
|
39
|
+
**Agent B — Staleness & hygiene:**
|
|
40
|
+
> Today's date is {YYYY-MM-DD}. Read data/workspace/context.md, data/workspace/tasks.md, data/workspace/open-questions.md. Report:
|
|
41
|
+
> 1. Dates older than 2 weeks from today (quote the line, note the date)
|
|
42
|
+
> 2. Tasks marked done but still in active lists
|
|
43
|
+
> 3. Questions marked resolved but still in Open section
|
|
44
|
+
> 4. Sprint items that look completed but not moved to a "done" section
|
|
45
|
+
> Format: numbered list with file:line references.
|
|
46
|
+
|
|
47
|
+
**Agent C — Structure & coherence:**
|
|
48
|
+
> Read data/workspace/context.md's knowledge table, then check each listed file exists under data/workspace/knowledge/. Read each knowledge file's first 10 lines. Report:
|
|
49
|
+
> 1. Knowledge table entries pointing to files that don't exist
|
|
50
|
+
> 2. Knowledge files that exist but aren't in the table
|
|
51
|
+
> 3. Files over 120 lines (with line count)
|
|
52
|
+
> 4. Files whose content has drifted from their stated purpose
|
|
53
|
+
> Format: numbered list with file paths and line counts.
|
|
54
|
+
|
|
55
|
+
## Phase 3: Synthesize & Propose
|
|
56
|
+
|
|
57
|
+
Review all 3 agent reports. Pick the **best 2-3 actionable changes** (max 3, fewer is fine). Use this operations vocabulary:
|
|
58
|
+
|
|
59
|
+
| Operation | What | Example |
|
|
60
|
+
|-----------|------|---------|
|
|
61
|
+
| **Dedup** | Same fact in context.md AND knowledge/ | Keep detail in knowledge/, replace context.md copy with pointer |
|
|
62
|
+
| **Split** | File over 120 lines | Break into focused files, update index |
|
|
63
|
+
| **Compress** | context.md section grew too detailed | Move to knowledge/ with pointer |
|
|
64
|
+
| **Stale** | Outdated dates, resolved items still listed | Update or remove |
|
|
65
|
+
| **Cross-ref** | Related files don't link to each other | Add "See also" pointers |
|
|
66
|
+
| **Orphan** | Content in knowledge/ not in context.md index | Add to knowledge table |
|
|
67
|
+
|
|
68
|
+
**Selection criteria** — pick changes that:
|
|
69
|
+
- Reduce duplication (highest value)
|
|
70
|
+
- Improve discoverability (orphans, missing cross-refs)
|
|
71
|
+
- Remove noise (stale items)
|
|
72
|
+
|
|
73
|
+
Skip anything speculative. Only propose what the evidence clearly supports.
|
|
74
|
+
|
|
75
|
+
### Write the report
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
mkdir -p data/workspace/garden-reports
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Write to `data/workspace/garden-reports/{YYYY-MM-DD}.md`:
|
|
82
|
+
|
|
83
|
+
```markdown
|
|
84
|
+
# Garden Report — {date}
|
|
85
|
+
|
|
86
|
+
## Raw Agent Reports
|
|
87
|
+
|
|
88
|
+
### Agent A — Duplication & Cross-ref
|
|
89
|
+
{paste full agent A report verbatim}
|
|
90
|
+
|
|
91
|
+
### Agent B — Staleness & Hygiene
|
|
92
|
+
{paste full agent B report verbatim}
|
|
93
|
+
|
|
94
|
+
### Agent C — Structure & Coherence
|
|
95
|
+
{paste full agent C report verbatim}
|
|
96
|
+
|
|
97
|
+
## Synthesis
|
|
98
|
+
|
|
99
|
+
{2-3 sentences: what's the overall state? what patterns emerged across agents?}
|
|
100
|
+
|
|
101
|
+
## Proposed Changes
|
|
102
|
+
|
|
103
|
+
### 1. [{operation}] {title}
|
|
104
|
+
**File(s):** {paths}
|
|
105
|
+
**Evidence:** {which agent(s) flagged this, with their exact finding}
|
|
106
|
+
**Current (verbatim):**
|
|
107
|
+
> {exact quoted lines from the file — enough context to verify}
|
|
108
|
+
|
|
109
|
+
**Proposed (verbatim):**
|
|
110
|
+
> {exact replacement text — what the file will look like after}
|
|
111
|
+
|
|
112
|
+
**Diff preview:**
|
|
113
|
+
- {removed lines}
|
|
114
|
+
+ {added lines}
|
|
115
|
+
**Why:** {rationale — why this change, why now, what improves}
|
|
116
|
+
**Risk:** {what could go wrong — "none: purely additive" or "removes content: verify X is captured in Y first"}
|
|
117
|
+
|
|
118
|
+
### 2. [{operation}] ...
|
|
119
|
+
{same structure}
|
|
120
|
+
|
|
121
|
+
### 3. [{operation}] ...
|
|
122
|
+
{same structure}
|
|
123
|
+
|
|
124
|
+
## Skipped Findings
|
|
125
|
+
{list findings from agents that you chose NOT to act on, with 1-line reason why — so the reviewer can verify your judgment}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The full report is the audit trail. Raw agent reports let you verify the diagnosis. Diff previews let you verify the prescription. Skipped findings let you verify the triage.
|
|
129
|
+
|
|
130
|
+
### Send Slack DM to owners
|
|
131
|
+
|
|
132
|
+
Send a DM to each owner (from `<known_contacts>` with Slack IDs) using `post_slack_message`:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
🌱 Knowledge Garden — {date}
|
|
136
|
+
|
|
137
|
+
{N} raw findings → {N} proposed changes (max 3).
|
|
138
|
+
Full audit trail: data/workspace/garden-reports/{date}.md
|
|
139
|
+
|
|
140
|
+
1. [{operation}] {1-liner} — {file}
|
|
141
|
+
Risk: {none/low/medium}
|
|
142
|
+
Diff: -{removed summary} +{added summary}
|
|
143
|
+
2. [{operation}] {1-liner} — {file}
|
|
144
|
+
Risk: {none/low/medium}
|
|
145
|
+
Diff: -{removed summary} +{added summary}
|
|
146
|
+
3. [{operation}] {1-liner} — {file}
|
|
147
|
+
Risk: {none/low/medium}
|
|
148
|
+
Diff: -{removed summary} +{added summary}
|
|
149
|
+
|
|
150
|
+
Skipped {N} lower-priority findings (see report).
|
|
151
|
+
Reply with numbers to approve (e.g. "1,3") or "all".
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**STOP here. Do not apply changes. Wait for user approval.**
|
|
155
|
+
|
|
156
|
+
## Phase 4: Apply (only when user approves)
|
|
157
|
+
|
|
158
|
+
When the user replies with numbers (e.g. "1,3") or "all":
|
|
159
|
+
|
|
160
|
+
1. Load the report from `data/workspace/garden-reports/{date}.md`
|
|
161
|
+
2. Apply only the approved changes using Edit tool
|
|
162
|
+
3. Commit:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
cd data && git add -A && git commit -m "garden: $(date +%Y-%m-%d) — <brief summary of applied changes>"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Recovery:** `cd data && git revert HEAD`
|
|
169
|
+
|
|
170
|
+
## Guidelines
|
|
171
|
+
|
|
172
|
+
- **Propose, don't act** — never edit workspace files without explicit approval
|
|
173
|
+
- **Max 3 changes** — gardening is incremental; run again tomorrow
|
|
174
|
+
- **Preserve voice** — match existing tone of each file
|
|
175
|
+
- **context.md is the hot index** — keep it under 100 lines of actual content; push detail to knowledge/
|
|
176
|
+
- **knowledge/*.md files hold detail** — keep each under 120 lines; split if growing
|
|
177
|
+
- **Don't touch user-scope** — `users/{id}/` is reconcile's domain
|
|
178
|
+
- **Cite evidence** — every proposal references the agent finding that supports it
|
|
179
|
+
- **Don't fabricate** — restructure existing content, don't invent new facts
|