adaria-ai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/apps.example.yaml +65 -0
- package/dist/agent/audit.d.ts +16 -0
- package/dist/agent/audit.d.ts.map +1 -0
- package/dist/agent/audit.js +42 -0
- package/dist/agent/audit.js.map +1 -0
- package/dist/agent/claude.d.ts +62 -0
- package/dist/agent/claude.d.ts.map +1 -0
- package/dist/agent/claude.js +297 -0
- package/dist/agent/claude.js.map +1 -0
- package/dist/agent/conversation-summary.d.ts +29 -0
- package/dist/agent/conversation-summary.d.ts.map +1 -0
- package/dist/agent/conversation-summary.js +221 -0
- package/dist/agent/conversation-summary.js.map +1 -0
- package/dist/agent/core.d.ts +81 -0
- package/dist/agent/core.d.ts.map +1 -0
- package/dist/agent/core.js +527 -0
- package/dist/agent/core.js.map +1 -0
- package/dist/agent/mcp-launcher.d.ts +42 -0
- package/dist/agent/mcp-launcher.d.ts.map +1 -0
- package/dist/agent/mcp-launcher.js +38 -0
- package/dist/agent/mcp-launcher.js.map +1 -0
- package/dist/agent/mcp-manager.d.ts +81 -0
- package/dist/agent/mcp-manager.d.ts.map +1 -0
- package/dist/agent/mcp-manager.js +136 -0
- package/dist/agent/mcp-manager.js.map +1 -0
- package/dist/agent/memory.d.ts +10 -0
- package/dist/agent/memory.d.ts.map +1 -0
- package/dist/agent/memory.js +95 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/safety.d.ts +45 -0
- package/dist/agent/safety.d.ts.map +1 -0
- package/dist/agent/safety.js +71 -0
- package/dist/agent/safety.js.map +1 -0
- package/dist/agent/session.d.ts +27 -0
- package/dist/agent/session.d.ts.map +1 -0
- package/dist/agent/session.js +124 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/agent/tool-descriptions.d.ts +8 -0
- package/dist/agent/tool-descriptions.d.ts.map +1 -0
- package/dist/agent/tool-descriptions.js +26 -0
- package/dist/agent/tool-descriptions.js.map +1 -0
- package/dist/cli/analyze.d.ts +8 -0
- package/dist/cli/analyze.d.ts.map +1 -0
- package/dist/cli/analyze.js +114 -0
- package/dist/cli/analyze.js.map +1 -0
- package/dist/cli/daemon.d.ts +2 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +91 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +198 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +459 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/logs.d.ts +4 -0
- package/dist/cli/logs.d.ts.map +1 -0
- package/dist/cli/logs.js +50 -0
- package/dist/cli/logs.js.map +1 -0
- package/dist/cli/monitor-cmd.d.ts +11 -0
- package/dist/cli/monitor-cmd.d.ts.map +1 -0
- package/dist/cli/monitor-cmd.js +59 -0
- package/dist/cli/monitor-cmd.js.map +1 -0
- package/dist/cli/start.d.ts +11 -0
- package/dist/cli/start.d.ts.map +1 -0
- package/dist/cli/start.js +103 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/cli/status.d.ts +9 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +49 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/stop.d.ts +2 -0
- package/dist/cli/stop.d.ts.map +1 -0
- package/dist/cli/stop.js +34 -0
- package/dist/cli/stop.js.map +1 -0
- package/dist/collectors/appstore.d.ts +51 -0
- package/dist/collectors/appstore.d.ts.map +1 -0
- package/dist/collectors/appstore.js +166 -0
- package/dist/collectors/appstore.js.map +1 -0
- package/dist/collectors/arden-tts.d.ts +60 -0
- package/dist/collectors/arden-tts.d.ts.map +1 -0
- package/dist/collectors/arden-tts.js +83 -0
- package/dist/collectors/arden-tts.js.map +1 -0
- package/dist/collectors/asomobile.d.ts +37 -0
- package/dist/collectors/asomobile.d.ts.map +1 -0
- package/dist/collectors/asomobile.js +88 -0
- package/dist/collectors/asomobile.js.map +1 -0
- package/dist/collectors/eodin-blog.d.ts +90 -0
- package/dist/collectors/eodin-blog.d.ts.map +1 -0
- package/dist/collectors/eodin-blog.js +238 -0
- package/dist/collectors/eodin-blog.js.map +1 -0
- package/dist/collectors/eodin-sdk.d.ts +60 -0
- package/dist/collectors/eodin-sdk.d.ts.map +1 -0
- package/dist/collectors/eodin-sdk.js +112 -0
- package/dist/collectors/eodin-sdk.js.map +1 -0
- package/dist/collectors/fridgify-recipes.d.ts +65 -0
- package/dist/collectors/fridgify-recipes.d.ts.map +1 -0
- package/dist/collectors/fridgify-recipes.js +111 -0
- package/dist/collectors/fridgify-recipes.js.map +1 -0
- package/dist/collectors/playstore.d.ts +46 -0
- package/dist/collectors/playstore.d.ts.map +1 -0
- package/dist/collectors/playstore.js +140 -0
- package/dist/collectors/playstore.js.map +1 -0
- package/dist/collectors/youtube.d.ts +44 -0
- package/dist/collectors/youtube.d.ts.map +1 -0
- package/dist/collectors/youtube.js +107 -0
- package/dist/collectors/youtube.js.map +1 -0
- package/dist/config/apps-schema.d.ts +94 -0
- package/dist/config/apps-schema.d.ts.map +1 -0
- package/dist/config/apps-schema.js +66 -0
- package/dist/config/apps-schema.js.map +1 -0
- package/dist/config/keychain.d.ts +14 -0
- package/dist/config/keychain.d.ts.map +1 -0
- package/dist/config/keychain.js +89 -0
- package/dist/config/keychain.js.map +1 -0
- package/dist/config/load-apps.d.ts +16 -0
- package/dist/config/load-apps.d.ts.map +1 -0
- package/dist/config/load-apps.js +38 -0
- package/dist/config/load-apps.js.map +1 -0
- package/dist/config/schema.d.ts +306 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +220 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/store.d.ts +38 -0
- package/dist/config/store.d.ts.map +1 -0
- package/dist/config/store.js +180 -0
- package/dist/config/store.js.map +1 -0
- package/dist/db/queries.d.ts +304 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +327 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +15 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +252 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/messenger/adapter.d.ts +63 -0
- package/dist/messenger/adapter.d.ts.map +1 -0
- package/dist/messenger/adapter.js +7 -0
- package/dist/messenger/adapter.js.map +1 -0
- package/dist/messenger/factory.d.ts +12 -0
- package/dist/messenger/factory.d.ts.map +1 -0
- package/dist/messenger/factory.js +9 -0
- package/dist/messenger/factory.js.map +1 -0
- package/dist/messenger/slack.d.ts +30 -0
- package/dist/messenger/slack.d.ts.map +1 -0
- package/dist/messenger/slack.js +309 -0
- package/dist/messenger/slack.js.map +1 -0
- package/dist/messenger/split.d.ts +17 -0
- package/dist/messenger/split.d.ts.map +1 -0
- package/dist/messenger/split.js +56 -0
- package/dist/messenger/split.js.map +1 -0
- package/dist/orchestrator/dashboard.d.ts +67 -0
- package/dist/orchestrator/dashboard.d.ts.map +1 -0
- package/dist/orchestrator/dashboard.js +113 -0
- package/dist/orchestrator/dashboard.js.map +1 -0
- package/dist/orchestrator/monitor.d.ts +37 -0
- package/dist/orchestrator/monitor.d.ts.map +1 -0
- package/dist/orchestrator/monitor.js +236 -0
- package/dist/orchestrator/monitor.js.map +1 -0
- package/dist/orchestrator/types.d.ts +82 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +12 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/orchestrator/weekly.d.ts +66 -0
- package/dist/orchestrator/weekly.d.ts.map +1 -0
- package/dist/orchestrator/weekly.js +376 -0
- package/dist/orchestrator/weekly.js.map +1 -0
- package/dist/prompts/loader.d.ts +18 -0
- package/dist/prompts/loader.d.ts.map +1 -0
- package/dist/prompts/loader.js +28 -0
- package/dist/prompts/loader.js.map +1 -0
- package/dist/security/auth.d.ts +14 -0
- package/dist/security/auth.d.ts.map +1 -0
- package/dist/security/auth.js +14 -0
- package/dist/security/auth.js.map +1 -0
- package/dist/security/prompt-guard.d.ts +21 -0
- package/dist/security/prompt-guard.d.ts.map +1 -0
- package/dist/security/prompt-guard.js +54 -0
- package/dist/security/prompt-guard.js.map +1 -0
- package/dist/skills/aso.d.ts +60 -0
- package/dist/skills/aso.d.ts.map +1 -0
- package/dist/skills/aso.js +322 -0
- package/dist/skills/aso.js.map +1 -0
- package/dist/skills/content.d.ts +25 -0
- package/dist/skills/content.d.ts.map +1 -0
- package/dist/skills/content.js +90 -0
- package/dist/skills/content.js.map +1 -0
- package/dist/skills/index.d.ts +65 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +90 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/onboarding.d.ts +58 -0
- package/dist/skills/onboarding.d.ts.map +1 -0
- package/dist/skills/onboarding.js +274 -0
- package/dist/skills/onboarding.js.map +1 -0
- package/dist/skills/registry.d.ts +24 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +66 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/review.d.ts +33 -0
- package/dist/skills/review.d.ts.map +1 -0
- package/dist/skills/review.js +236 -0
- package/dist/skills/review.js.map +1 -0
- package/dist/skills/sdk-request.d.ts +30 -0
- package/dist/skills/sdk-request.d.ts.map +1 -0
- package/dist/skills/sdk-request.js +72 -0
- package/dist/skills/sdk-request.js.map +1 -0
- package/dist/skills/seo-blog.d.ts +64 -0
- package/dist/skills/seo-blog.d.ts.map +1 -0
- package/dist/skills/seo-blog.js +268 -0
- package/dist/skills/seo-blog.js.map +1 -0
- package/dist/skills/short-form.d.ts +28 -0
- package/dist/skills/short-form.d.ts.map +1 -0
- package/dist/skills/short-form.js +121 -0
- package/dist/skills/short-form.js.map +1 -0
- package/dist/skills/social-publish.d.ts +32 -0
- package/dist/skills/social-publish.d.ts.map +1 -0
- package/dist/skills/social-publish.js +133 -0
- package/dist/skills/social-publish.js.map +1 -0
- package/dist/social/base.d.ts +47 -0
- package/dist/social/base.d.ts.map +1 -0
- package/dist/social/base.js +26 -0
- package/dist/social/base.js.map +1 -0
- package/dist/social/facebook.d.ts +27 -0
- package/dist/social/facebook.d.ts.map +1 -0
- package/dist/social/facebook.js +166 -0
- package/dist/social/facebook.js.map +1 -0
- package/dist/social/factory.d.ts +26 -0
- package/dist/social/factory.d.ts.map +1 -0
- package/dist/social/factory.js +32 -0
- package/dist/social/factory.js.map +1 -0
- package/dist/social/linkedin.d.ts +26 -0
- package/dist/social/linkedin.d.ts.map +1 -0
- package/dist/social/linkedin.js +190 -0
- package/dist/social/linkedin.js.map +1 -0
- package/dist/social/threads.d.ts +21 -0
- package/dist/social/threads.d.ts.map +1 -0
- package/dist/social/threads.js +122 -0
- package/dist/social/threads.js.map +1 -0
- package/dist/social/tiktok.d.ts +23 -0
- package/dist/social/tiktok.d.ts.map +1 -0
- package/dist/social/tiktok.js +110 -0
- package/dist/social/tiktok.js.map +1 -0
- package/dist/social/twitter.d.ts +30 -0
- package/dist/social/twitter.d.ts.map +1 -0
- package/dist/social/twitter.js +189 -0
- package/dist/social/twitter.js.map +1 -0
- package/dist/social/youtube.d.ts +21 -0
- package/dist/social/youtube.d.ts.map +1 -0
- package/dist/social/youtube.js +108 -0
- package/dist/social/youtube.js.map +1 -0
- package/dist/tools/app-info.d.ts +7 -0
- package/dist/tools/app-info.d.ts.map +1 -0
- package/dist/tools/app-info.js +53 -0
- package/dist/tools/app-info.js.map +1 -0
- package/dist/tools/collector-fetch.d.ts +11 -0
- package/dist/tools/collector-fetch.d.ts.map +1 -0
- package/dist/tools/collector-fetch.js +101 -0
- package/dist/tools/collector-fetch.js.map +1 -0
- package/dist/tools/db-query.d.ts +29 -0
- package/dist/tools/db-query.d.ts.map +1 -0
- package/dist/tools/db-query.js +159 -0
- package/dist/tools/db-query.js.map +1 -0
- package/dist/tools/skill-result.d.ts +8 -0
- package/dist/tools/skill-result.d.ts.map +1 -0
- package/dist/tools/skill-result.js +63 -0
- package/dist/tools/skill-result.js.map +1 -0
- package/dist/tools/tool-host.d.ts +12 -0
- package/dist/tools/tool-host.d.ts.map +1 -0
- package/dist/tools/tool-host.js +124 -0
- package/dist/tools/tool-host.js.map +1 -0
- package/dist/types/collectors.d.ts +198 -0
- package/dist/types/collectors.d.ts.map +1 -0
- package/dist/types/collectors.js +28 -0
- package/dist/types/collectors.js.map +1 -0
- package/dist/types/skill.d.ts +60 -0
- package/dist/types/skill.d.ts.map +1 -0
- package/dist/types/skill.js +9 -0
- package/dist/types/skill.js.map +1 -0
- package/dist/utils/circuit-breaker.d.ts +26 -0
- package/dist/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/utils/circuit-breaker.js +67 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/dist/utils/errors.d.ts +44 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +75 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/escape.d.ts +11 -0
- package/dist/utils/escape.d.ts.map +1 -0
- package/dist/utils/escape.js +19 -0
- package/dist/utils/escape.js.map +1 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +93 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/parse-json.d.ts +13 -0
- package/dist/utils/parse-json.d.ts.map +1 -0
- package/dist/utils/parse-json.js +61 -0
- package/dist/utils/parse-json.js.map +1 -0
- package/dist/utils/paths.d.ts +14 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +19 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +20 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +47 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/retry.d.ts +26 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +61 -0
- package/dist/utils/retry.js.map +1 -0
- package/launchd/.gitkeep +0 -0
- package/launchd/com.adaria-ai.daemon.plist.template +62 -0
- package/launchd/com.adaria-ai.monitor.plist.template +41 -0
- package/launchd/com.adaria-ai.weekly.plist.template +43 -0
- package/package.json +72 -0
- package/prompts/aso-description.md +44 -0
- package/prompts/aso-inapp-events.md +20 -0
- package/prompts/aso-metadata.md +34 -0
- package/prompts/aso-screenshots.md +20 -0
- package/prompts/onboarding-hypotheses.md +38 -0
- package/prompts/onboarding-review-timing.md +24 -0
- package/prompts/review-clustering.md +19 -0
- package/prompts/review-replies.md +18 -0
- package/prompts/review-sentiment.md +16 -0
- package/prompts/seo-blog-fridgify-recipe.md +116 -0
- package/prompts/seo-blog.md +69 -0
- package/prompts/short-form-ideas.md +50 -0
- package/prompts/social-publish.md +46 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { McpServerConfig } from "./mcp-launcher.js";
|
|
2
|
+
/** JSON Schema fragment describing an MCP tool's input object. */
|
|
3
|
+
export type McpInputSchema = Record<string, unknown>;
|
|
4
|
+
/**
|
|
5
|
+
* Daemon-visible metadata for a single MCP tool. Handlers live in the
|
|
6
|
+
* tool-host subprocess (see `McpToolImplementation`) and are dispatched
|
|
7
|
+
* by `id`.
|
|
8
|
+
*/
|
|
9
|
+
export interface McpToolDescriptor {
|
|
10
|
+
/** Stable identifier used in `mcp__adaria__<id>`. */
|
|
11
|
+
id: string;
|
|
12
|
+
/** Short human-readable name for the tool. */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Description injected into Claude's system prompt. */
|
|
15
|
+
description: string;
|
|
16
|
+
/** JSON Schema describing the `input` object. */
|
|
17
|
+
inputSchema: McpInputSchema;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Tool-host-side type: metadata plus the in-process handler. M5.5's MCP
|
|
21
|
+
* tool-host module will maintain its own registry of these and dispatch
|
|
22
|
+
* JSON-RPC `tools/call` requests to the matching `handler`. The daemon's
|
|
23
|
+
* `McpManager` never touches this type.
|
|
24
|
+
*/
|
|
25
|
+
export interface McpToolImplementation extends McpToolDescriptor {
|
|
26
|
+
handler: (input: unknown) => Promise<unknown>;
|
|
27
|
+
}
|
|
28
|
+
/** Shape of the JSON config consumed by `claude --mcp-config <path>`. */
|
|
29
|
+
export interface McpConfigFile {
|
|
30
|
+
mcpServers: Record<string, McpServerConfig>;
|
|
31
|
+
}
|
|
32
|
+
export type McpServerStatus = "ready" | "error" | "not_registered";
|
|
33
|
+
export interface McpServerStatusResult {
|
|
34
|
+
serverId: string;
|
|
35
|
+
status: McpServerStatus;
|
|
36
|
+
message?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Daemon-side registry of tool metadata. adaria-ai only ever spawns one
|
|
40
|
+
* MCP server (the bundled marketing tool host), so tools are flat rather
|
|
41
|
+
* than grouped per server.
|
|
42
|
+
*/
|
|
43
|
+
export declare class McpManager {
|
|
44
|
+
private tools;
|
|
45
|
+
/** Register a tool descriptor. Throws on duplicate id. */
|
|
46
|
+
registerTool(descriptor: McpToolDescriptor): void;
|
|
47
|
+
unregisterTool(id: string): boolean;
|
|
48
|
+
getTool(id: string): McpToolDescriptor | undefined;
|
|
49
|
+
getRegisteredTools(): McpToolDescriptor[];
|
|
50
|
+
getToolCount(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Builds the system-prompt text describing registered tools. Returns ''
|
|
53
|
+
* when no tools are registered so callers can unconditionally concat
|
|
54
|
+
* this into a larger system prompt.
|
|
55
|
+
*/
|
|
56
|
+
buildMcpContext(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Produces the `mcp-config.json` shape Claude CLI expects, or `null`
|
|
59
|
+
* when there are no tools to expose. Mirrors pilot-ai's
|
|
60
|
+
* `getMcpConfigPathIfExists` convention so `core.ts` can `if (path)`-
|
|
61
|
+
* guard the `--mcp-config` flag and skip it entirely in M1.
|
|
62
|
+
*
|
|
63
|
+
* M5.5 will extend this to emit a single `adaria` server whose command
|
|
64
|
+
* points at the bundled tool-host entry via `mcp-launcher`.
|
|
65
|
+
*/
|
|
66
|
+
buildMcpConfig(): McpConfigFile | null;
|
|
67
|
+
/**
|
|
68
|
+
* Writes the MCP config to disk at 0600 and returns the absolute path.
|
|
69
|
+
* Returns `null` (without touching disk) when no tools are registered,
|
|
70
|
+
* so core.ts can skip the `--mcp-config` flag.
|
|
71
|
+
*/
|
|
72
|
+
writeMcpConfig(outputPath?: string): Promise<string | null>;
|
|
73
|
+
/**
|
|
74
|
+
* Health-check stub. In M1 this returns an empty array — there are no
|
|
75
|
+
* servers to probe. M5.5 replaces this with a real stdio JSON-RPC ping
|
|
76
|
+
* against the bundled adaria tool-host and wires it into
|
|
77
|
+
* `adaria-ai doctor`.
|
|
78
|
+
*/
|
|
79
|
+
checkMcpServerHealth(): Promise<McpServerStatusResult[]>;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=mcp-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-manager.d.ts","sourceRoot":"","sources":["../../src/agent/mcp-manager.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,mBAAmB,CAAC;AAM7E,kEAAkE;AAClE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,WAAW,EAAE,cAAc,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/C;AAED,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,gBAAgB,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAwC;IAErD,0DAA0D;IAC1D,YAAY,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI;IAOjD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAInC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIlD,kBAAkB,IAAI,iBAAiB,EAAE;IAIzC,YAAY,IAAI,MAAM;IAItB;;;;OAIG;IACH,eAAe,IAAI,MAAM;IAezB;;;;;;;;OAQG;IACH,cAAc,IAAI,aAAa,GAAG,IAAI;IActC;;;;OAIG;IACG,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUjE;;;;;OAKG;IAKG,oBAAoB,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;CAG/D"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP framework — minimal M1 skeleton.
|
|
3
|
+
*
|
|
4
|
+
* Pilot-ai's mcp-manager is scaffolded around installing third-party npm MCP
|
|
5
|
+
* servers (Gmail, Slack, Figma) with Keychain-backed launcher scripts. None
|
|
6
|
+
* of that applies to adaria-ai: our Mode B tools (`db-query`,
|
|
7
|
+
* `collector-fetch`, `skill-result`, `app-info`) are in-process code that
|
|
8
|
+
* ships with adaria-ai itself, not external packages the user installs.
|
|
9
|
+
*
|
|
10
|
+
* This file therefore carries only the shape M5.5 will need.
|
|
11
|
+
*
|
|
12
|
+
* ## Process-boundary note (M1 review H1)
|
|
13
|
+
*
|
|
14
|
+
* Claude CLI spawns the MCP server as a **separate subprocess** and talks
|
|
15
|
+
* to it over stdio JSON-RPC. That means the daemon's `McpManager` and the
|
|
16
|
+
* tool-host's registry live in different processes — a handler function
|
|
17
|
+
* registered on the daemon's Map would never be callable by Claude.
|
|
18
|
+
*
|
|
19
|
+
* To keep this honest in the type system:
|
|
20
|
+
* - `McpToolDescriptor` is metadata only (id, name, description, schema).
|
|
21
|
+
* The daemon holds descriptors and uses them to build the system-prompt
|
|
22
|
+
* context and the `mcp-config.json` Claude consumes.
|
|
23
|
+
* - `McpToolImplementation extends McpToolDescriptor` and carries the
|
|
24
|
+
* `handler` function. It lives inside the tool-host subprocess (M5.5).
|
|
25
|
+
* The daemon never sees `handler` and therefore cannot mistakenly
|
|
26
|
+
* invoke it in-process.
|
|
27
|
+
*
|
|
28
|
+
* M1 exit criterion: the daemon boots with zero tools registered,
|
|
29
|
+
* `buildMcpContext()` returns '', and `writeMcpConfig()` returns `null` so
|
|
30
|
+
* `core.ts` can skip the `--mcp-config` flag entirely (mirrors pilot-ai's
|
|
31
|
+
* `getMcpConfigPathIfExists` / `claude.ts` guard pattern).
|
|
32
|
+
*/
|
|
33
|
+
import fs from "node:fs/promises";
|
|
34
|
+
import path from "node:path";
|
|
35
|
+
import { fileURLToPath } from "node:url";
|
|
36
|
+
// ADARIA_HOME is an eager const from paths.ts. Tests that need a custom
|
|
37
|
+
// $ADARIA_HOME set `process.env["ADARIA_HOME"]` before `await import()`-ing
|
|
38
|
+
// this module — same convention as session/audit/memory/logger.
|
|
39
|
+
import { ADARIA_HOME } from "../utils/paths.js";
|
|
40
|
+
import { buildToolHostServerConfig } from "./mcp-launcher.js";
|
|
41
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
42
|
+
const TOOL_HOST_ENTRY = path.resolve(path.dirname(thisFile), "..", "tools", "tool-host.js");
|
|
43
|
+
/**
|
|
44
|
+
* Daemon-side registry of tool metadata. adaria-ai only ever spawns one
|
|
45
|
+
* MCP server (the bundled marketing tool host), so tools are flat rather
|
|
46
|
+
* than grouped per server.
|
|
47
|
+
*/
|
|
48
|
+
export class McpManager {
|
|
49
|
+
tools = new Map();
|
|
50
|
+
/** Register a tool descriptor. Throws on duplicate id. */
|
|
51
|
+
registerTool(descriptor) {
|
|
52
|
+
if (this.tools.has(descriptor.id)) {
|
|
53
|
+
throw new Error(`MCP tool already registered: ${descriptor.id}`);
|
|
54
|
+
}
|
|
55
|
+
this.tools.set(descriptor.id, descriptor);
|
|
56
|
+
}
|
|
57
|
+
unregisterTool(id) {
|
|
58
|
+
return this.tools.delete(id);
|
|
59
|
+
}
|
|
60
|
+
getTool(id) {
|
|
61
|
+
return this.tools.get(id);
|
|
62
|
+
}
|
|
63
|
+
getRegisteredTools() {
|
|
64
|
+
return Array.from(this.tools.values());
|
|
65
|
+
}
|
|
66
|
+
getToolCount() {
|
|
67
|
+
return this.tools.size;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Builds the system-prompt text describing registered tools. Returns ''
|
|
71
|
+
* when no tools are registered so callers can unconditionally concat
|
|
72
|
+
* this into a larger system prompt.
|
|
73
|
+
*/
|
|
74
|
+
buildMcpContext() {
|
|
75
|
+
if (this.tools.size === 0)
|
|
76
|
+
return "";
|
|
77
|
+
const lines = [];
|
|
78
|
+
lines.push("MCP TOOLS AVAILABLE:");
|
|
79
|
+
lines.push("These are read-only marketing tools. Use them to answer questions about apps, rankings, reviews, and prior analyses. They CANNOT write to the database or trigger skill write paths.");
|
|
80
|
+
lines.push("");
|
|
81
|
+
for (const tool of this.getRegisteredTools()) {
|
|
82
|
+
lines.push(`- mcp__adaria__${tool.id} — ${tool.description}`);
|
|
83
|
+
}
|
|
84
|
+
return lines.join("\n");
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Produces the `mcp-config.json` shape Claude CLI expects, or `null`
|
|
88
|
+
* when there are no tools to expose. Mirrors pilot-ai's
|
|
89
|
+
* `getMcpConfigPathIfExists` convention so `core.ts` can `if (path)`-
|
|
90
|
+
* guard the `--mcp-config` flag and skip it entirely in M1.
|
|
91
|
+
*
|
|
92
|
+
* M5.5 will extend this to emit a single `adaria` server whose command
|
|
93
|
+
* points at the bundled tool-host entry via `mcp-launcher`.
|
|
94
|
+
*/
|
|
95
|
+
buildMcpConfig() {
|
|
96
|
+
if (this.tools.size === 0)
|
|
97
|
+
return null;
|
|
98
|
+
const spec = {
|
|
99
|
+
entryPoint: TOOL_HOST_ENTRY,
|
|
100
|
+
};
|
|
101
|
+
if (process.env["ADARIA_HOME"]) {
|
|
102
|
+
spec.env = { ADARIA_HOME: process.env["ADARIA_HOME"] };
|
|
103
|
+
}
|
|
104
|
+
const adariaServer = buildToolHostServerConfig(spec);
|
|
105
|
+
return { mcpServers: { adaria: adariaServer } };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Writes the MCP config to disk at 0600 and returns the absolute path.
|
|
109
|
+
* Returns `null` (without touching disk) when no tools are registered,
|
|
110
|
+
* so core.ts can skip the `--mcp-config` flag.
|
|
111
|
+
*/
|
|
112
|
+
async writeMcpConfig(outputPath) {
|
|
113
|
+
const config = this.buildMcpConfig();
|
|
114
|
+
if (config === null)
|
|
115
|
+
return null;
|
|
116
|
+
const target = outputPath ?? path.join(ADARIA_HOME, "mcp-config.json");
|
|
117
|
+
await fs.writeFile(target, JSON.stringify(config, null, 2), {
|
|
118
|
+
mode: 0o600,
|
|
119
|
+
});
|
|
120
|
+
return target;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Health-check stub. In M1 this returns an empty array — there are no
|
|
124
|
+
* servers to probe. M5.5 replaces this with a real stdio JSON-RPC ping
|
|
125
|
+
* against the bundled adaria tool-host and wires it into
|
|
126
|
+
* `adaria-ai doctor`.
|
|
127
|
+
*/
|
|
128
|
+
// M5.5 will turn this into a real stdio JSON-RPC ping against the tool
|
|
129
|
+
// host, which is genuinely I/O-bound; keeping the signature async now
|
|
130
|
+
// avoids churning every caller when that lands.
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
132
|
+
async checkMcpServerHealth() {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=mcp-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-manager.js","sourceRoot":"","sources":["../../src/agent/mcp-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function readUserMemory(): Promise<string>;
|
|
2
|
+
export declare function writeUserMemory(content: string): Promise<void>;
|
|
3
|
+
export declare function appendUserMemory(entry: string): Promise<void>;
|
|
4
|
+
export declare function appendHistory(entry: string): Promise<void>;
|
|
5
|
+
export declare function readHistory(date?: Date): Promise<string>;
|
|
6
|
+
export declare function getRecentHistory(days?: number): Promise<string>;
|
|
7
|
+
export declare function buildMemoryContext(): Promise<string>;
|
|
8
|
+
/** Test-only reset. */
|
|
9
|
+
export declare function resetMemory(): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agent/memory.ts"],"names":[],"mappings":"AA0BA,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAMtD;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpE;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAInE;AAID,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhE;AAED,wBAAsB,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAM9D;AAED,wBAAsB,gBAAgB,CAAC,IAAI,SAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAehE;AAID,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAc1D;AAED,uBAAuB;AACvB,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAMjD"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-project-scoped memory for adaria-ai.
|
|
3
|
+
*
|
|
4
|
+
* adaria-ai is a single-user marketing daemon with no concept of projects,
|
|
5
|
+
* so the project-scoped memory from pilot-ai is dropped. What remains:
|
|
6
|
+
* a rolling user-preferences file and a day-indexed history log that the
|
|
7
|
+
* daemon can inject into Claude's system prompt for cross-session context.
|
|
8
|
+
*/
|
|
9
|
+
import fs from "node:fs/promises";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { MEMORY_DIR } from "../utils/paths.js";
|
|
12
|
+
const MAX_MEMORY_LINES = 200;
|
|
13
|
+
function getMemoryFilePath() {
|
|
14
|
+
return path.join(MEMORY_DIR, "MEMORY.md");
|
|
15
|
+
}
|
|
16
|
+
function getHistoryPath(date) {
|
|
17
|
+
const d = date ?? new Date();
|
|
18
|
+
const dateStr = d.toISOString().split("T")[0];
|
|
19
|
+
return path.join(MEMORY_DIR, "history", `${dateStr}.md`);
|
|
20
|
+
}
|
|
21
|
+
// --- MEMORY.md (user preferences) ---
|
|
22
|
+
export async function readUserMemory() {
|
|
23
|
+
try {
|
|
24
|
+
return await fs.readFile(getMemoryFilePath(), "utf-8");
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function writeUserMemory(content) {
|
|
31
|
+
const lines = content.split("\n");
|
|
32
|
+
const trimmed = lines.slice(0, MAX_MEMORY_LINES).join("\n");
|
|
33
|
+
await fs.mkdir(MEMORY_DIR, { recursive: true, mode: 0o700 });
|
|
34
|
+
await fs.writeFile(getMemoryFilePath(), trimmed);
|
|
35
|
+
}
|
|
36
|
+
export async function appendUserMemory(entry) {
|
|
37
|
+
const existing = await readUserMemory();
|
|
38
|
+
const updated = existing ? `${existing}\n${entry}` : entry;
|
|
39
|
+
await writeUserMemory(updated);
|
|
40
|
+
}
|
|
41
|
+
// --- History ---
|
|
42
|
+
export async function appendHistory(entry) {
|
|
43
|
+
const histPath = getHistoryPath();
|
|
44
|
+
await fs.mkdir(path.dirname(histPath), { recursive: true, mode: 0o700 });
|
|
45
|
+
const timestamp = new Date().toLocaleTimeString("en-US", {
|
|
46
|
+
hour: "2-digit",
|
|
47
|
+
minute: "2-digit",
|
|
48
|
+
});
|
|
49
|
+
const line = `- ${timestamp}: ${entry}\n`;
|
|
50
|
+
await fs.appendFile(histPath, line);
|
|
51
|
+
}
|
|
52
|
+
export async function readHistory(date) {
|
|
53
|
+
try {
|
|
54
|
+
return await fs.readFile(getHistoryPath(date), "utf-8");
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return "";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export async function getRecentHistory(days = 3) {
|
|
61
|
+
const entries = [];
|
|
62
|
+
const now = new Date();
|
|
63
|
+
for (let i = 0; i < days; i++) {
|
|
64
|
+
const d = new Date(now);
|
|
65
|
+
d.setDate(d.getDate() - i);
|
|
66
|
+
const content = await readHistory(d);
|
|
67
|
+
if (content) {
|
|
68
|
+
const dateStr = d.toISOString().split("T")[0];
|
|
69
|
+
entries.push(`### ${dateStr}\n${content}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return entries.join("\n\n");
|
|
73
|
+
}
|
|
74
|
+
// --- Assemble memory context for prompts ---
|
|
75
|
+
export async function buildMemoryContext() {
|
|
76
|
+
const parts = [];
|
|
77
|
+
const userMemory = await readUserMemory();
|
|
78
|
+
if (userMemory) {
|
|
79
|
+
parts.push(`<USER_PREFERENCES>\n${userMemory}\n</USER_PREFERENCES>`);
|
|
80
|
+
}
|
|
81
|
+
const history = await getRecentHistory(3);
|
|
82
|
+
if (history) {
|
|
83
|
+
parts.push(`<RECENT_HISTORY>\n${history}\n</RECENT_HISTORY>`);
|
|
84
|
+
}
|
|
85
|
+
return parts.join("\n\n");
|
|
86
|
+
}
|
|
87
|
+
/** Test-only reset. */
|
|
88
|
+
export async function resetMemory() {
|
|
89
|
+
await fs.rm(MEMORY_DIR, { recursive: true, force: true });
|
|
90
|
+
await fs.mkdir(path.join(MEMORY_DIR, "history"), {
|
|
91
|
+
recursive: true,
|
|
92
|
+
mode: 0o700,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/agent/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base approval infrastructure for adaria-ai.
|
|
3
|
+
*
|
|
4
|
+
* M1 ships the pilot-ai ApprovalManager skeleton: a taskId → pending-promise
|
|
5
|
+
* registry with a timeout fallback. The growth-agent domain gates
|
|
6
|
+
* (`blog_publish`, `metadata_change`, `review_reply`, `sdk_request`) are
|
|
7
|
+
* merged on top in M5 once the skills that produce them land.
|
|
8
|
+
*
|
|
9
|
+
* Pilot-ai's shell-oriented `classifySafety` / DANGEROUS_PATTERNS classifier
|
|
10
|
+
* is intentionally dropped — adaria-ai has no shell tool, and its
|
|
11
|
+
* approvals are always domain-tagged, never inferred from regex.
|
|
12
|
+
*/
|
|
13
|
+
export type ApprovalGate = "blog_publish" | "metadata_change" | "review_reply" | "sdk_request" | "social_publish";
|
|
14
|
+
export interface PendingApproval {
|
|
15
|
+
taskId: string;
|
|
16
|
+
action: string;
|
|
17
|
+
resolve: (approved: boolean) => void;
|
|
18
|
+
timer: ReturnType<typeof setTimeout>;
|
|
19
|
+
}
|
|
20
|
+
export declare class ApprovalManager {
|
|
21
|
+
private pending;
|
|
22
|
+
private shuttingDown;
|
|
23
|
+
/**
|
|
24
|
+
* Registers a pending approval and returns a Promise that resolves once
|
|
25
|
+
* `handleResponse` is called with the same taskId, or resolves to `false`
|
|
26
|
+
* when the timeout fires.
|
|
27
|
+
*
|
|
28
|
+
* Fails fast if a request for the same `taskId` is already pending — the
|
|
29
|
+
* old behavior silently overwrote the Map entry, stranding the original
|
|
30
|
+
* promise's resolver forever and leaving the first timer to evict the
|
|
31
|
+
* new entry when it fired (M1 safety review HIGH).
|
|
32
|
+
*
|
|
33
|
+
* Also fails fast once `shutdown()` has been called, so M5 write-path
|
|
34
|
+
* skills observe a clean rejection during daemon teardown rather than
|
|
35
|
+
* hanging until their timeout.
|
|
36
|
+
*/
|
|
37
|
+
requestApproval(taskId: string, action: string, timeoutMs: number): Promise<boolean>;
|
|
38
|
+
/** Resolves the pending approval for `taskId`. Returns false if unknown. */
|
|
39
|
+
handleResponse(taskId: string, approved: boolean): boolean;
|
|
40
|
+
hasPending(taskId: string): boolean;
|
|
41
|
+
getPendingCount(): number;
|
|
42
|
+
/** Cancels every pending approval (for clean daemon shutdown). */
|
|
43
|
+
shutdown(): void;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=safety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/agent/safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,gBAAgB,CAAC;AAErB,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,KAAK,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;CACtC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,YAAY,CAAS;IAE7B;;;;;;;;;;;;;OAaG;IACH,eAAe,CACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAyBnB,4EAA4E;IAC5E,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO;IAU1D,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAInC,eAAe,IAAI,MAAM;IAIzB,kEAAkE;IAClE,QAAQ,IAAI,IAAI;CAQjB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base approval infrastructure for adaria-ai.
|
|
3
|
+
*
|
|
4
|
+
* M1 ships the pilot-ai ApprovalManager skeleton: a taskId → pending-promise
|
|
5
|
+
* registry with a timeout fallback. The growth-agent domain gates
|
|
6
|
+
* (`blog_publish`, `metadata_change`, `review_reply`, `sdk_request`) are
|
|
7
|
+
* merged on top in M5 once the skills that produce them land.
|
|
8
|
+
*
|
|
9
|
+
* Pilot-ai's shell-oriented `classifySafety` / DANGEROUS_PATTERNS classifier
|
|
10
|
+
* is intentionally dropped — adaria-ai has no shell tool, and its
|
|
11
|
+
* approvals are always domain-tagged, never inferred from regex.
|
|
12
|
+
*/
|
|
13
|
+
export class ApprovalManager {
|
|
14
|
+
pending = new Map();
|
|
15
|
+
shuttingDown = false;
|
|
16
|
+
/**
|
|
17
|
+
* Registers a pending approval and returns a Promise that resolves once
|
|
18
|
+
* `handleResponse` is called with the same taskId, or resolves to `false`
|
|
19
|
+
* when the timeout fires.
|
|
20
|
+
*
|
|
21
|
+
* Fails fast if a request for the same `taskId` is already pending — the
|
|
22
|
+
* old behavior silently overwrote the Map entry, stranding the original
|
|
23
|
+
* promise's resolver forever and leaving the first timer to evict the
|
|
24
|
+
* new entry when it fired (M1 safety review HIGH).
|
|
25
|
+
*
|
|
26
|
+
* Also fails fast once `shutdown()` has been called, so M5 write-path
|
|
27
|
+
* skills observe a clean rejection during daemon teardown rather than
|
|
28
|
+
* hanging until their timeout.
|
|
29
|
+
*/
|
|
30
|
+
requestApproval(taskId, action, timeoutMs) {
|
|
31
|
+
if (this.shuttingDown) {
|
|
32
|
+
return Promise.reject(new Error(`ApprovalManager is shutting down; refusing approval request for "${taskId}"`));
|
|
33
|
+
}
|
|
34
|
+
if (this.pending.has(taskId)) {
|
|
35
|
+
return Promise.reject(new Error(`Duplicate approval request for taskId "${taskId}"; a prior request is still pending`));
|
|
36
|
+
}
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
const timer = setTimeout(() => {
|
|
39
|
+
this.pending.delete(taskId);
|
|
40
|
+
resolve(false);
|
|
41
|
+
}, timeoutMs);
|
|
42
|
+
this.pending.set(taskId, { taskId, action, resolve, timer });
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** Resolves the pending approval for `taskId`. Returns false if unknown. */
|
|
46
|
+
handleResponse(taskId, approved) {
|
|
47
|
+
const entry = this.pending.get(taskId);
|
|
48
|
+
if (!entry)
|
|
49
|
+
return false;
|
|
50
|
+
clearTimeout(entry.timer);
|
|
51
|
+
this.pending.delete(taskId);
|
|
52
|
+
entry.resolve(approved);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
hasPending(taskId) {
|
|
56
|
+
return this.pending.has(taskId);
|
|
57
|
+
}
|
|
58
|
+
getPendingCount() {
|
|
59
|
+
return this.pending.size;
|
|
60
|
+
}
|
|
61
|
+
/** Cancels every pending approval (for clean daemon shutdown). */
|
|
62
|
+
shutdown() {
|
|
63
|
+
this.shuttingDown = true;
|
|
64
|
+
for (const entry of this.pending.values()) {
|
|
65
|
+
clearTimeout(entry.timer);
|
|
66
|
+
entry.resolve(false);
|
|
67
|
+
}
|
|
68
|
+
this.pending.clear();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../../src/agent/safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgBH,MAAM,OAAO,eAAe;IAClB,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC7C,YAAY,GAAG,KAAK,CAAC;IAE7B;;;;;;;;;;;;;OAaG;IACH,eAAe,CACb,MAAc,EACd,MAAc,EACd,SAAiB;QAEjB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CACP,oEAAoE,MAAM,GAAG,CAC9E,CACF,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CACP,0CAA0C,MAAM,qCAAqC,CACtF,CACF,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;YACtC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC5B,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,cAAc,CAAC,MAAc,EAAE,QAAiB;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAEzB,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU,CAAC,MAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,kEAAkE;IAClE,QAAQ;QACN,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface SessionEntry {
|
|
2
|
+
/** Claude CLI session ID (UUID) */
|
|
3
|
+
sessionId: string;
|
|
4
|
+
/** Messenger thread ID */
|
|
5
|
+
threadId: string;
|
|
6
|
+
/** Channel ID */
|
|
7
|
+
channelId: string;
|
|
8
|
+
/** Platform — slack only for adaria-ai, left generic for future messengers */
|
|
9
|
+
platform: "slack";
|
|
10
|
+
/** When this session was created */
|
|
11
|
+
createdAt: string;
|
|
12
|
+
/** When this session was last used */
|
|
13
|
+
lastUsedAt: string;
|
|
14
|
+
/** Number of turns in this session */
|
|
15
|
+
turnCount: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function getSession(platform: string, channelId: string, threadId: string): Promise<SessionEntry | null>;
|
|
18
|
+
export declare function createSession(platform: "slack", channelId: string, threadId: string, explicitSessionId?: string): Promise<SessionEntry>;
|
|
19
|
+
export declare function touchSession(platform: string, channelId: string, threadId: string): Promise<void>;
|
|
20
|
+
/** Deletes a specific session. Used for error recovery (msg_too_long). */
|
|
21
|
+
export declare function deleteSession(platform: string, channelId: string, threadId: string): Promise<boolean>;
|
|
22
|
+
export declare function cleanupSessions(): Promise<number>;
|
|
23
|
+
export declare function getSessionCount(): Promise<number>;
|
|
24
|
+
export declare function getRemainingTurns(entry: SessionEntry): number;
|
|
25
|
+
/** Test-only reset. */
|
|
26
|
+
export declare function resetSessionStore(): void;
|
|
27
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;CACnB;AAuCD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAoB9B;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,YAAY,CAAC,CAuBvB;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CASf;AAED,0EAA0E;AAC1E,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAavD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAGvD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAE7D;AAED,uBAAuB;AACvB,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session store for mapping Slack threads to Claude CLI sessions.
|
|
3
|
+
* Enables multi-turn conversations where each Slack thread maintains a
|
|
4
|
+
* continuous Claude session with full context.
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs/promises";
|
|
7
|
+
import crypto from "node:crypto";
|
|
8
|
+
import { SESSIONS_PATH } from "../utils/paths.js";
|
|
9
|
+
const SESSION_TTL_MS = 24 * 60 * 60 * 1000;
|
|
10
|
+
const MAX_SESSION_TURNS = 10;
|
|
11
|
+
let sessions = new Map();
|
|
12
|
+
let loadPromise = null;
|
|
13
|
+
function threadKey(platform, channelId, threadId) {
|
|
14
|
+
return `${platform}:${channelId}:${threadId}`;
|
|
15
|
+
}
|
|
16
|
+
async function ensureLoaded() {
|
|
17
|
+
if (loadPromise)
|
|
18
|
+
return loadPromise;
|
|
19
|
+
loadPromise = (async () => {
|
|
20
|
+
try {
|
|
21
|
+
const data = await fs.readFile(SESSIONS_PATH, "utf-8");
|
|
22
|
+
const entries = JSON.parse(data);
|
|
23
|
+
sessions = new Map(entries.map((e) => [threadKey(e.platform, e.channelId, e.threadId), e]));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
sessions = new Map();
|
|
27
|
+
}
|
|
28
|
+
})();
|
|
29
|
+
return loadPromise;
|
|
30
|
+
}
|
|
31
|
+
async function save() {
|
|
32
|
+
const entries = Array.from(sessions.values());
|
|
33
|
+
await fs.writeFile(SESSIONS_PATH, JSON.stringify(entries, null, 2), {
|
|
34
|
+
mode: 0o600,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export async function getSession(platform, channelId, threadId) {
|
|
38
|
+
await ensureLoaded();
|
|
39
|
+
const key = threadKey(platform, channelId, threadId);
|
|
40
|
+
const entry = sessions.get(key);
|
|
41
|
+
if (!entry)
|
|
42
|
+
return null;
|
|
43
|
+
const age = Date.now() - new Date(entry.lastUsedAt).getTime();
|
|
44
|
+
if (age > SESSION_TTL_MS) {
|
|
45
|
+
sessions.delete(key);
|
|
46
|
+
await save();
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
if (entry.turnCount >= MAX_SESSION_TURNS) {
|
|
50
|
+
sessions.delete(key);
|
|
51
|
+
await save();
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return entry;
|
|
55
|
+
}
|
|
56
|
+
export async function createSession(platform, channelId, threadId, explicitSessionId) {
|
|
57
|
+
await ensureLoaded();
|
|
58
|
+
const entry = {
|
|
59
|
+
// When `explicitSessionId` is provided, the caller is responsible for
|
|
60
|
+
// ensuring the same UUID is handed to Claude CLI via `--session-id`.
|
|
61
|
+
// The msg_too_long fallback in `core.ts` relies on this to keep the
|
|
62
|
+
// stored mapping and Claude's actual session in lock-step; otherwise
|
|
63
|
+
// the next message on the thread would `--resume` a UUID Claude has
|
|
64
|
+
// never seen (M1 core review HIGH #1).
|
|
65
|
+
sessionId: explicitSessionId ?? crypto.randomUUID(),
|
|
66
|
+
threadId,
|
|
67
|
+
channelId,
|
|
68
|
+
platform,
|
|
69
|
+
createdAt: new Date().toISOString(),
|
|
70
|
+
lastUsedAt: new Date().toISOString(),
|
|
71
|
+
turnCount: 1,
|
|
72
|
+
};
|
|
73
|
+
const key = threadKey(platform, channelId, threadId);
|
|
74
|
+
sessions.set(key, entry);
|
|
75
|
+
await save();
|
|
76
|
+
return entry;
|
|
77
|
+
}
|
|
78
|
+
export async function touchSession(platform, channelId, threadId) {
|
|
79
|
+
await ensureLoaded();
|
|
80
|
+
const key = threadKey(platform, channelId, threadId);
|
|
81
|
+
const entry = sessions.get(key);
|
|
82
|
+
if (entry) {
|
|
83
|
+
entry.lastUsedAt = new Date().toISOString();
|
|
84
|
+
entry.turnCount++;
|
|
85
|
+
await save();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Deletes a specific session. Used for error recovery (msg_too_long). */
|
|
89
|
+
export async function deleteSession(platform, channelId, threadId) {
|
|
90
|
+
await ensureLoaded();
|
|
91
|
+
const key = threadKey(platform, channelId, threadId);
|
|
92
|
+
const deleted = sessions.delete(key);
|
|
93
|
+
if (deleted)
|
|
94
|
+
await save();
|
|
95
|
+
return deleted;
|
|
96
|
+
}
|
|
97
|
+
export async function cleanupSessions() {
|
|
98
|
+
await ensureLoaded();
|
|
99
|
+
const now = Date.now();
|
|
100
|
+
let removed = 0;
|
|
101
|
+
for (const [key, entry] of sessions) {
|
|
102
|
+
const age = now - new Date(entry.lastUsedAt).getTime();
|
|
103
|
+
if (age > SESSION_TTL_MS) {
|
|
104
|
+
sessions.delete(key);
|
|
105
|
+
removed++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (removed > 0)
|
|
109
|
+
await save();
|
|
110
|
+
return removed;
|
|
111
|
+
}
|
|
112
|
+
export async function getSessionCount() {
|
|
113
|
+
await ensureLoaded();
|
|
114
|
+
return sessions.size;
|
|
115
|
+
}
|
|
116
|
+
export function getRemainingTurns(entry) {
|
|
117
|
+
return Math.max(0, MAX_SESSION_TURNS - entry.turnCount);
|
|
118
|
+
}
|
|
119
|
+
/** Test-only reset. */
|
|
120
|
+
export function resetSessionStore() {
|
|
121
|
+
sessions = new Map();
|
|
122
|
+
loadPromise = null;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool description text injected into the Mode B system prompt.
|
|
3
|
+
*
|
|
4
|
+
* Describes the 4 marketing MCP tools so Claude knows how and when
|
|
5
|
+
* to call them. All tools are strictly read-only.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildToolDescriptions(): string;
|
|
8
|
+
//# sourceMappingURL=tool-descriptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-descriptions.d.ts","sourceRoot":"","sources":["../../src/agent/tool-descriptions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAkB9C"}
|