boten-gemma 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/README.md +860 -0
- package/dist/automation/cron/index.d.ts +6 -0
- package/dist/automation/cron/index.d.ts.map +1 -0
- package/dist/automation/cron/index.js +4 -0
- package/dist/automation/cron/index.js.map +1 -0
- package/dist/automation/cron/parse-schedule.d.ts +11 -0
- package/dist/automation/cron/parse-schedule.d.ts.map +1 -0
- package/dist/automation/cron/parse-schedule.js +36 -0
- package/dist/automation/cron/parse-schedule.js.map +1 -0
- package/dist/automation/cron/schedule.d.ts +7 -0
- package/dist/automation/cron/schedule.d.ts.map +1 -0
- package/dist/automation/cron/schedule.js +28 -0
- package/dist/automation/cron/schedule.js.map +1 -0
- package/dist/automation/cron/service.d.ts +70 -0
- package/dist/automation/cron/service.d.ts.map +1 -0
- package/dist/automation/cron/service.js +207 -0
- package/dist/automation/cron/service.js.map +1 -0
- package/dist/automation/cron/store.d.ts +12 -0
- package/dist/automation/cron/store.d.ts.map +1 -0
- package/dist/automation/cron/store.js +27 -0
- package/dist/automation/cron/store.js.map +1 -0
- package/dist/automation/cron/types.d.ts +67 -0
- package/dist/automation/cron/types.d.ts.map +1 -0
- package/dist/automation/cron/types.js +5 -0
- package/dist/automation/cron/types.js.map +1 -0
- package/dist/automation/cron.d.ts +15 -0
- package/dist/automation/cron.d.ts.map +1 -0
- package/dist/automation/cron.js +10 -0
- package/dist/automation/cron.js.map +1 -0
- package/dist/automation/heartbeat.d.ts +14 -0
- package/dist/automation/heartbeat.d.ts.map +1 -0
- package/dist/automation/heartbeat.js +27 -0
- package/dist/automation/heartbeat.js.map +1 -0
- package/dist/channels/cli.d.ts +17 -0
- package/dist/channels/cli.d.ts.map +1 -0
- package/dist/channels/cli.js +125 -0
- package/dist/channels/cli.js.map +1 -0
- package/dist/channels/telegram.d.ts +27 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +288 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/types.d.ts +50 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +6 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/channels/web.d.ts +149 -0
- package/dist/channels/web.d.ts.map +1 -0
- package/dist/channels/web.js +1113 -0
- package/dist/channels/web.js.map +1 -0
- package/dist/config/defaults.d.ts +11 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +80 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/loader.d.ts +22 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +158 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +261 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +119 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/confirm/audit.d.ts +34 -0
- package/dist/confirm/audit.d.ts.map +1 -0
- package/dist/confirm/audit.js +49 -0
- package/dist/confirm/audit.js.map +1 -0
- package/dist/confirm/auto-approve.d.ts +20 -0
- package/dist/confirm/auto-approve.d.ts.map +1 -0
- package/dist/confirm/auto-approve.js +62 -0
- package/dist/confirm/auto-approve.js.map +1 -0
- package/dist/confirm/gate.d.ts +50 -0
- package/dist/confirm/gate.d.ts.map +1 -0
- package/dist/confirm/gate.js +138 -0
- package/dist/confirm/gate.js.map +1 -0
- package/dist/confirm/parser.d.ts +23 -0
- package/dist/confirm/parser.d.ts.map +1 -0
- package/dist/confirm/parser.js +76 -0
- package/dist/confirm/parser.js.map +1 -0
- package/dist/confirm/presenter.d.ts +23 -0
- package/dist/confirm/presenter.d.ts.map +1 -0
- package/dist/confirm/presenter.js +92 -0
- package/dist/confirm/presenter.js.map +1 -0
- package/dist/core/agent-loop.d.ts +44 -0
- package/dist/core/agent-loop.d.ts.map +1 -0
- package/dist/core/agent-loop.js +156 -0
- package/dist/core/agent-loop.js.map +1 -0
- package/dist/core/compaction.d.ts +17 -0
- package/dist/core/compaction.d.ts.map +1 -0
- package/dist/core/compaction.js +70 -0
- package/dist/core/compaction.js.map +1 -0
- package/dist/core/context-builder.d.ts +38 -0
- package/dist/core/context-builder.d.ts.map +1 -0
- package/dist/core/context-builder.js +137 -0
- package/dist/core/context-builder.js.map +1 -0
- package/dist/core/logger.d.ts +42 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +95 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/queue.d.ts +25 -0
- package/dist/core/queue.d.ts.map +1 -0
- package/dist/core/queue.js +33 -0
- package/dist/core/queue.js.map +1 -0
- package/dist/core/router.d.ts +21 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/router.js +27 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/session-store.d.ts +53 -0
- package/dist/core/session-store.d.ts.map +1 -0
- package/dist/core/session-store.js +367 -0
- package/dist/core/session-store.js.map +1 -0
- package/dist/core/session.d.ts +89 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +49 -0
- package/dist/core/session.js.map +1 -0
- package/dist/daemon/launchd.d.ts +8 -0
- package/dist/daemon/launchd.d.ts.map +1 -0
- package/dist/daemon/launchd.js +155 -0
- package/dist/daemon/launchd.js.map +1 -0
- package/dist/daemon/service.d.ts +12 -0
- package/dist/daemon/service.d.ts.map +1 -0
- package/dist/daemon/service.js +42 -0
- package/dist/daemon/service.js.map +1 -0
- package/dist/daemon/systemd.d.ts +11 -0
- package/dist/daemon/systemd.d.ts.map +1 -0
- package/dist/daemon/systemd.js +145 -0
- package/dist/daemon/systemd.js.map +1 -0
- package/dist/daemon/types.d.ts +14 -0
- package/dist/daemon/types.d.ts.map +1 -0
- package/dist/daemon/types.js +2 -0
- package/dist/daemon/types.js.map +1 -0
- package/dist/daemon/update.d.ts +41 -0
- package/dist/daemon/update.d.ts.map +1 -0
- package/dist/daemon/update.js +106 -0
- package/dist/daemon/update.js.map +1 -0
- package/dist/gateway.d.ts +103 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +1063 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +572 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/auth/oauth-callback.d.ts +20 -0
- package/dist/llm/auth/oauth-callback.d.ts.map +1 -0
- package/dist/llm/auth/oauth-callback.js +95 -0
- package/dist/llm/auth/oauth-callback.js.map +1 -0
- package/dist/llm/auth/oauth.d.ts +30 -0
- package/dist/llm/auth/oauth.d.ts.map +1 -0
- package/dist/llm/auth/oauth.js +331 -0
- package/dist/llm/auth/oauth.js.map +1 -0
- package/dist/llm/auth/resolver.d.ts +24 -0
- package/dist/llm/auth/resolver.d.ts.map +1 -0
- package/dist/llm/auth/resolver.js +97 -0
- package/dist/llm/auth/resolver.js.map +1 -0
- package/dist/llm/auth/token-store.d.ts +15 -0
- package/dist/llm/auth/token-store.d.ts.map +1 -0
- package/dist/llm/auth/token-store.js +94 -0
- package/dist/llm/auth/token-store.js.map +1 -0
- package/dist/llm/auth/types.d.ts +20 -0
- package/dist/llm/auth/types.d.ts.map +1 -0
- package/dist/llm/auth/types.js +3 -0
- package/dist/llm/auth/types.js.map +1 -0
- package/dist/llm/gemini.d.ts +28 -0
- package/dist/llm/gemini.d.ts.map +1 -0
- package/dist/llm/gemini.js +524 -0
- package/dist/llm/gemini.js.map +1 -0
- package/dist/llm/openai-compat.d.ts +14 -0
- package/dist/llm/openai-compat.d.ts.map +1 -0
- package/dist/llm/openai-compat.js +200 -0
- package/dist/llm/openai-compat.js.map +1 -0
- package/dist/llm/provider.d.ts +2 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +4 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/types.d.ts +75 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +3 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/mcp/adapter.d.ts +14 -0
- package/dist/mcp/adapter.d.ts.map +1 -0
- package/dist/mcp/adapter.js +58 -0
- package/dist/mcp/adapter.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +48 -0
- package/dist/mcp/manager.d.ts.map +1 -0
- package/dist/mcp/manager.js +109 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/memory/daily-log.d.ts +19 -0
- package/dist/memory/daily-log.d.ts.map +1 -0
- package/dist/memory/daily-log.js +47 -0
- package/dist/memory/daily-log.js.map +1 -0
- package/dist/memory/memory-manager.d.ts +41 -0
- package/dist/memory/memory-manager.d.ts.map +1 -0
- package/dist/memory/memory-manager.js +97 -0
- package/dist/memory/memory-manager.js.map +1 -0
- package/dist/memory/workspace.d.ts +21 -0
- package/dist/memory/workspace.d.ts.map +1 -0
- package/dist/memory/workspace.js +63 -0
- package/dist/memory/workspace.js.map +1 -0
- package/dist/panels/bridge.d.ts +19 -0
- package/dist/panels/bridge.d.ts.map +1 -0
- package/dist/panels/bridge.js +74 -0
- package/dist/panels/bridge.js.map +1 -0
- package/dist/panels/registry.d.ts +30 -0
- package/dist/panels/registry.d.ts.map +1 -0
- package/dist/panels/registry.js +102 -0
- package/dist/panels/registry.js.map +1 -0
- package/dist/panels/routes.d.ts +8 -0
- package/dist/panels/routes.d.ts.map +1 -0
- package/dist/panels/routes.js +252 -0
- package/dist/panels/routes.js.map +1 -0
- package/dist/panels/sdk/gemma-panel.js +331 -0
- package/dist/panels/service-context.d.ts +28 -0
- package/dist/panels/service-context.d.ts.map +1 -0
- package/dist/panels/service-context.js +84 -0
- package/dist/panels/service-context.js.map +1 -0
- package/dist/panels/service-loader.d.ts +19 -0
- package/dist/panels/service-loader.d.ts.map +1 -0
- package/dist/panels/service-loader.js +61 -0
- package/dist/panels/service-loader.js.map +1 -0
- package/dist/panels/service-manager.d.ts +40 -0
- package/dist/panels/service-manager.d.ts.map +1 -0
- package/dist/panels/service-manager.js +148 -0
- package/dist/panels/service-manager.js.map +1 -0
- package/dist/panels/storage.d.ts +14 -0
- package/dist/panels/storage.d.ts.map +1 -0
- package/dist/panels/storage.js +47 -0
- package/dist/panels/storage.js.map +1 -0
- package/dist/panels/types.d.ts +39 -0
- package/dist/panels/types.d.ts.map +1 -0
- package/dist/panels/types.js +8 -0
- package/dist/panels/types.js.map +1 -0
- package/dist/shared/ws-types.d.ts +332 -0
- package/dist/shared/ws-types.d.ts.map +1 -0
- package/dist/shared/ws-types.js +7 -0
- package/dist/shared/ws-types.js.map +1 -0
- package/dist/skills/gating.d.ts +15 -0
- package/dist/skills/gating.d.ts.map +1 -0
- package/dist/skills/gating.js +49 -0
- package/dist/skills/gating.js.map +1 -0
- package/dist/skills/loader.d.ts +32 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +66 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/parser.d.ts +22 -0
- package/dist/skills/parser.d.ts.map +1 -0
- package/dist/skills/parser.js +29 -0
- package/dist/skills/parser.js.map +1 -0
- package/dist/skills/prompt-injector.d.ts +10 -0
- package/dist/skills/prompt-injector.d.ts.map +1 -0
- package/dist/skills/prompt-injector.js +29 -0
- package/dist/skills/prompt-injector.js.map +1 -0
- package/dist/tools/builtin/cron.d.ts +3 -0
- package/dist/tools/builtin/cron.d.ts.map +1 -0
- package/dist/tools/builtin/cron.js +198 -0
- package/dist/tools/builtin/cron.js.map +1 -0
- package/dist/tools/builtin/edit.d.ts +3 -0
- package/dist/tools/builtin/edit.d.ts.map +1 -0
- package/dist/tools/builtin/edit.js +77 -0
- package/dist/tools/builtin/edit.js.map +1 -0
- package/dist/tools/builtin/exec.d.ts +3 -0
- package/dist/tools/builtin/exec.d.ts.map +1 -0
- package/dist/tools/builtin/exec.js +88 -0
- package/dist/tools/builtin/exec.js.map +1 -0
- package/dist/tools/builtin/panel.d.ts +14 -0
- package/dist/tools/builtin/panel.d.ts.map +1 -0
- package/dist/tools/builtin/panel.js +521 -0
- package/dist/tools/builtin/panel.js.map +1 -0
- package/dist/tools/builtin/read.d.ts +3 -0
- package/dist/tools/builtin/read.d.ts.map +1 -0
- package/dist/tools/builtin/read.js +61 -0
- package/dist/tools/builtin/read.js.map +1 -0
- package/dist/tools/builtin/web-fetch.d.ts +3 -0
- package/dist/tools/builtin/web-fetch.d.ts.map +1 -0
- package/dist/tools/builtin/web-fetch.js +68 -0
- package/dist/tools/builtin/web-fetch.js.map +1 -0
- package/dist/tools/builtin/web-search.d.ts +3 -0
- package/dist/tools/builtin/web-search.d.ts.map +1 -0
- package/dist/tools/builtin/web-search.js +67 -0
- package/dist/tools/builtin/web-search.js.map +1 -0
- package/dist/tools/builtin/write.d.ts +3 -0
- package/dist/tools/builtin/write.d.ts.map +1 -0
- package/dist/tools/builtin/write.js +40 -0
- package/dist/tools/builtin/write.js.map +1 -0
- package/dist/tools/executor.d.ts +16 -0
- package/dist/tools/executor.d.ts.map +1 -0
- package/dist/tools/executor.js +142 -0
- package/dist/tools/executor.js.map +1 -0
- package/dist/tools/registry.d.ts +23 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +72 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +58 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +8 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/ui/assets/code-block-OCS4YCEC-D5mQabi7.js +2 -0
- package/dist/ui/assets/index-0RdIdnZu.js +456 -0
- package/dist/ui/assets/index-CjWH8YjU.css +1 -0
- package/dist/ui/index.html +16 -0
- package/package.json +89 -0
- package/skills/coding/SKILL.md +52 -0
- package/skills/file-ops/SKILL.md +50 -0
- package/skills/panel-dev/SKILL.md +742 -0
- package/skills/system-admin/SKILL.md +56 -0
- package/skills/web-research/SKILL.md +44 -0
- package/templates/BOOTSTRAP.md +19 -0
- package/templates/IDENTITY.md +9 -0
- package/templates/INSTRUCTIONS.md +19 -0
- package/templates/MEMORY.md +5 -0
- package/templates/SOUL.md +21 -0
- package/templates/TOOLS.md +13 -0
- package/templates/USER.md +12 -0
- package/templates/panel/gemma-panel-sdk.d.ts +27 -0
- package/templates/panel/gemma-panel.d.ts +46 -0
- package/templates/panel/index.html +59 -0
- package/templates/panel/package.json +15 -0
- package/templates/panel/panel.json +12 -0
- package/templates/panel/service.ts +69 -0
- package/templates/panel/tsconfig.json +17 -0
- package/templates/panel/vite.config.ts +13 -0
- package/templates/panel-react/index.html +12 -0
- package/templates/panel-react/package.json +22 -0
- package/templates/panel-react/panel.json +10 -0
- package/templates/panel-react/service.ts +69 -0
- package/templates/panel-react/src/App.tsx +108 -0
- package/templates/panel-react/src/gemma.d.ts +13 -0
- package/templates/panel-react/src/main.tsx +9 -0
- package/templates/panel-react/src/vite-env.d.ts +1 -0
- package/templates/panel-react/tsconfig.json +17 -0
- package/templates/panel-react/tsconfig.service.json +16 -0
- package/templates/panel-react/vite.config.ts +14 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// --- Sub-schemas ---
|
|
3
|
+
export const OAuthConfigSchema = z.object({
|
|
4
|
+
clientId: z.string().optional(),
|
|
5
|
+
clientSecret: z.string().optional(),
|
|
6
|
+
});
|
|
7
|
+
export const OpenAICompatConfigSchema = z.object({
|
|
8
|
+
baseUrl: z.string().url(),
|
|
9
|
+
model: z.string(),
|
|
10
|
+
});
|
|
11
|
+
export const ModelConfigSchema = z.object({
|
|
12
|
+
provider: z.enum(['gemini', 'openai-compat']).default('gemini'),
|
|
13
|
+
model: z.string().default('gemini-2.5-flash'),
|
|
14
|
+
fallbackModel: z.string().optional(),
|
|
15
|
+
auth: z.enum(['oauth', 'api-key', 'adc']).optional(),
|
|
16
|
+
apiKey: z.string().optional(),
|
|
17
|
+
oauth: OAuthConfigSchema.optional(),
|
|
18
|
+
openaiCompat: OpenAICompatConfigSchema.optional(),
|
|
19
|
+
});
|
|
20
|
+
export const GatewayAuthConfigSchema = z.object({
|
|
21
|
+
token: z.string().optional(),
|
|
22
|
+
});
|
|
23
|
+
export const GatewayConfigSchema = z.object({
|
|
24
|
+
port: z.number().int().min(1).max(65535).default(process.env['GEMMA_PORT'] ? parseInt(process.env['GEMMA_PORT'], 10) : 18789),
|
|
25
|
+
bind: z.string().default(process.env['GEMMA_BIND'] || '127.0.0.1'),
|
|
26
|
+
auth: GatewayAuthConfigSchema.optional(),
|
|
27
|
+
});
|
|
28
|
+
export const TelegramChannelConfigSchema = z.object({
|
|
29
|
+
enabled: z.boolean().default(false),
|
|
30
|
+
token: z.string().optional(),
|
|
31
|
+
webhookUrl: z.string().optional(),
|
|
32
|
+
allowFrom: z.array(z.number()).default([]),
|
|
33
|
+
});
|
|
34
|
+
export const WebChannelConfigSchema = z.object({
|
|
35
|
+
enabled: z.boolean().default(true),
|
|
36
|
+
});
|
|
37
|
+
export const CliChannelConfigSchema = z.object({
|
|
38
|
+
enabled: z.boolean().default(false),
|
|
39
|
+
});
|
|
40
|
+
export const ChannelsConfigSchema = z.object({
|
|
41
|
+
telegram: TelegramChannelConfigSchema.default({ enabled: false, allowFrom: [] }),
|
|
42
|
+
web: WebChannelConfigSchema.default({ enabled: true }),
|
|
43
|
+
cli: CliChannelConfigSchema.default({ enabled: false }),
|
|
44
|
+
});
|
|
45
|
+
export const AutoApproveConfigSchema = z.object({
|
|
46
|
+
internalReads: z.boolean().default(true),
|
|
47
|
+
memoryWrites: z.boolean().default(false),
|
|
48
|
+
});
|
|
49
|
+
export const ConfirmConfigSchema = z.object({
|
|
50
|
+
timeout: z.number().int().min(1).default(300),
|
|
51
|
+
autoApprove: AutoApproveConfigSchema.default({ internalReads: true, memoryWrites: false }),
|
|
52
|
+
});
|
|
53
|
+
export const WorkspaceConfigSchema = z.object({
|
|
54
|
+
path: z.string().default('~/.gemma/workspace'),
|
|
55
|
+
});
|
|
56
|
+
export const ExecToolConfigSchema = z.object({
|
|
57
|
+
timeout: z.number().int().min(1).default(30),
|
|
58
|
+
shell: z.string().default('/bin/bash'),
|
|
59
|
+
});
|
|
60
|
+
export const WebSearchToolConfigSchema = z.object({
|
|
61
|
+
provider: z.enum(['brave']).default('brave'),
|
|
62
|
+
apiKey: z.string().optional(),
|
|
63
|
+
});
|
|
64
|
+
export const ToolsConfigSchema = z.object({
|
|
65
|
+
exec: ExecToolConfigSchema.default({ timeout: 30, shell: '/bin/bash' }),
|
|
66
|
+
webSearch: WebSearchToolConfigSchema.default({ provider: 'brave' }),
|
|
67
|
+
});
|
|
68
|
+
export const SkillsConfigSchema = z.object({
|
|
69
|
+
dirs: z.array(z.string()).default([]),
|
|
70
|
+
entries: z.record(z.string(), z.unknown()).default({}),
|
|
71
|
+
});
|
|
72
|
+
export const PanelsConfigSchema = z.object({
|
|
73
|
+
enabled: z.boolean().default(true),
|
|
74
|
+
dir: z.string().default('~/.gemma/panels'),
|
|
75
|
+
maxDataSize: z.number().int().default(5_242_880),
|
|
76
|
+
disabled: z.array(z.string()).default([]),
|
|
77
|
+
devMode: z.boolean().default(false),
|
|
78
|
+
serviceTimeout: z.number().int().default(30_000),
|
|
79
|
+
});
|
|
80
|
+
export const HeartbeatConfigSchema = z.object({
|
|
81
|
+
enabled: z.boolean().default(true),
|
|
82
|
+
intervalMinutes: z.number().int().min(1).default(30),
|
|
83
|
+
prompt: z.string().default('Read HEARTBEAT.md if it exists. Follow it strictly. If nothing needs attention, reply HEARTBEAT_OK.'),
|
|
84
|
+
});
|
|
85
|
+
export const CronConfigSchema = z.object({
|
|
86
|
+
enabled: z.boolean().default(true),
|
|
87
|
+
store: z.string().default('~/.gemma/cron/jobs.json'),
|
|
88
|
+
});
|
|
89
|
+
export const AgentLoopConfigSchema = z.object({
|
|
90
|
+
maxIterations: z.number().int().min(1).max(100).default(25),
|
|
91
|
+
compactionThreshold: z.number().int().min(10_000).default(200_000),
|
|
92
|
+
maxContextChars: z.number().int().min(10_000).default(320_000),
|
|
93
|
+
maxToolResultChars: z.number().int().min(1_000).default(30_000),
|
|
94
|
+
});
|
|
95
|
+
export const MCPServerConfigSchema = z.object({
|
|
96
|
+
command: z.string(),
|
|
97
|
+
args: z.array(z.string()).default([]),
|
|
98
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
99
|
+
enabled: z.boolean().default(true),
|
|
100
|
+
});
|
|
101
|
+
export const MCPConfigSchema = z.object({
|
|
102
|
+
servers: z.record(z.string(), MCPServerConfigSchema).default({}),
|
|
103
|
+
});
|
|
104
|
+
// --- Root config schema ---
|
|
105
|
+
export const GemmaConfigSchema = z.object({
|
|
106
|
+
model: ModelConfigSchema.default(() => ModelConfigSchema.parse({})),
|
|
107
|
+
gateway: GatewayConfigSchema.default(() => GatewayConfigSchema.parse({})),
|
|
108
|
+
channels: ChannelsConfigSchema.default(() => ChannelsConfigSchema.parse({})),
|
|
109
|
+
confirm: ConfirmConfigSchema.default(() => ConfirmConfigSchema.parse({})),
|
|
110
|
+
workspace: WorkspaceConfigSchema.default(() => WorkspaceConfigSchema.parse({})),
|
|
111
|
+
tools: ToolsConfigSchema.default(() => ToolsConfigSchema.parse({})),
|
|
112
|
+
skills: SkillsConfigSchema.default(() => SkillsConfigSchema.parse({})),
|
|
113
|
+
panels: PanelsConfigSchema.default(() => PanelsConfigSchema.parse({})),
|
|
114
|
+
heartbeat: HeartbeatConfigSchema.default(() => HeartbeatConfigSchema.parse({})),
|
|
115
|
+
agent: AgentLoopConfigSchema.default(() => AgentLoopConfigSchema.parse({})),
|
|
116
|
+
cron: CronConfigSchema.default(() => CronConfigSchema.parse({})),
|
|
117
|
+
mcp: MCPConfigSchema.default(() => MCPConfigSchema.parse({})),
|
|
118
|
+
});
|
|
119
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Logger — records all tool proposals and user decisions.
|
|
3
|
+
*
|
|
4
|
+
* Every confirmation cycle is logged to ~/.gemma/logs/audit.jsonl
|
|
5
|
+
* Format:
|
|
6
|
+
* {
|
|
7
|
+
* "timestamp": "2026-02-17T14:30:00.000Z",
|
|
8
|
+
* "session": "main",
|
|
9
|
+
* "proposed": [{"tool": "read", "args": {"path": "..."}}],
|
|
10
|
+
* "approved": [0],
|
|
11
|
+
* "rejected": [1],
|
|
12
|
+
* "auto_approved": [2],
|
|
13
|
+
* "user_response_time_ms": 4200
|
|
14
|
+
* }
|
|
15
|
+
*/
|
|
16
|
+
import type { ToolCall } from '../llm/types.js';
|
|
17
|
+
import type { ConfirmationResult } from '../tools/types.js';
|
|
18
|
+
export interface AuditEntry {
|
|
19
|
+
timestamp: string;
|
|
20
|
+
session: string;
|
|
21
|
+
proposed: Array<{
|
|
22
|
+
tool: string;
|
|
23
|
+
args: Record<string, unknown>;
|
|
24
|
+
}>;
|
|
25
|
+
approved: number[];
|
|
26
|
+
rejected: number[];
|
|
27
|
+
auto_approved: number[];
|
|
28
|
+
user_response_time_ms: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Log a confirmation gate cycle to the audit log.
|
|
32
|
+
*/
|
|
33
|
+
export declare function logAudit(sessionId: string, calls: ToolCall[], result: ConfirmationResult, autoApprovedIndices: number[], responseTimeMs: number): Promise<void>;
|
|
34
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/confirm/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAWD;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,QAAQ,EAAE,EACjB,MAAM,EAAE,kBAAkB,EAC1B,mBAAmB,EAAE,MAAM,EAAE,EAC7B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAmBf"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Logger — records all tool proposals and user decisions.
|
|
3
|
+
*
|
|
4
|
+
* Every confirmation cycle is logged to ~/.gemma/logs/audit.jsonl
|
|
5
|
+
* Format:
|
|
6
|
+
* {
|
|
7
|
+
* "timestamp": "2026-02-17T14:30:00.000Z",
|
|
8
|
+
* "session": "main",
|
|
9
|
+
* "proposed": [{"tool": "read", "args": {"path": "..."}}],
|
|
10
|
+
* "approved": [0],
|
|
11
|
+
* "rejected": [1],
|
|
12
|
+
* "auto_approved": [2],
|
|
13
|
+
* "user_response_time_ms": 4200
|
|
14
|
+
* }
|
|
15
|
+
*/
|
|
16
|
+
import { appendFile, mkdir } from 'node:fs/promises';
|
|
17
|
+
import { resolve, dirname } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
/** Resolve the audit log path. */
|
|
20
|
+
function getAuditLogPath() {
|
|
21
|
+
const gemmaHome = process.env['GEMMA_HOME'] || '~/.gemma';
|
|
22
|
+
const base = gemmaHome === '~' || gemmaHome.startsWith('~/') || gemmaHome.startsWith('~\\')
|
|
23
|
+
? resolve(homedir(), gemmaHome.slice(2))
|
|
24
|
+
: resolve(gemmaHome);
|
|
25
|
+
return resolve(base, 'logs', 'audit.jsonl');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Log a confirmation gate cycle to the audit log.
|
|
29
|
+
*/
|
|
30
|
+
export async function logAudit(sessionId, calls, result, autoApprovedIndices, responseTimeMs) {
|
|
31
|
+
const logPath = getAuditLogPath();
|
|
32
|
+
const entry = {
|
|
33
|
+
timestamp: new Date().toISOString(),
|
|
34
|
+
session: sessionId,
|
|
35
|
+
proposed: calls.map((c) => ({ tool: c.tool, args: c.args })),
|
|
36
|
+
approved: result.approved,
|
|
37
|
+
rejected: result.rejected,
|
|
38
|
+
auto_approved: autoApprovedIndices,
|
|
39
|
+
user_response_time_ms: Math.round(responseTimeMs),
|
|
40
|
+
};
|
|
41
|
+
try {
|
|
42
|
+
await mkdir(dirname(logPath), { recursive: true });
|
|
43
|
+
await appendFile(logPath, JSON.stringify(entry) + '\n', 'utf-8');
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Audit logging is best-effort — don't crash the gate if logging fails
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/confirm/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAclC,kCAAkC;AAClC,SAAS,eAAe;IACtB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC;IAC1D,MAAM,IAAI,GAAG,SAAS,KAAK,GAAG,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;QACzF,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,SAAiB,EACjB,KAAiB,EACjB,MAA0B,EAC1B,mBAA6B,EAC7B,cAAsB;IAEtB,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAElC,MAAM,KAAK,GAAe;QACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,OAAO,EAAE,SAAS;QAClB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5D,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,aAAa,EAAE,mBAAmB;QAClC,qBAAqB,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;KAClD,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-approve rules for the confirmation gate.
|
|
3
|
+
*
|
|
4
|
+
* Determines which tool calls can be auto-approved (executed without user confirmation).
|
|
5
|
+
* The boundary is intentionally narrow: only reads of Gemma's own internal files,
|
|
6
|
+
* and optionally memory writes.
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolCall } from '../llm/types.js';
|
|
9
|
+
import type { ConfirmConfig } from '../config/schema.js';
|
|
10
|
+
/**
|
|
11
|
+
* Determine if a tool call needs user confirmation.
|
|
12
|
+
*
|
|
13
|
+
* Returns false (auto-approved) only for:
|
|
14
|
+
* - `read` calls targeting files inside GEMMA_HOME (when internalReads is enabled)
|
|
15
|
+
* - `write`/`edit` calls targeting MEMORY.md or memory/*.md (when memoryWrites is enabled)
|
|
16
|
+
*
|
|
17
|
+
* Everything else requires confirmation.
|
|
18
|
+
*/
|
|
19
|
+
export declare function needsConfirmation(call: ToolCall, config: ConfirmConfig, gemmaHome?: string): boolean;
|
|
20
|
+
//# sourceMappingURL=auto-approve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-approve.d.ts","sourceRoot":"","sources":["../../src/confirm/auto-approve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAezD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,aAAa,EACrB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAmCT"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-approve rules for the confirmation gate.
|
|
3
|
+
*
|
|
4
|
+
* Determines which tool calls can be auto-approved (executed without user confirmation).
|
|
5
|
+
* The boundary is intentionally narrow: only reads of Gemma's own internal files,
|
|
6
|
+
* and optionally memory writes.
|
|
7
|
+
*/
|
|
8
|
+
import { resolve, sep, basename } from 'node:path';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
/** Resolve a path that might start with ~ to an absolute path. */
|
|
11
|
+
function expandHome(p) {
|
|
12
|
+
if (p === '~' || p.startsWith('~/') || p.startsWith('~\\')) {
|
|
13
|
+
return resolve(homedir(), p.slice(2));
|
|
14
|
+
}
|
|
15
|
+
return resolve(p);
|
|
16
|
+
}
|
|
17
|
+
/** Get the resolved GEMMA_HOME path. */
|
|
18
|
+
function resolveGemmaHome() {
|
|
19
|
+
return expandHome(process.env['GEMMA_HOME'] || '~/.gemma');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Determine if a tool call needs user confirmation.
|
|
23
|
+
*
|
|
24
|
+
* Returns false (auto-approved) only for:
|
|
25
|
+
* - `read` calls targeting files inside GEMMA_HOME (when internalReads is enabled)
|
|
26
|
+
* - `write`/`edit` calls targeting MEMORY.md or memory/*.md (when memoryWrites is enabled)
|
|
27
|
+
*
|
|
28
|
+
* Everything else requires confirmation.
|
|
29
|
+
*/
|
|
30
|
+
export function needsConfirmation(call, config, gemmaHome) {
|
|
31
|
+
const home = gemmaHome ?? resolveGemmaHome();
|
|
32
|
+
// Auto-approve reads of Gemma's own workspace files
|
|
33
|
+
if (call.tool === 'read' && config.autoApprove.internalReads) {
|
|
34
|
+
const filePath = call.args['path'];
|
|
35
|
+
if (typeof filePath === 'string') {
|
|
36
|
+
const resolved = resolve(expandHome(filePath));
|
|
37
|
+
if (resolved === home || resolved.startsWith(home + sep)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
// Also auto-approve HEARTBEAT.md reads (heartbeat prompt)
|
|
41
|
+
if (basename(resolved) === 'HEARTBEAT.md') {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Auto-approve memory writes when configured
|
|
47
|
+
if ((call.tool === 'write' || call.tool === 'edit') && config.autoApprove.memoryWrites) {
|
|
48
|
+
const filePath = call.args['path'];
|
|
49
|
+
if (typeof filePath === 'string') {
|
|
50
|
+
const resolved = resolve(expandHome(filePath));
|
|
51
|
+
const workspacePath = resolve(home, 'workspace');
|
|
52
|
+
const memoryFile = resolve(workspacePath, 'MEMORY.md');
|
|
53
|
+
const memoryDir = resolve(workspacePath, 'memory') + sep;
|
|
54
|
+
if (resolved === memoryFile || resolved.startsWith(memoryDir)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Everything else requires confirmation
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=auto-approve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-approve.js","sourceRoot":"","sources":["../../src/confirm/auto-approve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIlC,kEAAkE;AAClE,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,wCAAwC;AACxC,SAAS,gBAAgB;IACvB,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAc,EACd,MAAqB,EACrB,SAAkB;IAElB,MAAM,IAAI,GAAG,SAAS,IAAI,gBAAgB,EAAE,CAAC;IAE7C,oDAAoD;IACpD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/C,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACzD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,0DAA0D;YAC1D,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,cAAc,EAAE,CAAC;gBAC1C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;QACvF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/C,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACjD,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;YACvD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC;YAEzD,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9D,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Confirmation Gate — core security boundary.
|
|
3
|
+
*
|
|
4
|
+
* No tool call executes unless it passes through this gate.
|
|
5
|
+
* The executor is ONLY callable from within this file.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Receive proposed tool calls from agent loop
|
|
9
|
+
* 2. Check auto-approve rules (internal reads, optionally memory writes)
|
|
10
|
+
* 3. Auto-approved calls: execute immediately, collect results
|
|
11
|
+
* 4. Remaining calls: present to user via channel for confirmation
|
|
12
|
+
* 5. Wait for user approval (with timeout)
|
|
13
|
+
* 6. Execute approved calls sequentially
|
|
14
|
+
* 7. Return rejected calls with rejection result
|
|
15
|
+
* 8. Audit log every cycle
|
|
16
|
+
*/
|
|
17
|
+
import type { ToolCall, ToolResult } from '../llm/types.js';
|
|
18
|
+
import type { ConfirmConfig } from '../config/schema.js';
|
|
19
|
+
import type { ToolContext, ConfirmationResult } from '../tools/types.js';
|
|
20
|
+
import type { ToolRegistry } from '../tools/registry.js';
|
|
21
|
+
import type { Channel } from '../channels/types.js';
|
|
22
|
+
/** Callback that presents confirmation to user and returns their decision */
|
|
23
|
+
export type ConfirmationPresenter = (channelId: string, calls: ToolCall[], timeout: number) => Promise<ConfirmationResult>;
|
|
24
|
+
/** Options for the gate's process method */
|
|
25
|
+
export interface GateOptions {
|
|
26
|
+
sessionId: string;
|
|
27
|
+
channelId: string;
|
|
28
|
+
toolContext: ToolContext;
|
|
29
|
+
cowboyMode?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The Confirmation Gate.
|
|
33
|
+
* Instantiate once per gateway with the tool registry and config.
|
|
34
|
+
* Each process() call handles one batch of tool calls from the agent loop.
|
|
35
|
+
*/
|
|
36
|
+
export declare class ConfirmationGate {
|
|
37
|
+
private readonly registry;
|
|
38
|
+
private readonly config;
|
|
39
|
+
constructor(registry: ToolRegistry, config: ConfirmConfig);
|
|
40
|
+
/**
|
|
41
|
+
* Process a batch of tool calls through the confirmation gate.
|
|
42
|
+
*
|
|
43
|
+
* @param calls - Tool calls proposed by the LLM
|
|
44
|
+
* @param options - Session, channel, and context info
|
|
45
|
+
* @param channel - The channel to present confirmations through
|
|
46
|
+
* @returns ToolResult[] for all calls (approved, auto-approved, and rejected)
|
|
47
|
+
*/
|
|
48
|
+
process(calls: ToolCall[], options: GateOptions, channel: Channel): Promise<ToolResult[]>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/confirm/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAOpD,6EAA6E;AAC7E,MAAM,MAAM,qBAAqB,GAAG,CAClC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,aAAa;IAGxC;;;;;;;OAOG;IACG,OAAO,CACX,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,UAAU,EAAE,CAAC;CAqIzB"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Confirmation Gate — core security boundary.
|
|
3
|
+
*
|
|
4
|
+
* No tool call executes unless it passes through this gate.
|
|
5
|
+
* The executor is ONLY callable from within this file.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Receive proposed tool calls from agent loop
|
|
9
|
+
* 2. Check auto-approve rules (internal reads, optionally memory writes)
|
|
10
|
+
* 3. Auto-approved calls: execute immediately, collect results
|
|
11
|
+
* 4. Remaining calls: present to user via channel for confirmation
|
|
12
|
+
* 5. Wait for user approval (with timeout)
|
|
13
|
+
* 6. Execute approved calls sequentially
|
|
14
|
+
* 7. Return rejected calls with rejection result
|
|
15
|
+
* 8. Audit log every cycle
|
|
16
|
+
*/
|
|
17
|
+
// SECURITY: Direct import of executor — not re-exported anywhere
|
|
18
|
+
import { executeTool } from '../tools/executor.js';
|
|
19
|
+
import { needsConfirmation } from './auto-approve.js';
|
|
20
|
+
import { logAudit } from './audit.js';
|
|
21
|
+
/**
|
|
22
|
+
* The Confirmation Gate.
|
|
23
|
+
* Instantiate once per gateway with the tool registry and config.
|
|
24
|
+
* Each process() call handles one batch of tool calls from the agent loop.
|
|
25
|
+
*/
|
|
26
|
+
export class ConfirmationGate {
|
|
27
|
+
registry;
|
|
28
|
+
config;
|
|
29
|
+
constructor(registry, config) {
|
|
30
|
+
this.registry = registry;
|
|
31
|
+
this.config = config;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Process a batch of tool calls through the confirmation gate.
|
|
35
|
+
*
|
|
36
|
+
* @param calls - Tool calls proposed by the LLM
|
|
37
|
+
* @param options - Session, channel, and context info
|
|
38
|
+
* @param channel - The channel to present confirmations through
|
|
39
|
+
* @returns ToolResult[] for all calls (approved, auto-approved, and rejected)
|
|
40
|
+
*/
|
|
41
|
+
async process(calls, options, channel) {
|
|
42
|
+
if (calls.length === 0)
|
|
43
|
+
return [];
|
|
44
|
+
const startTime = Date.now();
|
|
45
|
+
// Cowboy mode: bypass all confirmation, execute everything directly
|
|
46
|
+
if (options.cowboyMode) {
|
|
47
|
+
const results = [];
|
|
48
|
+
for (const call of calls) {
|
|
49
|
+
results.push(await executeTool(call, options.toolContext, this.registry));
|
|
50
|
+
}
|
|
51
|
+
const elapsed = Date.now() - startTime;
|
|
52
|
+
await logAudit(options.sessionId, calls, { approved: calls.map((_, i) => i), rejected: [], timedOut: false }, calls.map((_, i) => i), // all treated as auto-approved
|
|
53
|
+
elapsed);
|
|
54
|
+
return results;
|
|
55
|
+
}
|
|
56
|
+
// Partition calls into auto-approved and needs-confirmation
|
|
57
|
+
const autoApproved = [];
|
|
58
|
+
const needsApproval = [];
|
|
59
|
+
for (let i = 0; i < calls.length; i++) {
|
|
60
|
+
if (needsConfirmation(calls[i], this.config)) {
|
|
61
|
+
needsApproval.push(i);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
autoApproved.push(i);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Execute auto-approved calls immediately
|
|
68
|
+
const results = new Array(calls.length);
|
|
69
|
+
for (const idx of autoApproved) {
|
|
70
|
+
results[idx] = await executeTool(calls[idx], options.toolContext, this.registry);
|
|
71
|
+
}
|
|
72
|
+
// If all calls were auto-approved, log and return
|
|
73
|
+
if (needsApproval.length === 0) {
|
|
74
|
+
const elapsed = Date.now() - startTime;
|
|
75
|
+
await logAudit(options.sessionId, calls, { approved: autoApproved, rejected: [], timedOut: false }, autoApproved, elapsed);
|
|
76
|
+
return results;
|
|
77
|
+
}
|
|
78
|
+
// Present remaining calls to user for confirmation
|
|
79
|
+
const pendingCalls = needsApproval.map((i) => calls[i]);
|
|
80
|
+
let confirmation;
|
|
81
|
+
try {
|
|
82
|
+
confirmation = await channel.presentConfirmation(options.channelId, pendingCalls, this.config.timeout);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// If presentation fails, reject all pending calls
|
|
86
|
+
confirmation = {
|
|
87
|
+
approved: [],
|
|
88
|
+
rejected: Array.from({ length: needsApproval.length }, (_, i) => i),
|
|
89
|
+
timedOut: false,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const confirmTime = Date.now() - startTime;
|
|
93
|
+
// Map confirmation indices back to original call indices
|
|
94
|
+
const approvedOriginal = [];
|
|
95
|
+
const rejectedOriginal = [];
|
|
96
|
+
for (const localIdx of confirmation.approved) {
|
|
97
|
+
const originalIdx = needsApproval[localIdx];
|
|
98
|
+
if (originalIdx !== undefined) {
|
|
99
|
+
approvedOriginal.push(originalIdx);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const localIdx of confirmation.rejected) {
|
|
103
|
+
const originalIdx = needsApproval[localIdx];
|
|
104
|
+
if (originalIdx !== undefined) {
|
|
105
|
+
rejectedOriginal.push(originalIdx);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Handle any indices not covered (shouldn't happen, but be safe)
|
|
109
|
+
for (const idx of needsApproval) {
|
|
110
|
+
if (!approvedOriginal.includes(idx) && !rejectedOriginal.includes(idx)) {
|
|
111
|
+
rejectedOriginal.push(idx);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Execute approved calls sequentially
|
|
115
|
+
for (const idx of approvedOriginal) {
|
|
116
|
+
results[idx] = await executeTool(calls[idx], options.toolContext, this.registry);
|
|
117
|
+
}
|
|
118
|
+
// Fill in rejection results
|
|
119
|
+
const rejectionMessage = confirmation.timedOut
|
|
120
|
+
? 'All proposed actions timed out waiting for user approval.'
|
|
121
|
+
: 'The user declined this action.';
|
|
122
|
+
for (const idx of rejectedOriginal) {
|
|
123
|
+
results[idx] = {
|
|
124
|
+
toolCallId: calls[idx].id,
|
|
125
|
+
content: rejectionMessage,
|
|
126
|
+
isError: false,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// Audit log
|
|
130
|
+
await logAudit(options.sessionId, calls, {
|
|
131
|
+
approved: [...autoApproved, ...approvedOriginal],
|
|
132
|
+
rejected: rejectedOriginal,
|
|
133
|
+
timedOut: confirmation.timedOut,
|
|
134
|
+
}, autoApproved, confirmTime);
|
|
135
|
+
return results;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/confirm/gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirmation Parser — parses user approval responses.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - "a" or "all" or "y" or "yes" -> approve all
|
|
6
|
+
* - "n" or "none" or "no" or "reject" -> reject all
|
|
7
|
+
* - Comma-separated numbers -> selective approval (e.g., "1,2" or "1, 3")
|
|
8
|
+
* - Inline keyboard callback data from Telegram (e.g., "approve_all", "reject_all", "select:0,1")
|
|
9
|
+
*/
|
|
10
|
+
import type { ConfirmationResult } from '../tools/types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Parse a user's approval response into a ConfirmationResult.
|
|
13
|
+
*
|
|
14
|
+
* @param response - Raw user response string
|
|
15
|
+
* @param totalCalls - Total number of pending tool calls
|
|
16
|
+
* @returns Parsed confirmation result
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseApprovalResponse(response: string, totalCalls: number): ConfirmationResult;
|
|
19
|
+
/**
|
|
20
|
+
* Create a timeout result — all calls rejected.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createTimeoutResult(totalCalls: number): ConfirmationResult;
|
|
23
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/confirm/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,kBAAkB,CA2BpB;AAkCD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CAM1E"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirmation Parser — parses user approval responses.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - "a" or "all" or "y" or "yes" -> approve all
|
|
6
|
+
* - "n" or "none" or "no" or "reject" -> reject all
|
|
7
|
+
* - Comma-separated numbers -> selective approval (e.g., "1,2" or "1, 3")
|
|
8
|
+
* - Inline keyboard callback data from Telegram (e.g., "approve_all", "reject_all", "select:0,1")
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Parse a user's approval response into a ConfirmationResult.
|
|
12
|
+
*
|
|
13
|
+
* @param response - Raw user response string
|
|
14
|
+
* @param totalCalls - Total number of pending tool calls
|
|
15
|
+
* @returns Parsed confirmation result
|
|
16
|
+
*/
|
|
17
|
+
export function parseApprovalResponse(response, totalCalls) {
|
|
18
|
+
const trimmed = response.trim().toLowerCase();
|
|
19
|
+
const allIndices = Array.from({ length: totalCalls }, (_, i) => i);
|
|
20
|
+
// Approve all
|
|
21
|
+
if (trimmed === 'a' || trimmed === 'all' || trimmed === 'y' || trimmed === 'yes' || trimmed === 'approve_all') {
|
|
22
|
+
return { approved: allIndices, rejected: [], timedOut: false };
|
|
23
|
+
}
|
|
24
|
+
// Reject all
|
|
25
|
+
if (trimmed === 'n' || trimmed === 'none' || trimmed === 'no' || trimmed === 'reject' || trimmed === 'reject_all') {
|
|
26
|
+
return { approved: [], rejected: allIndices, timedOut: false };
|
|
27
|
+
}
|
|
28
|
+
// Telegram callback: "select:0,1,2" (always 0-based)
|
|
29
|
+
if (trimmed.startsWith('select:')) {
|
|
30
|
+
const nums = trimmed.slice(7);
|
|
31
|
+
return parseNumberList(nums, totalCalls, true);
|
|
32
|
+
}
|
|
33
|
+
// Comma-separated numbers from user (always 1-based, e.g., "1,2,3")
|
|
34
|
+
if (/^[\d,\s]+$/.test(trimmed)) {
|
|
35
|
+
return parseNumberList(trimmed, totalCalls, false);
|
|
36
|
+
}
|
|
37
|
+
// Unrecognized -> reject all (safe default)
|
|
38
|
+
return { approved: [], rejected: allIndices, timedOut: false };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a comma-separated list of numbers into approval indices.
|
|
42
|
+
*
|
|
43
|
+
* @param input - Comma-separated numbers
|
|
44
|
+
* @param totalCalls - Total number of pending calls
|
|
45
|
+
* @param zeroBased - If true, numbers are 0-based (callback data). If false, 1-based (user input).
|
|
46
|
+
*/
|
|
47
|
+
function parseNumberList(input, totalCalls, zeroBased) {
|
|
48
|
+
const allIndices = Array.from({ length: totalCalls }, (_, i) => i);
|
|
49
|
+
const nums = input
|
|
50
|
+
.split(',')
|
|
51
|
+
.map((s) => s.trim())
|
|
52
|
+
.filter((s) => s.length > 0)
|
|
53
|
+
.map(Number)
|
|
54
|
+
.filter((n) => !isNaN(n) && Number.isInteger(n));
|
|
55
|
+
if (nums.length === 0) {
|
|
56
|
+
return { approved: [], rejected: allIndices, timedOut: false };
|
|
57
|
+
}
|
|
58
|
+
const indices = zeroBased
|
|
59
|
+
? nums.filter((n) => n >= 0 && n < totalCalls)
|
|
60
|
+
: nums.map((n) => n - 1).filter((n) => n >= 0 && n < totalCalls);
|
|
61
|
+
const approvedSet = new Set(indices);
|
|
62
|
+
const approved = Array.from(approvedSet);
|
|
63
|
+
const rejected = allIndices.filter((i) => !approvedSet.has(i));
|
|
64
|
+
return { approved, rejected, timedOut: false };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Create a timeout result — all calls rejected.
|
|
68
|
+
*/
|
|
69
|
+
export function createTimeoutResult(totalCalls) {
|
|
70
|
+
return {
|
|
71
|
+
approved: [],
|
|
72
|
+
rejected: Array.from({ length: totalCalls }, (_, i) => i),
|
|
73
|
+
timedOut: true,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/confirm/parser.ts"],"names":[],"mappings":"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"}
|