shraga 0.0.3 → 0.1.2

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.
Files changed (180) hide show
  1. package/README.md +82 -27
  2. package/defaults/agents/summarizer.md +16 -0
  3. package/defaults/agents/trace-extractor.md +84 -0
  4. package/defaults/bin/claude +45 -0
  5. package/defaults/bin/claude-revive +17 -0
  6. package/defaults/extensions/README.md +70 -0
  7. package/defaults/extensions/selftest.ext.ts +43 -0
  8. package/defaults/extensions/stripe-webhook.ext.ts +58 -0
  9. package/defaults/gmail-triage-prompt.md +42 -0
  10. package/defaults/scripts/README +4 -0
  11. package/defaults/scripts/agent-once.ts +67 -0
  12. package/defaults/scripts/backfill-slack-usernames.ts +82 -0
  13. package/defaults/scripts/notifier-throttle.ts +44 -0
  14. package/defaults/scripts/summarize-conversations.ts +5 -0
  15. package/defaults/shraga.config.ts +29 -0
  16. package/defaults/skills/add-skill.md +14 -0
  17. package/defaults/skills/artifacts.md +116 -0
  18. package/defaults/skills/code-review.md +26 -0
  19. package/defaults/skills/communications.md +54 -0
  20. package/defaults/skills/context-audit.md +87 -0
  21. package/defaults/skills/debug.md +10 -0
  22. package/defaults/skills/garden.md +179 -0
  23. package/defaults/skills/github-contributor.md +35 -0
  24. package/defaults/skills/identity.md +30 -0
  25. package/defaults/skills/mcp-server.md +62 -0
  26. package/defaults/skills/mcps-sync.md +105 -0
  27. package/defaults/skills/plan.md +9 -0
  28. package/defaults/skills/platform.md +177 -0
  29. package/defaults/skills/reconcile.md +239 -0
  30. package/defaults/skills/scheduler.md +192 -0
  31. package/defaults/skills/self-aware.md +136 -0
  32. package/defaults/skills/shraga-know.md +333 -0
  33. package/defaults/skills/stripe.md +55 -0
  34. package/defaults/skills/write-tests.md +10 -0
  35. package/defaults/skills-defaults.json +1 -0
  36. package/defaults/system-prompt.md +46 -0
  37. package/defaults/workspace/context.md +28 -0
  38. package/defaults/workspace.md +50 -0
  39. package/defaults/zdotdir/.gitignore +8 -0
  40. package/defaults/zdotdir/.zlogin +3 -0
  41. package/defaults/zdotdir/.zprofile +1 -0
  42. package/defaults/zdotdir/.zshenv +4 -0
  43. package/defaults/zdotdir/.zshrc +3 -0
  44. package/dist/client/assets/index-BoHttkMt.js +1940 -0
  45. package/dist/client/assets/index-DdibEb2O.css +10 -0
  46. package/dist/client/index.html +22 -0
  47. package/package.json +59 -14
  48. package/src/cli.ts +71 -46
  49. package/src/client/App.tsx +510 -0
  50. package/src/client/components/ArtifactCard.tsx +26 -0
  51. package/src/client/components/ArtifactPanel.tsx +138 -0
  52. package/src/client/components/AuthedImage.tsx +85 -0
  53. package/src/client/components/AutocompleteTextarea.tsx +149 -0
  54. package/src/client/components/ChatView.tsx +866 -0
  55. package/src/client/components/CliAuthConsent.tsx +98 -0
  56. package/src/client/components/ConfigPanel.tsx +328 -0
  57. package/src/client/components/ConversationHeader.tsx +156 -0
  58. package/src/client/components/ConversationPane.tsx +277 -0
  59. package/src/client/components/LoginPage.tsx +81 -0
  60. package/src/client/components/MachineStats.tsx +77 -0
  61. package/src/client/components/McpManager.tsx +209 -0
  62. package/src/client/components/MessageInput.tsx +263 -0
  63. package/src/client/components/OAuthConsent.tsx +103 -0
  64. package/src/client/components/SchedulesManager.tsx +99 -0
  65. package/src/client/components/Sidebar.tsx +235 -0
  66. package/src/client/components/SkillsManager.tsx +280 -0
  67. package/src/client/components/SmartChart.tsx +167 -0
  68. package/src/client/components/Toast.tsx +54 -0
  69. package/src/client/components/WorkspaceTree.tsx +313 -0
  70. package/src/client/components/ZoomableImage.tsx +123 -0
  71. package/src/client/components/artifact-presets.ts +10 -0
  72. package/src/client/components/schedules/ScheduleEditor.tsx +264 -0
  73. package/src/client/components/schedules/ScheduleList.tsx +271 -0
  74. package/src/client/components/ui/accordion.tsx +50 -0
  75. package/src/client/components/ui/button.tsx +43 -0
  76. package/src/client/components/ui/dialog.tsx +82 -0
  77. package/src/client/components/ui/input.tsx +19 -0
  78. package/src/client/components/ui/scroll-area.tsx +39 -0
  79. package/src/client/components/ui/textarea.tsx +18 -0
  80. package/src/client/globals.css +51 -0
  81. package/src/client/hooks/useAgentSocket.ts +79 -0
  82. package/src/client/hooks/useArtifacts.ts +89 -0
  83. package/src/client/hooks/useAuth.ts +127 -0
  84. package/src/client/hooks/useConversation.ts +412 -0
  85. package/src/client/hooks/useDarkMode.ts +57 -0
  86. package/src/client/hooks/useIsMobile.ts +23 -0
  87. package/src/client/hooks/usePush.ts +127 -0
  88. package/src/client/hooks/useSchedules.ts +73 -0
  89. package/src/client/hooks/useUnread.ts +238 -0
  90. package/src/client/lib/desktopAttention.ts +75 -0
  91. package/src/client/lib/firebase.ts +32 -0
  92. package/src/client/lib/googleAuthNative.ts +94 -0
  93. package/src/client/lib/native.ts +43 -0
  94. package/src/client/lib/schedule-types.ts +34 -0
  95. package/src/client/lib/sessionApi.ts +58 -0
  96. package/src/client/lib/slots.tsx +79 -0
  97. package/src/client/lib/storage.ts +39 -0
  98. package/src/client/lib/utils.ts +26 -0
  99. package/src/client/lib/workspaceContext.tsx +54 -0
  100. package/src/client/lib/ws.ts +203 -0
  101. package/src/client/main.tsx +14 -0
  102. package/src/mcp-stdio-bridge.ts +70 -0
  103. package/src/scripts/summarize-conversations.ts +5 -0
  104. package/src/scripts/typecheck.ts +43 -0
  105. package/src/server/agents.ts +54 -0
  106. package/src/server/api-keys.ts +63 -0
  107. package/src/server/artifacts/artifacts.export.ts +85 -0
  108. package/src/server/artifacts/artifacts.handler.ts +93 -0
  109. package/src/server/artifacts/artifacts.routes.ts +43 -0
  110. package/src/server/artifacts/artifacts.service.ts +100 -0
  111. package/src/server/artifacts/artifacts.types.ts +31 -0
  112. package/src/server/auth.ts +262 -0
  113. package/src/server/claude.ts +394 -0
  114. package/src/server/commands.ts +21 -0
  115. package/src/server/contacts.ts +177 -0
  116. package/src/server/conversation-summarizer.ts +204 -0
  117. package/src/server/data-sync.ts +664 -0
  118. package/src/server/directives.ts +91 -0
  119. package/src/server/engine/claude-code.ts +514 -0
  120. package/src/server/engine/index.ts +41 -0
  121. package/src/server/engine/registry.ts +21 -0
  122. package/src/server/engine/shared.ts +47 -0
  123. package/src/server/engine/types.ts +48 -0
  124. package/src/server/env-resolve.ts +71 -0
  125. package/src/server/env-sanitize.ts +9 -0
  126. package/src/server/events/bus.ts +29 -0
  127. package/src/server/events/dispatcher.ts +48 -0
  128. package/src/server/events/routes.ts +19 -0
  129. package/src/server/events/types.ts +9 -0
  130. package/src/server/extensions.ts +101 -0
  131. package/src/server/features.ts +109 -0
  132. package/src/server/file-inject.ts +45 -0
  133. package/src/server/hooks.ts +142 -0
  134. package/src/server/idempotency.ts +25 -0
  135. package/src/server/index.ts +1715 -0
  136. package/src/server/integrity-audit.ts +132 -0
  137. package/src/server/mcp-catalog.ts +70 -0
  138. package/src/server/mcp-oauth.ts +198 -0
  139. package/src/server/mcp-progress.ts +45 -0
  140. package/src/server/mcp-server.ts +456 -0
  141. package/src/server/mcp-sidecar.ts +87 -0
  142. package/src/server/mcp.ts +291 -0
  143. package/src/server/model-aliases.ts +76 -0
  144. package/src/server/paths.ts +24 -0
  145. package/src/server/polls.ts +175 -0
  146. package/src/server/push/apns.ts +113 -0
  147. package/src/server/push/fcm.ts +108 -0
  148. package/src/server/push/push.ts +66 -0
  149. package/src/server/push/store.ts +84 -0
  150. package/src/server/push/triggers.ts +99 -0
  151. package/src/server/scheduler/builtins.ts +157 -0
  152. package/src/server/scheduler/engine.ts +432 -0
  153. package/src/server/scheduler/index.ts +4 -0
  154. package/src/server/scheduler/runner.ts +334 -0
  155. package/src/server/scheduler/storage.ts +98 -0
  156. package/src/server/scheduler/timing.ts +70 -0
  157. package/src/server/scheduler/types.ts +62 -0
  158. package/src/server/sdk-utils.ts +45 -0
  159. package/src/server/seed.ts +174 -0
  160. package/src/server/session-bus.ts +18 -0
  161. package/src/server/sessions.ts +559 -0
  162. package/src/server/shraga-config.ts +167 -0
  163. package/src/server/skills.ts +372 -0
  164. package/src/server/slack/api.ts +37 -0
  165. package/src/server/slack/bot.ts +391 -0
  166. package/src/server/slack/context-cache.ts +42 -0
  167. package/src/server/slack/feature.ts +59 -0
  168. package/src/server/slack/mention-rewrite.ts +59 -0
  169. package/src/server/slack/oauth.ts +102 -0
  170. package/src/server/slack/questions.ts +112 -0
  171. package/src/server/slack/sessions.ts +139 -0
  172. package/src/server/stats.ts +106 -0
  173. package/src/server/summarize.ts +11 -0
  174. package/src/server/turn-context.ts +61 -0
  175. package/src/server/unclaw-config.ts +19 -0
  176. package/src/server/unread.ts +79 -0
  177. package/src/server/user-context.ts +33 -0
  178. package/src/server/vendor-sync.ts +52 -0
  179. package/src/server/voice-provider.ts +74 -0
  180. package/src/server/workspace.ts +249 -0
