shraga 0.1.2 → 0.1.4
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 +63 -1
- package/defaults/agents/trace-extractor.md +1 -1
- package/defaults/extensions/stripe-webhook.ext.ts +29 -21
- package/defaults/scripts/agent-once.ts +1 -1
- package/defaults/skills/communications.md +1 -1
- package/defaults/skills/mcps-sync.md +2 -2
- package/defaults/skills/self-aware.md +1 -1
- package/dist/client/assets/{index-BoHttkMt.js → index-BnArwb7g.js} +43 -43
- package/dist/client/index.html +1 -1
- package/package.json +8 -5
- package/src/cli.ts +3 -1
- package/src/client/components/ArtifactPanel.tsx +16 -3
- package/src/index.ts +172 -0
- package/src/server/artifacts/artifacts.routes.ts +2 -19
- package/src/server/boot.ts +1779 -0
- package/src/server/engine/claude-code.ts +2 -2
- package/src/server/events/bus.ts +21 -5
- package/src/server/events/types.ts +26 -3
- package/src/server/events/webhook.ts +64 -0
- package/src/server/extensions.ts +34 -0
- package/src/server/hooks.ts +2 -2
- package/src/server/index.ts +8 -1712
- package/src/server/slack/bot.ts +1 -1
- package/src/server/slack/feature.ts +1 -1
- package/src/server/turn-context.ts +7 -0
- package/src/server/artifacts/artifacts.export.ts +0 -85
package/src/server/slack/bot.ts
CHANGED
|
@@ -189,7 +189,7 @@ export async function* runAgentTurn(msg: IngressMessage): AsyncGenerator<AgentEv
|
|
|
189
189
|
: `#${channelName || 'channel'} context`;
|
|
190
190
|
appendMessage(sessionId, {
|
|
191
191
|
id: crypto.randomUUID(), role: 'user',
|
|
192
|
-
blocks: [{ type: 'context', label, text: `${channelCtx}\n\n[Use mcp-slack tools (get_slack_history_by_channel, post_slack_message) for further context or replies. Always read channel history before posting.]` }],
|
|
192
|
+
blocks: [{ type: 'context', label, text: `${channelCtx}\n\n[Use mcp-slack-use tools (get_slack_history_by_channel, post_slack_message) for further context or replies. Always read channel history before posting.]` }],
|
|
193
193
|
});
|
|
194
194
|
}
|
|
195
195
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// slackFeature — the ServerFeature that mounts Slack in this app. It wires the mcp-slack package
|
|
1
|
+
// slackFeature — the ServerFeature that mounts Slack in this app. It wires the mcp-slack-use package
|
|
2
2
|
// `ingress` (protocol) to the agent-glue (bot.ts) and subscribes the data-sync deploy notifier
|
|
3
3
|
// (event bus → owner DMs). Slack ships in this app, so index.ts registers this directly.
|
|
4
4
|
import type { ServerFeature, FeatureContext } from '../features.ts';
|
|
@@ -27,6 +27,13 @@ export function registerTurnContext(name: string, contribute: TurnContextContrib
|
|
|
27
27
|
contributors.set(name, contribute);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/** Clear all registered contributors. For tests: the registry is a process-global, so a test that
|
|
31
|
+
* asserts the empty-registry (no-contributor) behavior must reset it first or it inherits whatever
|
|
32
|
+
* another test file registered — bun's cross-file order is not stable across platforms. */
|
|
33
|
+
export function clearTurnContext(): void {
|
|
34
|
+
contributors.clear();
|
|
35
|
+
}
|
|
36
|
+
|
|
30
37
|
/**
|
|
31
38
|
* Collect every contributor's block for this turn, joined by a blank line. Empty when none is
|
|
32
39
|
* registered — which is the core's own state, so the core's prompt is byte-identical to before.
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { dataPath } from '../paths.ts';
|
|
4
|
-
|
|
5
|
-
const PREFIX = '[artifacts:export]';
|
|
6
|
-
|
|
7
|
-
let browserInstance: any = null;
|
|
8
|
-
let idleTimer: ReturnType<typeof setTimeout> | null = null;
|
|
9
|
-
const IDLE_TIMEOUT = 60_000;
|
|
10
|
-
|
|
11
|
-
async function getBrowser() {
|
|
12
|
-
if (browserInstance) {
|
|
13
|
-
resetIdleTimer();
|
|
14
|
-
return browserInstance;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
let puppeteer: any;
|
|
18
|
-
try {
|
|
19
|
-
puppeteer = await import('puppeteer');
|
|
20
|
-
} catch {
|
|
21
|
-
throw new Error('puppeteer not installed. Run: bun add puppeteer');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
console.log(PREFIX, 'launching browser');
|
|
25
|
-
browserInstance = await puppeteer.default.launch({
|
|
26
|
-
headless: true,
|
|
27
|
-
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
browserInstance.on('disconnected', () => { browserInstance = null; });
|
|
31
|
-
resetIdleTimer();
|
|
32
|
-
return browserInstance;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function resetIdleTimer() {
|
|
36
|
-
if (idleTimer) clearTimeout(idleTimer);
|
|
37
|
-
idleTimer = setTimeout(async () => {
|
|
38
|
-
if (browserInstance) {
|
|
39
|
-
console.log(PREFIX, 'closing idle browser');
|
|
40
|
-
await browserInstance.close().catch(() => {});
|
|
41
|
-
browserInstance = null;
|
|
42
|
-
}
|
|
43
|
-
}, IDLE_TIMEOUT);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export async function exportToPng(
|
|
47
|
-
html: string,
|
|
48
|
-
dimensions: [number, number],
|
|
49
|
-
): Promise<Buffer> {
|
|
50
|
-
const [width, height] = dimensions;
|
|
51
|
-
const browser = await getBrowser();
|
|
52
|
-
const page = await browser.newPage();
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
await page.setViewport({ width, height, deviceScaleFactor: 2 });
|
|
56
|
-
await page.setContent(html, { waitUntil: 'networkidle0', timeout: 15_000 });
|
|
57
|
-
const png = await page.screenshot({ type: 'png', clip: { x: 0, y: 0, width, height } });
|
|
58
|
-
return Buffer.from(png);
|
|
59
|
-
} finally {
|
|
60
|
-
await page.close();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export async function exportAndSave(
|
|
65
|
-
sessionId: string,
|
|
66
|
-
artifactId: string,
|
|
67
|
-
html: string,
|
|
68
|
-
dimensions: [number, number],
|
|
69
|
-
): Promise<string> {
|
|
70
|
-
const png = await exportToPng(html, dimensions);
|
|
71
|
-
const dir = dataPath(`sessions/${sessionId}/artifacts`);
|
|
72
|
-
mkdirSync(dir, { recursive: true });
|
|
73
|
-
const filePath = path.join(dir, `${artifactId}.png`);
|
|
74
|
-
writeFileSync(filePath, png);
|
|
75
|
-
console.log(PREFIX, `saved ${filePath} (${png.length} bytes)`);
|
|
76
|
-
return filePath;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export async function closeBrowser() {
|
|
80
|
-
if (idleTimer) clearTimeout(idleTimer);
|
|
81
|
-
if (browserInstance) {
|
|
82
|
-
await browserInstance.close().catch(() => {});
|
|
83
|
-
browserInstance = null;
|
|
84
|
-
}
|
|
85
|
-
}
|