@meetquinn/animactl 0.1.2 → 0.1.3
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 +11 -6
- package/dist/server/{runtime/activity-payload.d.ts → activities/format.d.ts} +4 -1
- package/dist/server/activities/format.d.ts.map +1 -0
- package/dist/server/{runtime/activity-payload.js → activities/format.js} +16 -1
- package/dist/server/agents/agent-skills.d.ts +7 -3
- package/dist/server/agents/agent-skills.d.ts.map +1 -1
- package/dist/server/agents/agent-skills.js +243 -38
- package/dist/server/agents/agent-slack.service.d.ts +15 -0
- package/dist/server/agents/agent-slack.service.d.ts.map +1 -1
- package/dist/server/agents/agent-slack.service.js +43 -6
- package/dist/server/agents/default-skills.d.ts +9 -0
- package/dist/server/agents/default-skills.d.ts.map +1 -0
- package/dist/server/agents/default-skills.js +52 -0
- package/dist/server/cli/runtime-cli.d.ts +7 -1
- package/dist/server/cli/runtime-cli.d.ts.map +1 -1
- package/dist/server/cli/runtime-cli.js +107 -3
- package/dist/server/cli/services-cli.d.ts.map +1 -1
- package/dist/server/cli/services-cli.js +39 -0
- package/dist/server/inbox/slack-subscriber.d.ts +2 -0
- package/dist/server/inbox/slack-subscriber.d.ts.map +1 -1
- package/dist/server/inbox/slack-subscriber.js +28 -2
- package/dist/server/inbox/slack-subscription.service.d.ts.map +1 -1
- package/dist/server/inbox/slack-subscription.service.js +13 -1
- package/dist/server/inbox/wake-queue.service.d.ts +3 -1
- package/dist/server/inbox/wake-queue.service.d.ts.map +1 -1
- package/dist/server/inbox/wake-queue.service.js +5 -3
- package/dist/server/provider-usage/http.d.ts +1 -0
- package/dist/server/provider-usage/http.d.ts.map +1 -1
- package/dist/server/provider-usage/http.js +23 -1
- package/dist/server/provider-usage/provider-usage.service.d.ts +1 -4
- package/dist/server/provider-usage/provider-usage.service.d.ts.map +1 -1
- package/dist/server/provider-usage/provider-usage.service.js +1 -18
- package/dist/server/provider-usage/providers/claude.d.ts +1 -1
- package/dist/server/provider-usage/providers/claude.d.ts.map +1 -1
- package/dist/server/provider-usage/providers/claude.js +1 -1
- package/dist/server/provider-usage/providers/codex.d.ts +1 -1
- package/dist/server/provider-usage/providers/codex.d.ts.map +1 -1
- package/dist/server/provider-usage/providers/codex.js +1 -1
- package/dist/server/provider-usage/providers/kimi.d.ts +1 -1
- package/dist/server/provider-usage/providers/kimi.d.ts.map +1 -1
- package/dist/server/provider-usage/providers/kimi.js +4 -4
- package/dist/server/provider-usage/result.d.ts +5 -0
- package/dist/server/provider-usage/result.d.ts.map +1 -0
- package/dist/server/provider-usage/result.js +18 -0
- package/dist/server/providers/active-runtime.d.ts +1 -1
- package/dist/server/providers/active-runtime.d.ts.map +1 -1
- package/dist/server/providers/claude-events.d.ts +1 -1
- package/dist/server/providers/claude-events.d.ts.map +1 -1
- package/dist/server/providers/claude-events.js +2 -2
- package/dist/server/providers/claude.d.ts +1 -1
- package/dist/server/providers/claude.d.ts.map +1 -1
- package/dist/server/providers/claude.js +2 -2
- package/dist/server/providers/codex-app-server.d.ts +1 -1
- package/dist/server/providers/codex-app-server.d.ts.map +1 -1
- package/dist/server/providers/codex-app-server.js +1 -1
- package/dist/server/providers/codex-events.js +1 -1
- package/dist/server/providers/codex.d.ts +1 -1
- package/dist/server/providers/codex.d.ts.map +1 -1
- package/dist/server/providers/codex.js +2 -2
- package/dist/server/{runtime/provider-contract.d.ts → providers/contract.d.ts} +1 -1
- package/dist/server/providers/contract.d.ts.map +1 -0
- package/dist/server/providers/factory.d.ts +1 -1
- package/dist/server/providers/factory.d.ts.map +1 -1
- package/dist/server/providers/kimi-events.d.ts +1 -1
- package/dist/server/providers/kimi-events.d.ts.map +1 -1
- package/dist/server/providers/kimi-events.js +1 -1
- package/dist/server/providers/kimi.d.ts +1 -1
- package/dist/server/providers/kimi.d.ts.map +1 -1
- package/dist/server/providers/kimi.js +3 -2
- package/dist/server/providers/reasoning-events.js +1 -1
- package/dist/server/runtime/active-run-control.d.ts +19 -0
- package/dist/server/runtime/active-run-control.d.ts.map +1 -0
- package/dist/server/runtime/active-run-control.js +89 -0
- package/dist/server/runtime/activity.js +1 -1
- package/dist/server/runtime/agent-runner.d.ts +1 -1
- package/dist/server/runtime/agent-runner.d.ts.map +1 -1
- package/dist/server/runtime/delivery-prompt.d.ts +6 -0
- package/dist/server/runtime/delivery-prompt.d.ts.map +1 -1
- package/dist/server/runtime/delivery-prompt.js +53 -34
- package/dist/server/runtime/followup-appender.d.ts +20 -0
- package/dist/server/runtime/followup-appender.d.ts.map +1 -0
- package/dist/server/runtime/followup-appender.js +128 -0
- package/dist/server/runtime/host.d.ts +2 -0
- package/dist/server/runtime/host.d.ts.map +1 -1
- package/dist/server/runtime/host.js +8 -0
- package/dist/server/runtime/provider-runner.d.ts +16 -0
- package/dist/server/runtime/provider-runner.d.ts.map +1 -0
- package/dist/server/runtime/provider-runner.js +86 -0
- package/dist/server/runtime/runtime-bridge.d.ts +1 -1
- package/dist/server/runtime/runtime-bridge.d.ts.map +1 -1
- package/dist/server/runtime/runtime-session.service.d.ts +1 -1
- package/dist/server/runtime/runtime-session.service.d.ts.map +1 -1
- package/dist/server/runtime/runtime-session.service.js +1 -1
- package/dist/server/runtime/runtime-worker.d.ts +2 -10
- package/dist/server/runtime/runtime-worker.d.ts.map +1 -1
- package/dist/server/runtime/runtime-worker.js +60 -286
- package/dist/server/runtime-management/managed-runtime.d.ts.map +1 -0
- package/dist/server/runtime-management/runtime-release.d.ts.map +1 -0
- package/dist/server/{runtime → runtime-management}/runtime-upgrade.d.ts +1 -0
- package/dist/server/runtime-management/runtime-upgrade.d.ts.map +1 -0
- package/dist/server/{runtime → runtime-management}/runtime-upgrade.js +14 -0
- package/dist/server/services/system.service.d.ts +41 -0
- package/dist/server/services/system.service.d.ts.map +1 -0
- package/dist/server/services/system.service.js +154 -0
- package/dist/server/settings/settings.service.d.ts +2 -1
- package/dist/server/settings/settings.service.d.ts.map +1 -1
- package/dist/server/settings/settings.service.js +9 -1
- package/dist/server/slack/shortcuts.d.ts +0 -3
- package/dist/server/slack/shortcuts.d.ts.map +1 -1
- package/dist/server/slack/shortcuts.js +0 -3
- package/dist/server/slack-interactions/shortcut-ids.d.ts +4 -0
- package/dist/server/slack-interactions/shortcut-ids.d.ts.map +1 -0
- package/dist/server/slack-interactions/shortcut-ids.js +3 -0
- package/dist/server/slack-interactions/shortcut-views.d.ts +65 -0
- package/dist/server/slack-interactions/shortcut-views.d.ts.map +1 -0
- package/dist/server/slack-interactions/shortcut-views.js +211 -0
- package/dist/server/{slack → slack-interactions}/shortcut.service.d.ts +2 -47
- package/dist/server/slack-interactions/shortcut.service.d.ts.map +1 -0
- package/dist/server/slack-interactions/shortcut.service.js +227 -0
- package/dist/server/storage/jsonl-log.d.ts +9 -0
- package/dist/server/storage/jsonl-log.d.ts.map +1 -1
- package/dist/server/storage/jsonl-log.js +36 -1
- package/dist/server/storage/schema/server.store.d.ts +5 -0
- package/dist/server/storage/schema/server.store.d.ts.map +1 -1
- package/dist/server/storage/schema/server.store.js +2 -1
- package/dist/server/storage/schema/wake-queue.store.d.ts +15 -1
- package/dist/server/storage/schema/wake-queue.store.d.ts.map +1 -1
- package/dist/server/storage/schema/wake-queue.store.js +5 -3
- package/dist/server/tests/agent-config.test.d.ts +2 -0
- package/dist/server/tests/agent-config.test.d.ts.map +1 -0
- package/dist/server/tests/agent-config.test.js +229 -0
- package/dist/server/tests/agent-runtime.test.d.ts +2 -0
- package/dist/server/tests/agent-runtime.test.d.ts.map +1 -0
- package/dist/server/tests/agent-runtime.test.js +1110 -0
- package/dist/server/tests/agent-seed-memory.test.d.ts +2 -0
- package/dist/server/tests/agent-seed-memory.test.d.ts.map +1 -0
- package/dist/server/tests/agent-seed-memory.test.js +16 -0
- package/dist/server/tests/agent-skills.test.d.ts +2 -0
- package/dist/server/tests/agent-skills.test.d.ts.map +1 -0
- package/dist/server/tests/agent-skills.test.js +140 -0
- package/dist/server/tests/anima-home.d.ts +2 -0
- package/dist/server/tests/anima-home.d.ts.map +1 -0
- package/dist/server/tests/anima-home.js +4 -0
- package/dist/server/tests/cli-file.test.d.ts +2 -0
- package/dist/server/tests/cli-file.test.d.ts.map +1 -0
- package/dist/server/tests/cli-file.test.js +596 -0
- package/dist/server/tests/cli-message.test.d.ts +2 -0
- package/dist/server/tests/cli-message.test.d.ts.map +1 -0
- package/dist/server/tests/cli-message.test.js +1196 -0
- package/dist/server/tests/client-error-routes.test.d.ts +2 -0
- package/dist/server/tests/client-error-routes.test.d.ts.map +1 -0
- package/dist/server/tests/client-error-routes.test.js +163 -0
- package/dist/server/tests/config.test.d.ts +2 -0
- package/dist/server/tests/config.test.d.ts.map +1 -0
- package/dist/server/tests/config.test.js +497 -0
- package/dist/server/tests/default-skills.test.d.ts +2 -0
- package/dist/server/tests/default-skills.test.d.ts.map +1 -0
- package/dist/server/tests/default-skills.test.js +57 -0
- package/dist/server/tests/helpers/inbox.d.ts +10 -0
- package/dist/server/tests/helpers/inbox.d.ts.map +1 -0
- package/dist/server/tests/helpers/inbox.js +21 -0
- package/dist/server/tests/helpers/slack.d.ts +11 -0
- package/dist/server/tests/helpers/slack.d.ts.map +1 -0
- package/dist/server/tests/helpers/slack.js +17 -0
- package/dist/server/tests/helpers/state.d.ts +19 -0
- package/dist/server/tests/helpers/state.d.ts.map +1 -0
- package/dist/server/tests/helpers/state.js +69 -0
- package/dist/server/tests/inbox-slack-events.test.d.ts +2 -0
- package/dist/server/tests/inbox-slack-events.test.d.ts.map +1 -0
- package/dist/server/tests/inbox-slack-events.test.js +271 -0
- package/dist/server/tests/inbox.test.d.ts +2 -0
- package/dist/server/tests/inbox.test.d.ts.map +1 -0
- package/dist/server/tests/inbox.test.js +144 -0
- package/dist/server/tests/interactive-ask.test.d.ts +2 -0
- package/dist/server/tests/interactive-ask.test.d.ts.map +1 -0
- package/dist/server/tests/interactive-ask.test.js +387 -0
- package/dist/server/tests/kb.test.d.ts +2 -0
- package/dist/server/tests/kb.test.d.ts.map +1 -0
- package/dist/server/tests/kb.test.js +371 -0
- package/dist/server/tests/message.service.test.d.ts +2 -0
- package/dist/server/tests/message.service.test.d.ts.map +1 -0
- package/dist/server/tests/message.service.test.js +151 -0
- package/dist/server/tests/messages.test.d.ts +2 -0
- package/dist/server/tests/messages.test.d.ts.map +1 -0
- package/dist/server/tests/messages.test.js +12 -0
- package/dist/server/tests/prompt-attachments.test.d.ts +2 -0
- package/dist/server/tests/prompt-attachments.test.d.ts.map +1 -0
- package/dist/server/tests/prompt-attachments.test.js +274 -0
- package/dist/server/tests/provider-usage.test.d.ts +2 -0
- package/dist/server/tests/provider-usage.test.d.ts.map +1 -0
- package/dist/server/tests/provider-usage.test.js +97 -0
- package/dist/server/tests/reminders.test.d.ts +2 -0
- package/dist/server/tests/reminders.test.d.ts.map +1 -0
- package/dist/server/tests/reminders.test.js +383 -0
- package/dist/server/tests/runtime-cli.test.d.ts +2 -0
- package/dist/server/tests/runtime-cli.test.d.ts.map +1 -0
- package/dist/server/tests/runtime-cli.test.js +21 -0
- package/dist/server/tests/runtime-upgrade.test.d.ts +2 -0
- package/dist/server/tests/runtime-upgrade.test.d.ts.map +1 -0
- package/dist/server/tests/runtime-upgrade.test.js +307 -0
- package/dist/server/tests/runtime-worker.test.d.ts +2 -0
- package/dist/server/tests/runtime-worker.test.d.ts.map +1 -0
- package/dist/server/tests/runtime-worker.test.js +1021 -0
- package/dist/server/tests/runtime.test.d.ts +2 -0
- package/dist/server/tests/runtime.test.d.ts.map +1 -0
- package/dist/server/tests/runtime.test.js +354 -0
- package/dist/server/tests/services.test.d.ts +2 -0
- package/dist/server/tests/services.test.d.ts.map +1 -0
- package/dist/server/tests/services.test.js +636 -0
- package/dist/server/tests/slack-files.test.d.ts +2 -0
- package/dist/server/tests/slack-files.test.d.ts.map +1 -0
- package/dist/server/tests/slack-files.test.js +118 -0
- package/dist/server/tests/slack-shortcuts.test.d.ts +2 -0
- package/dist/server/tests/slack-shortcuts.test.d.ts.map +1 -0
- package/dist/server/tests/slack-shortcuts.test.js +310 -0
- package/dist/server/tests/slack.test.d.ts +2 -0
- package/dist/server/tests/slack.test.d.ts.map +1 -0
- package/dist/server/tests/slack.test.js +213 -0
- package/dist/server/tests/state-cache.test.d.ts +2 -0
- package/dist/server/tests/state-cache.test.d.ts.map +1 -0
- package/dist/server/tests/state-cache.test.js +184 -0
- package/dist/server/tests/subscriptions.test.d.ts +2 -0
- package/dist/server/tests/subscriptions.test.d.ts.map +1 -0
- package/dist/server/tests/subscriptions.test.js +292 -0
- package/dist/server/tests/system-service.test.d.ts +2 -0
- package/dist/server/tests/system-service.test.d.ts.map +1 -0
- package/dist/server/tests/system-service.test.js +20 -0
- package/dist/server/tests/url-routes.test.d.ts +2 -0
- package/dist/server/tests/url-routes.test.d.ts.map +1 -0
- package/dist/server/tests/url-routes.test.js +217 -0
- package/dist/server/tests/web-api.test.d.ts +2 -0
- package/dist/server/tests/web-api.test.d.ts.map +1 -0
- package/dist/server/tests/web-api.test.js +1759 -0
- package/dist/server/web/app.d.ts.map +1 -1
- package/dist/server/web/app.js +2 -0
- package/dist/server/web/client-error-routes.d.ts +3 -0
- package/dist/server/web/client-error-routes.d.ts.map +1 -0
- package/dist/server/web/client-error-routes.js +101 -0
- package/dist/server/web/system-routes.d.ts.map +1 -1
- package/dist/server/web/system-routes.js +21 -131
- package/dist/shared/agent-config.d.ts +8 -18
- package/dist/shared/agent-config.d.ts.map +1 -1
- package/dist/shared/agent-config.js +3 -4
- package/dist/shared/inbox.d.ts +27 -0
- package/dist/shared/inbox.d.ts.map +1 -1
- package/dist/shared/inbox.js +1 -0
- package/dist/shared/server-info.d.ts +6 -5
- package/dist/shared/server-info.d.ts.map +1 -1
- package/dist/shared/server-info.js +3 -1
- package/dist/shared/server-settings.d.ts +6 -0
- package/dist/shared/server-settings.d.ts.map +1 -1
- package/dist/shared/server-settings.js +1 -0
- package/dist/shared/skills.d.ts +24 -3
- package/dist/shared/skills.d.ts.map +1 -1
- package/dist/web/assets/activity-DHjip8tY.js +7 -0
- package/dist/web/assets/clipboard-D2NSC52v.js +1 -0
- package/dist/web/assets/{external-link-Dt0qTpmV.js → external-link-Bhr1WdRS.js} +1 -1
- package/dist/web/assets/{file-text-Dd9ys6py.js → file-text-CYMA_SMA.js} +1 -1
- package/dist/web/assets/{index-CzAQnbuO.js → index-CVpew409.js} +5 -5
- package/dist/web/assets/index-mh0uJTkY.css +2 -0
- package/dist/web/assets/kb-DDVpYkT9.js +35 -0
- package/dist/web/assets/profile-CBy6GNzp.js +1 -0
- package/dist/web/assets/reminders-Bbwb9QNT.js +1 -0
- package/dist/web/favicon.svg +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/templates/runtime-standing-prompt.md +16 -2
- package/templates/skills/find-skills/SKILL.md +133 -0
- package/dist/server/runtime/activity-payload.d.ts.map +0 -1
- package/dist/server/runtime/activity-text.d.ts +0 -4
- package/dist/server/runtime/activity-text.d.ts.map +0 -1
- package/dist/server/runtime/activity-text.js +0 -16
- package/dist/server/runtime/managed-runtime.d.ts.map +0 -1
- package/dist/server/runtime/provider-contract.d.ts.map +0 -1
- package/dist/server/runtime/runtime-release.d.ts.map +0 -1
- package/dist/server/runtime/runtime-upgrade.d.ts.map +0 -1
- package/dist/server/slack/shortcut.service.d.ts.map +0 -1
- package/dist/server/slack/shortcut.service.js +0 -493
- package/dist/web/assets/activity-BP0C81IV.js +0 -7
- package/dist/web/assets/globe-DmDZSgDP.js +0 -1
- package/dist/web/assets/index-DKecrvN0.css +0 -2
- package/dist/web/assets/kb-3wFeP2Jt.js +0 -32
- package/dist/web/assets/profile-D7wPZXW_.js +0 -1
- package/dist/web/assets/reminders-DOhroVwo.js +0 -1
- /package/dist/server/{runtime/provider-contract.js → providers/contract.js} +0 -0
- /package/dist/server/{runtime → runtime-management}/managed-runtime.d.ts +0 -0
- /package/dist/server/{runtime → runtime-management}/managed-runtime.js +0 -0
- /package/dist/server/{runtime → runtime-management}/runtime-release.d.ts +0 -0
- /package/dist/server/{runtime → runtime-management}/runtime-release.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReleaseTrack, SidebarOrder } from '../../shared/server-settings.js';
|
|
1
|
+
import type { ReleaseTrack, ServerTrack, SidebarOrder } from '../../shared/server-settings.js';
|
|
2
2
|
import { type ServerConfig, type ServerConfigStore } from '../storage/schema/server.store.js';
|
|
3
3
|
export interface DashboardSettings {
|
|
4
4
|
host: string;
|
|
@@ -14,6 +14,7 @@ export declare class ServerSettingsService {
|
|
|
14
14
|
}): Promise<DashboardSettings>;
|
|
15
15
|
getSidebarOrder(): Promise<SidebarOrder>;
|
|
16
16
|
getReleaseTrack(): Promise<ReleaseTrack>;
|
|
17
|
+
getTrack(): Promise<ServerTrack>;
|
|
17
18
|
setReleaseTrack(releaseTrack: ReleaseTrack): Promise<ReleaseTrack>;
|
|
18
19
|
setSidebarOrder(sidebarOrder: SidebarOrder): Promise<SidebarOrder>;
|
|
19
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.service.d.ts","sourceRoot":"","sources":["../../../server/settings/settings.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.service.d.ts","sourceRoot":"","sources":["../../../server/settings/settings.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/F,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACvB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,qBAAqB;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,GAAE,iBAAqC;IAEzE,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC;IAI7B,oBAAoB,CAAC,KAAK,EAAE;QAChC,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQxB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAKxC,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAOxC,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;IAKhC,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAMlE,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CAKzE;AAED,eAAO,MAAM,4BAA4B,uBAA8B,CAAC"}
|
|
@@ -20,11 +20,19 @@ export class ServerSettingsService {
|
|
|
20
20
|
}
|
|
21
21
|
async getReleaseTrack() {
|
|
22
22
|
const config = await this.store.read();
|
|
23
|
+
if (config.releaseTrack)
|
|
24
|
+
return config.releaseTrack;
|
|
25
|
+
if (config.track === 'canary' || config.track === 'stable')
|
|
26
|
+
return config.track;
|
|
23
27
|
return config.releaseTrack ?? 'stable';
|
|
24
28
|
}
|
|
29
|
+
async getTrack() {
|
|
30
|
+
const config = await this.store.read();
|
|
31
|
+
return config.track ?? config.releaseTrack ?? 'stable';
|
|
32
|
+
}
|
|
25
33
|
async setReleaseTrack(releaseTrack) {
|
|
26
34
|
const config = await this.store.read();
|
|
27
|
-
await this.store.write({ ...config, releaseTrack });
|
|
35
|
+
await this.store.write({ ...config, releaseTrack, track: releaseTrack });
|
|
28
36
|
return releaseTrack;
|
|
29
37
|
}
|
|
30
38
|
async setSidebarOrder(sidebarOrder) {
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
export declare const SLACK_SHORTCUT_COMMANDS_SCOPE = "commands";
|
|
2
|
-
export declare const SLACK_STOP_CONFIRM_VIEW_CALLBACK_ID = "anima.stop.confirm";
|
|
3
|
-
export declare const SLACK_VIEW_REMINDERS_ACTION_ID = "anima.home.view_reminders";
|
|
4
|
-
export declare const SLACK_VIEW_REMINDER_DETAIL_ACTION_ID = "anima.home.view_reminder_detail";
|
|
5
2
|
export declare const SLACK_SHORTCUTS: readonly [{
|
|
6
3
|
readonly callback_id: "anima.home";
|
|
7
4
|
readonly description: "Open this agent's Anima home.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortcuts.d.ts","sourceRoot":"","sources":["../../../server/slack/shortcuts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"shortcuts.d.ts","sourceRoot":"","sources":["../../../server/slack/shortcuts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,aAAa,CAAC;AAExD,eAAO,MAAM,eAAe;;;;;;;;;;EAalB,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AAKrE,wBAAgB,+BAA+B,IAAI,MAAM,CAexD;AAED,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,OAAO,CAAC;IACvB,0BAA0B,EAAE,MAAM,EAAE,CAAC;IACrC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,EAAE,2BAA2B,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,OAAO,GAAG,2BAA2B,CAuB3F;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,OAAO,GAAG,2BAA2B,CAyC1F;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAKjF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEnE"}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
export const SLACK_SHORTCUT_COMMANDS_SCOPE = 'commands';
|
|
2
|
-
export const SLACK_STOP_CONFIRM_VIEW_CALLBACK_ID = 'anima.stop.confirm';
|
|
3
|
-
export const SLACK_VIEW_REMINDERS_ACTION_ID = 'anima.home.view_reminders';
|
|
4
|
-
export const SLACK_VIEW_REMINDER_DETAIL_ACTION_ID = 'anima.home.view_reminder_detail';
|
|
5
2
|
export const SLACK_SHORTCUTS = [
|
|
6
3
|
{
|
|
7
4
|
callback_id: 'anima.home',
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const SLACK_STOP_CONFIRM_VIEW_CALLBACK_ID = "anima.stop.confirm";
|
|
2
|
+
export declare const SLACK_VIEW_REMINDERS_ACTION_ID = "anima.home.view_reminders";
|
|
3
|
+
export declare const SLACK_VIEW_REMINDER_DETAIL_ACTION_ID = "anima.home.view_reminder_detail";
|
|
4
|
+
//# sourceMappingURL=shortcut-ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcut-ids.d.ts","sourceRoot":"","sources":["../../../server/slack-interactions/shortcut-ids.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mCAAmC,uBAAuB,CAAC;AACxE,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E,eAAO,MAAM,oCAAoC,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { AgentConfig } from '../../shared/agent-config.js';
|
|
2
|
+
import type { Reminder } from '../../shared/reminder.js';
|
|
3
|
+
import type { AgentStatusSummary } from '../../shared/snapshot.js';
|
|
4
|
+
type MrkdwnText = {
|
|
5
|
+
type: 'mrkdwn';
|
|
6
|
+
text: string;
|
|
7
|
+
};
|
|
8
|
+
type PlainText = {
|
|
9
|
+
type: 'plain_text';
|
|
10
|
+
text: string;
|
|
11
|
+
emoji?: boolean;
|
|
12
|
+
};
|
|
13
|
+
type ImageElement = {
|
|
14
|
+
type: 'image';
|
|
15
|
+
image_url: string;
|
|
16
|
+
alt_text: string;
|
|
17
|
+
};
|
|
18
|
+
type ButtonElement = {
|
|
19
|
+
type: 'button';
|
|
20
|
+
text: PlainText;
|
|
21
|
+
action_id: string;
|
|
22
|
+
value?: string;
|
|
23
|
+
};
|
|
24
|
+
type SectionAccessory = ImageElement | ButtonElement;
|
|
25
|
+
type ShortcutModalBlock = {
|
|
26
|
+
type: 'section';
|
|
27
|
+
text: MrkdwnText;
|
|
28
|
+
accessory?: SectionAccessory;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'context';
|
|
31
|
+
elements: Array<MrkdwnText>;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'header';
|
|
34
|
+
text: PlainText;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'divider';
|
|
37
|
+
} | {
|
|
38
|
+
type: 'actions';
|
|
39
|
+
elements: ButtonElement[];
|
|
40
|
+
};
|
|
41
|
+
export type ShortcutModalView = {
|
|
42
|
+
blocks: ShortcutModalBlock[];
|
|
43
|
+
callback_id?: string;
|
|
44
|
+
close?: PlainText;
|
|
45
|
+
private_metadata?: string;
|
|
46
|
+
submit?: PlainText;
|
|
47
|
+
title: PlainText;
|
|
48
|
+
type: 'modal';
|
|
49
|
+
};
|
|
50
|
+
export interface ShortcutModalInput {
|
|
51
|
+
callbackId?: string;
|
|
52
|
+
close?: string;
|
|
53
|
+
context?: string;
|
|
54
|
+
lines: string[];
|
|
55
|
+
privateMetadata?: string;
|
|
56
|
+
submit?: string;
|
|
57
|
+
title: string;
|
|
58
|
+
}
|
|
59
|
+
export declare function homeView(agent: AgentConfig, status: AgentStatusSummary, reminders: Reminder[], now: Date): ShortcutModalView;
|
|
60
|
+
export declare function remindersView(reminders: Reminder[], now: Date): ShortcutModalView;
|
|
61
|
+
export declare function reminderDetailView(reminder: Reminder, now: Date): ShortcutModalView;
|
|
62
|
+
export declare function shortcutModal(input: ShortcutModalInput): ShortcutModalView;
|
|
63
|
+
export declare function escapeMrkdwn(value: string): string;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=shortcut-views.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcut-views.d.ts","sourceRoot":"","sources":["../../../server/slack-interactions/shortcut-views.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,0BAA0B,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAOnE,KAAK,UAAU,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AACnD,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACvE,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAC3E,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,gBAAgB,GAAG,YAAY,GAAG,aAAa,CAAC;AAErD,KAAK,kBAAkB,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,wBAAgB,QAAQ,CACtB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,QAAQ,EAAE,EACrB,GAAG,EAAE,IAAI,GACR,iBAAiB,CAgFnB;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,GAAG,iBAAiB,CAmCjF;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,GAAG,iBAAiB,CAkCnF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,iBAAiB,CAuB1E;AA0CD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { SLACK_STOP_CONFIRM_VIEW_CALLBACK_ID, SLACK_VIEW_REMINDER_DETAIL_ACTION_ID, SLACK_VIEW_REMINDERS_ACTION_ID, } from './shortcut-ids.js';
|
|
2
|
+
export function homeView(agent, status, reminders, now) {
|
|
3
|
+
const displayName = agent.profile.displayName;
|
|
4
|
+
const role = agent.profile.role;
|
|
5
|
+
const state = status.currentItemId
|
|
6
|
+
? 'busy'
|
|
7
|
+
: status.queueDepth > 0
|
|
8
|
+
? 'queued'
|
|
9
|
+
: 'idle';
|
|
10
|
+
const blocks = [];
|
|
11
|
+
const identityText = role.trim()
|
|
12
|
+
? `*${escapeMrkdwn(displayName)}*\n${escapeMrkdwn(role)}`
|
|
13
|
+
: `*${escapeMrkdwn(displayName)}*`;
|
|
14
|
+
blocks.push({ type: 'section', text: { type: 'mrkdwn', text: identityText } });
|
|
15
|
+
if (agent.owner) {
|
|
16
|
+
const ownerLabel = agent.owner.handle
|
|
17
|
+
? `@${escapeMrkdwn(agent.owner.handle)}`
|
|
18
|
+
: escapeMrkdwn(agent.owner.displayName);
|
|
19
|
+
blocks.push({
|
|
20
|
+
type: 'context',
|
|
21
|
+
elements: [{ type: 'mrkdwn', text: `Owner: ${ownerLabel}` }],
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
blocks.push({ type: 'divider' });
|
|
25
|
+
const statusEmoji = state === 'busy' ? ':gear:' : state === 'queued' ? ':hourglass_flowing_sand:' : ':white_check_mark:';
|
|
26
|
+
const statusLabel = state === 'busy' ? 'Working' : state === 'queued' ? 'Queued' : 'Idle';
|
|
27
|
+
const elapsed = state === 'busy' && status.currentItemStartedAt
|
|
28
|
+
? ` · ${elapsedLabel(status.currentItemStartedAt, now)}`
|
|
29
|
+
: '';
|
|
30
|
+
blocks.push({
|
|
31
|
+
type: 'section',
|
|
32
|
+
text: { type: 'mrkdwn', text: `${statusEmoji} *${statusLabel}*${elapsed}` },
|
|
33
|
+
});
|
|
34
|
+
blocks.push({ type: 'divider' });
|
|
35
|
+
if (reminders.length === 0) {
|
|
36
|
+
blocks.push({
|
|
37
|
+
type: 'section',
|
|
38
|
+
text: { type: 'mrkdwn', text: ':alarm_clock: *Reminders*\n_None scheduled_' },
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const next = reminders[0];
|
|
43
|
+
const nextDue = next.nextDueAt ? humanDueLabel(next.nextDueAt, now) : '';
|
|
44
|
+
const preview = nextDue
|
|
45
|
+
? `_Next: "${escapeMrkdwn(next.title)}" · ${nextDue}_`
|
|
46
|
+
: `_${escapeMrkdwn(next.title)}_`;
|
|
47
|
+
const count = reminders.length;
|
|
48
|
+
blocks.push({
|
|
49
|
+
type: 'section',
|
|
50
|
+
text: {
|
|
51
|
+
type: 'mrkdwn',
|
|
52
|
+
text: `:alarm_clock: *Reminders* · ${count} scheduled\n${preview}`,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
blocks.push({
|
|
56
|
+
type: 'actions',
|
|
57
|
+
elements: [{
|
|
58
|
+
action_id: SLACK_VIEW_REMINDERS_ACTION_ID,
|
|
59
|
+
text: { emoji: true, text: `View all (${count}) →`, type: 'plain_text' },
|
|
60
|
+
type: 'button',
|
|
61
|
+
}],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
blocks,
|
|
66
|
+
close: { text: 'Close', type: 'plain_text' },
|
|
67
|
+
...(state === 'busy' ? {
|
|
68
|
+
callback_id: SLACK_STOP_CONFIRM_VIEW_CALLBACK_ID,
|
|
69
|
+
private_metadata: JSON.stringify({ itemId: status.currentItemId }),
|
|
70
|
+
submit: { text: 'Stop', type: 'plain_text' },
|
|
71
|
+
} : {}),
|
|
72
|
+
title: { text: 'Home', type: 'plain_text' },
|
|
73
|
+
type: 'modal',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export function remindersView(reminders, now) {
|
|
77
|
+
const blocks = [];
|
|
78
|
+
if (reminders.length === 0) {
|
|
79
|
+
blocks.push({
|
|
80
|
+
type: 'section',
|
|
81
|
+
text: { type: 'mrkdwn', text: '_No reminders scheduled._' },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
for (const reminder of reminders) {
|
|
86
|
+
const due = reminder.nextDueAt ? humanDueLabel(reminder.nextDueAt, now) : '';
|
|
87
|
+
const recurrence = scheduleLabel(reminder.schedule);
|
|
88
|
+
const meta = [due, recurrence].filter(Boolean).join(' · ');
|
|
89
|
+
blocks.push({
|
|
90
|
+
accessory: {
|
|
91
|
+
action_id: SLACK_VIEW_REMINDER_DETAIL_ACTION_ID,
|
|
92
|
+
text: { emoji: false, text: 'View →', type: 'plain_text' },
|
|
93
|
+
type: 'button',
|
|
94
|
+
value: reminder.reminderId,
|
|
95
|
+
},
|
|
96
|
+
text: {
|
|
97
|
+
text: `*${escapeMrkdwn(reminder.title)}*${meta ? `\n_${escapeMrkdwn(meta)}_` : ''}`,
|
|
98
|
+
type: 'mrkdwn',
|
|
99
|
+
},
|
|
100
|
+
type: 'section',
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
blocks,
|
|
106
|
+
close: { text: 'Close', type: 'plain_text' },
|
|
107
|
+
title: { text: 'Reminders', type: 'plain_text' },
|
|
108
|
+
type: 'modal',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function reminderDetailView(reminder, now) {
|
|
112
|
+
const blocks = [];
|
|
113
|
+
const due = reminder.nextDueAt ? humanDueLabel(reminder.nextDueAt, now) : '';
|
|
114
|
+
const recurrence = scheduleLabel(reminder.schedule);
|
|
115
|
+
const meta = [due, recurrence].filter(Boolean).join(' · ');
|
|
116
|
+
blocks.push({
|
|
117
|
+
type: 'section',
|
|
118
|
+
text: {
|
|
119
|
+
type: 'mrkdwn',
|
|
120
|
+
text: `*${escapeMrkdwn(reminder.title)}*${meta ? `\n_${escapeMrkdwn(meta)}_` : ''}`,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
const SECTION_LIMIT = 2900;
|
|
124
|
+
if (reminder.instructions.trim()) {
|
|
125
|
+
const escaped = escapeMrkdwn(reminder.instructions);
|
|
126
|
+
const text = escaped.length > SECTION_LIMIT
|
|
127
|
+
? `${escaped.slice(0, SECTION_LIMIT)}…`
|
|
128
|
+
: escaped;
|
|
129
|
+
blocks.push({ type: 'divider' });
|
|
130
|
+
blocks.push({
|
|
131
|
+
type: 'section',
|
|
132
|
+
text: { type: 'mrkdwn', text },
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
blocks,
|
|
137
|
+
close: { text: 'Close', type: 'plain_text' },
|
|
138
|
+
title: { text: 'Reminder', type: 'plain_text' },
|
|
139
|
+
type: 'modal',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export function shortcutModal(input) {
|
|
143
|
+
const blocks = [
|
|
144
|
+
...input.lines.map((line) => ({
|
|
145
|
+
text: { text: line, type: 'mrkdwn' },
|
|
146
|
+
type: 'section',
|
|
147
|
+
})),
|
|
148
|
+
...(input.context ? [{
|
|
149
|
+
elements: [{ text: input.context, type: 'mrkdwn' }],
|
|
150
|
+
type: 'context',
|
|
151
|
+
}] : []),
|
|
152
|
+
];
|
|
153
|
+
return {
|
|
154
|
+
blocks,
|
|
155
|
+
...(input.callbackId ? { callback_id: input.callbackId } : {}),
|
|
156
|
+
close: { text: input.close ?? 'Close', type: 'plain_text' },
|
|
157
|
+
...(input.privateMetadata ? { private_metadata: input.privateMetadata } : {}),
|
|
158
|
+
...(input.submit ? { submit: { text: input.submit, type: 'plain_text' } } : {}),
|
|
159
|
+
title: { text: input.title.slice(0, 24), type: 'plain_text' },
|
|
160
|
+
type: 'modal',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function humanDueLabel(dueAt, now) {
|
|
164
|
+
const ms = Date.parse(dueAt) - now.getTime();
|
|
165
|
+
if (ms < 0)
|
|
166
|
+
return 'overdue';
|
|
167
|
+
const totalMin = Math.round(ms / 60_000);
|
|
168
|
+
if (totalMin < 1)
|
|
169
|
+
return 'in <1m';
|
|
170
|
+
if (totalMin < 60)
|
|
171
|
+
return `in ${totalMin}m`;
|
|
172
|
+
const h = Math.floor(totalMin / 60);
|
|
173
|
+
const m = totalMin % 60;
|
|
174
|
+
if (h < 24)
|
|
175
|
+
return m > 0 ? `in ${h}h ${m}m` : `in ${h}h`;
|
|
176
|
+
const d = Math.floor(h / 24);
|
|
177
|
+
const rh = h % 24;
|
|
178
|
+
return rh > 0 ? `in ${d}d ${rh}h` : `in ${d}d`;
|
|
179
|
+
}
|
|
180
|
+
function scheduleLabel(schedule) {
|
|
181
|
+
switch (schedule.kind) {
|
|
182
|
+
case 'once': return 'once';
|
|
183
|
+
case 'daily': return 'repeating daily';
|
|
184
|
+
case 'weekly': return `weekly ${schedule.weekdays.slice(0, 3).join('/')}`;
|
|
185
|
+
case 'interval': {
|
|
186
|
+
const ms = schedule.intervalMs;
|
|
187
|
+
if (ms < 3_600_000)
|
|
188
|
+
return `every ${Math.round(ms / 60_000)}m`;
|
|
189
|
+
if (ms < 86_400_000)
|
|
190
|
+
return `every ${Math.round(ms / 3_600_000)}h`;
|
|
191
|
+
return `every ${Math.round(ms / 86_400_000)}d`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function elapsedLabel(startedAt, now) {
|
|
196
|
+
const startedMs = Date.parse(startedAt);
|
|
197
|
+
if (!Number.isFinite(startedMs))
|
|
198
|
+
return 'elapsed unknown';
|
|
199
|
+
const seconds = Math.max(0, Math.floor((now.getTime() - startedMs) / 1000));
|
|
200
|
+
if (seconds < 60)
|
|
201
|
+
return `${seconds}s`;
|
|
202
|
+
const minutes = Math.floor(seconds / 60);
|
|
203
|
+
if (minutes < 60)
|
|
204
|
+
return `${minutes}m`;
|
|
205
|
+
const hours = Math.floor(minutes / 60);
|
|
206
|
+
const remMinutes = minutes % 60;
|
|
207
|
+
return `${hours}h ${remMinutes}m`;
|
|
208
|
+
}
|
|
209
|
+
export function escapeMrkdwn(value) {
|
|
210
|
+
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
|
211
|
+
}
|
|
@@ -3,6 +3,8 @@ import type { AgentConfig } from '../../shared/agent-config.js';
|
|
|
3
3
|
import type { AgentStatusSummary } from '../../shared/snapshot.js';
|
|
4
4
|
import { type ActivityRecorder } from '../activities/activity.service.js';
|
|
5
5
|
import { type ReminderService } from '../reminders/reminder.service.js';
|
|
6
|
+
import type { ShortcutModalView } from './shortcut-views.js';
|
|
7
|
+
export type { ShortcutModalView } from './shortcut-views.js';
|
|
6
8
|
export interface SlackShortcutUser {
|
|
7
9
|
id: string;
|
|
8
10
|
name?: string;
|
|
@@ -32,52 +34,6 @@ export interface SlackShortcutBody {
|
|
|
32
34
|
export interface SlackShortcutView {
|
|
33
35
|
private_metadata?: string;
|
|
34
36
|
}
|
|
35
|
-
type MrkdwnText = {
|
|
36
|
-
type: 'mrkdwn';
|
|
37
|
-
text: string;
|
|
38
|
-
};
|
|
39
|
-
type PlainText = {
|
|
40
|
-
type: 'plain_text';
|
|
41
|
-
text: string;
|
|
42
|
-
emoji?: boolean;
|
|
43
|
-
};
|
|
44
|
-
type ImageElement = {
|
|
45
|
-
type: 'image';
|
|
46
|
-
image_url: string;
|
|
47
|
-
alt_text: string;
|
|
48
|
-
};
|
|
49
|
-
type ButtonElement = {
|
|
50
|
-
type: 'button';
|
|
51
|
-
text: PlainText;
|
|
52
|
-
action_id: string;
|
|
53
|
-
value?: string;
|
|
54
|
-
};
|
|
55
|
-
type SectionAccessory = ImageElement | ButtonElement;
|
|
56
|
-
type ShortcutModalBlock = {
|
|
57
|
-
type: 'section';
|
|
58
|
-
text: MrkdwnText;
|
|
59
|
-
accessory?: SectionAccessory;
|
|
60
|
-
} | {
|
|
61
|
-
type: 'context';
|
|
62
|
-
elements: Array<MrkdwnText>;
|
|
63
|
-
} | {
|
|
64
|
-
type: 'header';
|
|
65
|
-
text: PlainText;
|
|
66
|
-
} | {
|
|
67
|
-
type: 'divider';
|
|
68
|
-
} | {
|
|
69
|
-
type: 'actions';
|
|
70
|
-
elements: ButtonElement[];
|
|
71
|
-
};
|
|
72
|
-
export type ShortcutModalView = {
|
|
73
|
-
blocks: ShortcutModalBlock[];
|
|
74
|
-
callback_id?: string;
|
|
75
|
-
close?: PlainText;
|
|
76
|
-
private_metadata?: string;
|
|
77
|
-
submit?: PlainText;
|
|
78
|
-
title: PlainText;
|
|
79
|
-
type: 'modal';
|
|
80
|
-
};
|
|
81
37
|
interface ShortcutRuntimeService {
|
|
82
38
|
getStatus(agentId: string): Promise<AgentStatusSummary>;
|
|
83
39
|
stopCurrentItem(agentId: string): Promise<void>;
|
|
@@ -136,5 +92,4 @@ export declare class SlackShortcutService {
|
|
|
136
92
|
}
|
|
137
93
|
export declare const defaultSlackShortcutService: SlackShortcutService;
|
|
138
94
|
export declare function userIdFromShortcutBody(body: unknown): string | undefined;
|
|
139
|
-
export {};
|
|
140
95
|
//# sourceMappingURL=shortcut.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcut.service.d.ts","sourceRoot":"","sources":["../../../server/slack-interactions/shortcut.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { defaultActivityRecorder } from '../activities/activity.service.js';
|
|
2
|
+
import { defaultAgentRegistryService } from '../agents/agent.service.js';
|
|
3
|
+
import { nowIso } from '../ids.js';
|
|
4
|
+
import { WakeQueueService } from '../inbox/wake-queue.service.js';
|
|
5
|
+
import { reminderServiceForAgent } from '../reminders/reminder.service.js';
|
|
6
|
+
import { defaultRuntimeService, RuntimeServiceError } from '../runtime/runtime.service.js';
|
|
7
|
+
import { escapeMrkdwn, homeView, reminderDetailView, remindersView, shortcutModal } from './shortcut-views.js';
|
|
8
|
+
export class SlackShortcutService {
|
|
9
|
+
activityRecorder;
|
|
10
|
+
agentService;
|
|
11
|
+
now;
|
|
12
|
+
reminderServiceForAgent;
|
|
13
|
+
runtimeService;
|
|
14
|
+
constructor(deps = {}) {
|
|
15
|
+
this.activityRecorder = deps.activityRecorder ?? defaultActivityRecorder;
|
|
16
|
+
this.agentService = deps.agentService ?? defaultAgentRegistryService;
|
|
17
|
+
this.now = deps.now ?? (() => new Date());
|
|
18
|
+
this.reminderServiceForAgent = deps.reminderServiceForAgent ?? reminderServiceForAgent;
|
|
19
|
+
this.runtimeService = deps.runtimeService ?? defaultRuntimeService;
|
|
20
|
+
}
|
|
21
|
+
async handleShortcut(input) {
|
|
22
|
+
switch (input.body.callback_id) {
|
|
23
|
+
case 'anima.home':
|
|
24
|
+
await this.showHome(input);
|
|
25
|
+
return;
|
|
26
|
+
default:
|
|
27
|
+
await this.openModal(input.client, input.body, {
|
|
28
|
+
title: 'Shortcut unavailable',
|
|
29
|
+
lines: ['This shortcut is not supported by this Anima build yet.'],
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async confirmStop(input) {
|
|
34
|
+
const status = await this.runtimeService.getStatus(input.agentId);
|
|
35
|
+
const metadata = stopConfirmMetadata(input.view);
|
|
36
|
+
if (!status.currentItemId) {
|
|
37
|
+
await this.recordShortcutActivity(input.agentId, 'anima.shortcut.stop', {
|
|
38
|
+
outcome: 'idle',
|
|
39
|
+
userId: input.userId,
|
|
40
|
+
});
|
|
41
|
+
return shortcutModal({
|
|
42
|
+
title: 'Nothing running',
|
|
43
|
+
lines: ['This agent is idle. No current turn was stopped.'],
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (metadata.itemId && metadata.itemId !== status.currentItemId) {
|
|
47
|
+
await this.recordShortcutActivity(input.agentId, 'anima.shortcut.stop', {
|
|
48
|
+
currentItemId: status.currentItemId,
|
|
49
|
+
requestedItemId: metadata.itemId,
|
|
50
|
+
outcome: 'item_changed',
|
|
51
|
+
userId: input.userId,
|
|
52
|
+
});
|
|
53
|
+
return shortcutModal({
|
|
54
|
+
title: 'Item changed',
|
|
55
|
+
lines: [
|
|
56
|
+
'The current turn changed after this confirmation opened.',
|
|
57
|
+
'Open Stop again to interrupt the new current turn.',
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
await this.runtimeService.stopCurrentItem(input.agentId);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (!(error instanceof RuntimeServiceError) || error.statusCode !== 409)
|
|
66
|
+
throw error;
|
|
67
|
+
await this.recordShortcutActivity(input.agentId, 'anima.shortcut.stop', {
|
|
68
|
+
outcome: 'idle',
|
|
69
|
+
userId: input.userId,
|
|
70
|
+
});
|
|
71
|
+
return shortcutModal({
|
|
72
|
+
title: 'Nothing running',
|
|
73
|
+
lines: ['This agent became idle before Stop was applied.'],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
await this.recordShortcutActivity(input.agentId, 'anima.shortcut.stop', {
|
|
77
|
+
itemId: status.currentItemId,
|
|
78
|
+
outcome: 'stop_requested',
|
|
79
|
+
userId: input.userId,
|
|
80
|
+
});
|
|
81
|
+
return shortcutModal({
|
|
82
|
+
title: 'Stop requested',
|
|
83
|
+
lines: [
|
|
84
|
+
`Requested stop for current item \`${escapeMrkdwn(status.currentItemId)}\`.`,
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** Handles the "View all reminders" button — pushes a read-only reminder list. */
|
|
89
|
+
async showRemindersView(input) {
|
|
90
|
+
const reminders = await this.reminderServiceForAgent(input.agentId).listReminders({
|
|
91
|
+
statuses: ['scheduled'],
|
|
92
|
+
});
|
|
93
|
+
await input.client.views.push({
|
|
94
|
+
trigger_id: input.triggerId,
|
|
95
|
+
view: remindersView(reminders, this.now()),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/** Handles a per-reminder "View →" button — pushes a single-reminder detail view. */
|
|
99
|
+
async showReminderDetailView(input) {
|
|
100
|
+
const reminders = await this.reminderServiceForAgent(input.agentId).listReminders({
|
|
101
|
+
statuses: ['scheduled'],
|
|
102
|
+
});
|
|
103
|
+
const reminder = reminders.find((r) => r.reminderId === input.reminderId);
|
|
104
|
+
if (!reminder)
|
|
105
|
+
return; // reminder cancelled or not found — silently ignore
|
|
106
|
+
await input.client.views.push({
|
|
107
|
+
trigger_id: input.triggerId,
|
|
108
|
+
view: reminderDetailView(reminder, this.now()),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async showHome(input) {
|
|
112
|
+
const [agent, status, reminders] = await Promise.all([
|
|
113
|
+
this.agentService.serviceFor(input.agentId).getConfig(),
|
|
114
|
+
this.runtimeService.getStatus(input.agentId),
|
|
115
|
+
this.reminderServiceForAgent(input.agentId).listReminders({ statuses: ['scheduled'] }),
|
|
116
|
+
]);
|
|
117
|
+
if (!input.body.trigger_id)
|
|
118
|
+
return;
|
|
119
|
+
await input.client.views.open({
|
|
120
|
+
trigger_id: input.body.trigger_id,
|
|
121
|
+
view: homeView(agent, status, reminders, this.now()),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async handMessageToAgent(input) {
|
|
125
|
+
const message = input.body.message;
|
|
126
|
+
const channelId = input.body.channel?.id;
|
|
127
|
+
const teamId = input.body.team?.id;
|
|
128
|
+
if (!message?.ts || !channelId || !teamId) {
|
|
129
|
+
await this.respondToMessageShortcut(input.body, { text: 'I could not read the source message for this handoff.' });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const receivedAt = slackTsToIsoOrNow(message.ts);
|
|
133
|
+
const now = nowIso();
|
|
134
|
+
const threadTs = message.thread_ts ?? message.ts;
|
|
135
|
+
const item = {
|
|
136
|
+
actor: {
|
|
137
|
+
...(message.user ? { userId: message.user } : {}),
|
|
138
|
+
},
|
|
139
|
+
channelId,
|
|
140
|
+
...(input.body.channel?.name ? { channelName: input.body.channel.name } : {}),
|
|
141
|
+
handling: { createdAt: now, queuedAt: now, status: 'queued', updatedAt: now },
|
|
142
|
+
id: `slack-shortcut-handoff:${teamId}:${channelId}:${message.ts}`,
|
|
143
|
+
kind: 'slack',
|
|
144
|
+
messageTs: message.ts,
|
|
145
|
+
receivedAt,
|
|
146
|
+
teamId,
|
|
147
|
+
text: handoffText(message.text ?? '', input.body.user?.id),
|
|
148
|
+
threadTs,
|
|
149
|
+
};
|
|
150
|
+
const result = await new WakeQueueService(input.agentId).enqueue(item);
|
|
151
|
+
await this.recordShortcutActivity(input.agentId, 'anima.shortcut.handoff', {
|
|
152
|
+
channelId,
|
|
153
|
+
duplicate: result.duplicate,
|
|
154
|
+
itemId: result.item.id,
|
|
155
|
+
messageTs: message.ts,
|
|
156
|
+
queued: result.queued,
|
|
157
|
+
threadTs,
|
|
158
|
+
userId: input.body.user?.id,
|
|
159
|
+
});
|
|
160
|
+
await this.respondToMessageShortcut(input.body, {
|
|
161
|
+
text: result.duplicate
|
|
162
|
+
? 'This message was already handed to the agent.'
|
|
163
|
+
: 'Handed to the agent. It will reply in this thread.',
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
async openModal(client, body, input) {
|
|
167
|
+
if (!body.trigger_id)
|
|
168
|
+
return;
|
|
169
|
+
await client.views.open({
|
|
170
|
+
trigger_id: body.trigger_id,
|
|
171
|
+
view: shortcutModal(input),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async respondToMessageShortcut(body, input) {
|
|
175
|
+
if (!body.response_url)
|
|
176
|
+
return;
|
|
177
|
+
await fetch(body.response_url, {
|
|
178
|
+
body: JSON.stringify({ response_type: 'ephemeral', text: input.text }),
|
|
179
|
+
headers: { 'content-type': 'application/json; charset=utf-8' },
|
|
180
|
+
method: 'POST',
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async recordShortcutActivity(agentId, type, payload) {
|
|
184
|
+
await this.activityRecorder.record(agentId, { type, payload });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
export const defaultSlackShortcutService = new SlackShortcutService();
|
|
188
|
+
export function userIdFromShortcutBody(body) {
|
|
189
|
+
if (!isRecord(body))
|
|
190
|
+
return undefined;
|
|
191
|
+
const user = body['user'];
|
|
192
|
+
return isRecord(user) && typeof user['id'] === 'string' ? user['id'] : undefined;
|
|
193
|
+
}
|
|
194
|
+
function slackTsToIsoOrNow(ts) {
|
|
195
|
+
const seconds = Number(ts.split('.')[0]);
|
|
196
|
+
if (!Number.isFinite(seconds))
|
|
197
|
+
return nowIso();
|
|
198
|
+
return new Date(seconds * 1000).toISOString();
|
|
199
|
+
}
|
|
200
|
+
function stopConfirmMetadata(view) {
|
|
201
|
+
if (!view.private_metadata)
|
|
202
|
+
return {};
|
|
203
|
+
try {
|
|
204
|
+
const parsed = JSON.parse(view.private_metadata);
|
|
205
|
+
if (!isRecord(parsed))
|
|
206
|
+
return {};
|
|
207
|
+
const itemId = typeof parsed['itemId'] === 'string' ? parsed['itemId'] : undefined;
|
|
208
|
+
return itemId ? { itemId } : {};
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return {};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function handoffText(text, handedByUserId) {
|
|
215
|
+
const body = text.trim() || '(message had no text)';
|
|
216
|
+
return [
|
|
217
|
+
handedByUserId
|
|
218
|
+
? `<@${handedByUserId}> used the Slack message shortcut to hand you this message as a task.`
|
|
219
|
+
: 'A teammate used the Slack message shortcut to hand you this message as a task.',
|
|
220
|
+
'Reply in this thread with your result.',
|
|
221
|
+
'',
|
|
222
|
+
body,
|
|
223
|
+
].join('\n');
|
|
224
|
+
}
|
|
225
|
+
function isRecord(value) {
|
|
226
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
227
|
+
}
|