@@ -0,0 +1,174 @@
1
+ import { mkdirSync, readdirSync, existsSync, copyFileSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dataPath } from './paths.ts';
5
+ import { resolveConfigPath } from './shraga-config.ts';
6
+
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+ const DEFAULTS_DIR = path.resolve(__dirname, '../../defaults');
9
+
10
+ /**
11
+ * Copy only when content differs — avoids bumping mtime on identical reseeds.
12
+ * Critical for files in the runtime import graph (e.g. *.ext.ts): an unconditional
13
+ * copyFileSync churns mtime every boot, and `bun --watch` then restarts → reseed →
14
+ * restart loop. Returns true if a write happened.
15
+ */
16
+ function copyIfChanged(src: string, dest: string): boolean {
17
+ if (existsSync(dest)) {
18
+ try {
19
+ if (readFileSync(src).equals(readFileSync(dest))) return false;
20
+ } catch {}
21
+ }
22
+ copyFileSync(src, dest);
23
+ return true;
24
+ }
25
+
26
+ function copyDirRecursive(src: string, dest: string) {
27
+ mkdirSync(dest, { recursive: true });
28
+ for (const entry of readdirSync(src, { withFileTypes: true })) {
29
+ const s = path.join(src, entry.name);
30
+ const d = path.join(dest, entry.name);
31
+ if (entry.isDirectory()) copyDirRecursive(s, d);
32
+ else copyFileSync(s, d);
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Seed data/ from defaults/ on startup.
38
+ * - Skills: always overwritten from defaults (they're shipped code)
39
+ * - Other config files: only created if missing (preserves server state)
40
+ */
41
+ export function seedDefaults() {
42
+ if (!existsSync(DEFAULTS_DIR)) return;
43
+
44
+ // Skills: always sync from defaults — these are code, not user data.
45
+ const srcSkills = path.join(DEFAULTS_DIR, 'skills');
46
+ if (existsSync(srcSkills)) {
47
+ mkdirSync(dataPath('skills'), { recursive: true });
48
+ let count = 0;
49
+ for (const file of readdirSync(srcSkills).filter(f => f.endsWith('.md'))) {
50
+ copyFileSync(path.join(srcSkills, file), dataPath('skills', file));
51
+ count++;
52
+ }
53
+ console.log(`[seed] Synced ${count} built-in skills from defaults`);
54
+ }
55
+
56
+ // Typed subagent defs (data/agents/<name>.md): always sync from defaults — code, not user data.
57
+ // An add-on engine's Task tool loads these (agentsDir) to enable the `agentType` param (e.g. 'summarizer').
58
+ const srcAgents = path.join(DEFAULTS_DIR, 'agents');
59
+ if (existsSync(srcAgents)) {
60
+ mkdirSync(dataPath('agents'), { recursive: true });
61
+ let count = 0;
62
+ for (const file of readdirSync(srcAgents).filter(f => f.endsWith('.md'))) {
63
+ copyFileSync(path.join(srcAgents, file), dataPath('agents', file));
64
+ count++;
65
+ }
66
+ console.log(`[seed] Synced ${count} built-in subagent defs from defaults`);
67
+ }
68
+
69
+ // MCPs dir: ensure it exists for per-user configs
70
+ mkdirSync(dataPath('mcps'), { recursive: true });
71
+
72
+ // Scripts: seed agent-facing scripts from defaults → data/scripts/
73
+ const srcScripts = path.join(DEFAULTS_DIR, 'scripts');
74
+ const destScripts = dataPath('scripts');
75
+ if (existsSync(srcScripts)) {
76
+ mkdirSync(destScripts, { recursive: true });
77
+ let synced = 0;
78
+ for (const entry of readdirSync(srcScripts, { withFileTypes: true })) {
79
+ if (entry.isDirectory()) continue;
80
+ const dest = path.join(destScripts, entry.name);
81
+ if (!existsSync(dest)) {
82
+ copyFileSync(path.join(srcScripts, entry.name), dest);
83
+ synced++;
84
+ }
85
+ }
86
+ if (synced) console.log(`[seed] Seeded ${synced} agent scripts from defaults`);
87
+ }
88
+
89
+ // Extensions: drop-in route modules (data/extensions/*.ext.ts). Copy shipped
90
+ // files from defaults (overwriting same-named, like skills — they're code), and
91
+ // leave any deployment-added *.ext.ts untouched.
92
+ const srcExt = path.join(DEFAULTS_DIR, 'extensions');
93
+ if (existsSync(srcExt)) {
94
+ mkdirSync(dataPath('extensions'), { recursive: true });
95
+ let n = 0;
96
+ for (const entry of readdirSync(srcExt, { withFileTypes: true })) {
97
+ if (entry.isDirectory()) continue;
98
+ if (copyIfChanged(path.join(srcExt, entry.name), dataPath('extensions', entry.name))) n++;
99
+ }
100
+ if (n) console.log(`[seed] Synced ${n} built-in extensions from defaults`);
101
+ }
102
+
103
+ // Config: seed the template only when NO config exists under any known name. Guarding on the
104
+ // legacy name too is load-bearing — an existing deployment carries `unclaw.config.ts`, and
105
+ // seeding a fresh (empty) `shraga.config.ts` beside it would take precedence and silently drop
106
+ // every configured global MCP.
107
+ const configSrc = path.join(DEFAULTS_DIR, 'shraga.config.ts');
108
+ if (existsSync(configSrc) && !resolveConfigPath()) {
109
+ copyFileSync(configSrc, dataPath('shraga.config.ts'));
110
+ console.log('[seed] Seeded shraga.config.ts from defaults');
111
+ }
112
+
113
+ seedWorkspaceDefaults();
114
+
115
+ // Skills defaults: merge new entries from defaults into existing list
116
+ const skillDefaultsSrc = path.join(DEFAULTS_DIR, 'skills-defaults.json');
117
+ const skillDefaultsDest = dataPath('skills-defaults.json');
118
+ if (existsSync(skillDefaultsSrc)) {
119
+ mkdirSync(path.dirname(skillDefaultsDest), { recursive: true });
120
+ let defaults: string[] = [];
121
+ try { defaults = JSON.parse(readFileSync(skillDefaultsSrc, 'utf-8')); } catch {}
122
+ let existing: string[] = [];
123
+ try { existing = JSON.parse(readFileSync(skillDefaultsDest, 'utf-8')); } catch {}
124
+ const added = defaults.filter(s => !existing.includes(s));
125
+ if (added.length || !existsSync(skillDefaultsDest)) {
126
+ const merged = [...new Set([...existing, ...defaults])];
127
+ writeFileSync(skillDefaultsDest, JSON.stringify(merged, null, 2));
128
+ if (added.length) console.log(`[seed] Added default skills: ${added.join(', ')}`);
129
+ }
130
+ }
131
+ }
132
+
133
+ /** Shipped team knowledge: defaults/workspace → data/workspace (synced like extensions). */
134
+ function seedWorkspaceDefaults() {
135
+ const srcWorkspace = path.join(DEFAULTS_DIR, 'workspace');
136
+ if (!existsSync(srcWorkspace)) return;
137
+
138
+ const destWorkspace = dataPath('workspace');
139
+ mkdirSync(destWorkspace, { recursive: true });
140
+
141
+ const srcKnowledge = path.join(srcWorkspace, 'knowledge');
142
+ const destKnowledge = path.join(destWorkspace, 'knowledge');
143
+ if (existsSync(srcKnowledge)) {
144
+ mkdirSync(destKnowledge, { recursive: true });
145
+ let n = 0;
146
+ for (const file of readdirSync(srcKnowledge).filter(f => f.endsWith('.md'))) {
147
+ if (copyIfChanged(path.join(srcKnowledge, file), path.join(destKnowledge, file))) n++;
148
+ }
149
+ if (n) console.log(`[seed] Synced ${n} workspace knowledge file(s) from defaults`);
150
+ }
151
+
152
+ const srcContext = path.join(srcWorkspace, 'context.md');
153
+ const destContext = path.join(destWorkspace, 'context.md');
154
+ if (!existsSync(srcContext)) return;
155
+
156
+ if (!existsSync(destContext)) {
157
+ copyFileSync(srcContext, destContext);
158
+ console.log('[seed] Seeded workspace/context.md from defaults');
159
+ return;
160
+ }
161
+
162
+ // context.md is create-if-missing on purpose: it's the operator's own briefing card, so once it
163
+ // exists it belongs to them. Never rewrite it here — a seeder that edits live operator content is
164
+ // how gardened knowledge gets silently clobbered on boot.
165
+ }
166
+
167
+ /** Returns names of skills shipped in defaults/ */
168
+ export function getBuiltinSkillNames(): string[] {
169
+ const srcSkills = path.join(DEFAULTS_DIR, 'skills');
170
+ if (!existsSync(srcSkills)) return [];
171
+ return readdirSync(srcSkills)
172
+ .filter(f => f.endsWith('.md'))
173
+ .map(f => f.slice(0, -3));
174
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Tiny indirection so server modules (e.g. an add-on's background duplex engine) can push WS events to a session
3
+ * OUTSIDE a request turn — without importing index.ts (which would be a cycle). index.ts registers the
4
+ * real `broadcast` at boot via setBroadcaster(); callers use emitToSession().
5
+ */
6
+ type Broadcaster = (data: object) => void;
7
+
8
+ let _broadcast: Broadcaster | null = null;
9
+
10
+ export function setBroadcaster(fn: Broadcaster): void {
11
+ _broadcast = fn;
12
+ }
13
+
14
+ /** Push an event to all clients (carrying sessionId); no-op if the bus isn't wired yet. */
15
+ export function emitToSession(sessionId: string, data: object): void {
16
+ if (!_broadcast) return;
17
+ _broadcast({ ...data, sessionId });
18
+ }