@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
|
@@ -2,6 +2,13 @@ export declare const DEFAULT_JSONL_ROTATE_BYTES: number;
|
|
|
2
2
|
export interface JsonlRotationOptions {
|
|
3
3
|
archiveDir?: string;
|
|
4
4
|
maxBytes?: number;
|
|
5
|
+
/**
|
|
6
|
+
* Cap on how many rotated archive segments to retain. After a rotation, the
|
|
7
|
+
* oldest archives beyond this count are deleted, bounding total disk use at
|
|
8
|
+
* roughly `(maxArchives + 1) * maxBytes`. Omitted/undefined ⇒ keep all
|
|
9
|
+
* archives (the historical behavior); `0` ⇒ keep none.
|
|
10
|
+
*/
|
|
11
|
+
maxArchives?: number;
|
|
5
12
|
}
|
|
6
13
|
export declare class JsonlAppendLog<T> {
|
|
7
14
|
readonly path: string;
|
|
@@ -33,6 +40,8 @@ export declare class JsonlAppendLog<T> {
|
|
|
33
40
|
private refreshCache;
|
|
34
41
|
private rotationEnabled;
|
|
35
42
|
private rotateIfNeeded;
|
|
43
|
+
private pruneArchives;
|
|
44
|
+
private ownArchivePaths;
|
|
36
45
|
private segmentPaths;
|
|
37
46
|
private archivePaths;
|
|
38
47
|
private nextArchivePath;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonl-log.d.ts","sourceRoot":"","sources":["../../../server/storage/jsonl-log.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"jsonl-log.d.ts","sourceRoot":"","sources":["../../../server/storage/jsonl-log.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc,CAAC,CAAC;IAEzB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADhB,IAAI,EAAE,MAAM,EACJ,QAAQ,GAAE,oBAAyB;IAGhD,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAShC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,OAAO,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAe5F,cAAc,CAClB,MAAM,EAAE,CAAC,EACT,YAAY,EAAE,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,OAAO,EAC7C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAY3B,eAAe,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAwBhG;;;;OAIG;IACG,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAIjC,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAiB5E,OAAO,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;YAgBf,gBAAgB;YAYhB,gBAAgB;YAOhB,gBAAgB;YAgDhB,eAAe;YAQf,eAAe;YAkBf,YAAY;IAa1B,OAAO,CAAC,eAAe;YAIT,cAAc;YAmBd,aAAa;YAmBb,eAAe;YAOf,YAAY;YAKZ,YAAY;YAaZ,eAAe;IAW7B,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { appendFile, mkdir, open, readFile, readdir, rename } from 'node:fs/promises';
|
|
1
|
+
import { appendFile, mkdir, open, readFile, readdir, rename, unlink } from 'node:fs/promises';
|
|
2
2
|
import { basename, dirname, join } from 'node:path';
|
|
3
3
|
import { cacheDelete, cacheHit, cacheSet, isMissingFile, statOrNull } from './json-file.js';
|
|
4
4
|
import { withFileLock } from './lock.js';
|
|
@@ -235,6 +235,41 @@ export class JsonlAppendLog {
|
|
|
235
235
|
await rename(this.path, archivePath);
|
|
236
236
|
cacheDelete(this.path);
|
|
237
237
|
cacheDelete(archivePath);
|
|
238
|
+
await this.pruneArchives();
|
|
239
|
+
}
|
|
240
|
+
// Enforce the optional retention cap: keep only the newest `maxArchives`
|
|
241
|
+
// segments, deleting the oldest. ownArchivePaths() returns ONLY this log's own
|
|
242
|
+
// segments (scoped by the archive-name pattern, so a shared archive dir never
|
|
243
|
+
// prunes another log's files), sorted ascending by the timestamp-prefixed
|
|
244
|
+
// name — oldest at the front. Best-effort: a file already gone is fine; other
|
|
245
|
+
// errors propagate like rotation itself.
|
|
246
|
+
async pruneArchives() {
|
|
247
|
+
const maxArchives = this.rotation.maxArchives;
|
|
248
|
+
if (!Number.isFinite(maxArchives) || Number(maxArchives) < 0)
|
|
249
|
+
return;
|
|
250
|
+
const archives = await this.ownArchivePaths();
|
|
251
|
+
const excess = archives.length - Number(maxArchives);
|
|
252
|
+
if (excess <= 0)
|
|
253
|
+
return;
|
|
254
|
+
for (const path of archives.slice(0, excess)) {
|
|
255
|
+
try {
|
|
256
|
+
await unlink(path);
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
if (!isMissingFile(error))
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
cacheDelete(path);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Archive segments produced by THIS log only. nextArchivePath() names them
|
|
266
|
+
// `<13+ digit stamp>-<base>-<3 digit seq>.jsonl`, so we match that exact shape
|
|
267
|
+
// for this log's base name — never another log sharing the same archive dir.
|
|
268
|
+
async ownArchivePaths() {
|
|
269
|
+
const base = basename(this.path).replace(/\.jsonl$/i, '');
|
|
270
|
+
const escaped = base.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
271
|
+
const own = new RegExp(`^\\d{13,}-${escaped}-\\d{3}\\.jsonl$`);
|
|
272
|
+
return (await this.archivePaths()).filter((path) => own.test(basename(path)));
|
|
238
273
|
}
|
|
239
274
|
async segmentPaths() {
|
|
240
275
|
const archives = await this.archivePaths();
|
|
@@ -10,6 +10,11 @@ export declare const ServerConfig: z.ZodObject<{
|
|
|
10
10
|
agents: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
11
11
|
kbs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
12
12
|
}, z.core.$strip>>;
|
|
13
|
+
track: z.ZodOptional<z.ZodEnum<{
|
|
14
|
+
stable: "stable";
|
|
15
|
+
canary: "canary";
|
|
16
|
+
dev: "dev";
|
|
17
|
+
}>>;
|
|
13
18
|
}, z.core.$strict>;
|
|
14
19
|
export type ServerConfig = z.infer<typeof ServerConfig>;
|
|
15
20
|
export declare class ServerConfigStore {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.store.d.ts","sourceRoot":"","sources":["../../../../server/storage/schema/server.store.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"server.store.d.ts","sourceRoot":"","sources":["../../../../server/storage/schema/server.store.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;kBAMd,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAIlB;IAEH,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC;IAI7B,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
|
|
@@ -4,12 +4,13 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { resolveAnimaHome } from '../../anima-home.js';
|
|
6
6
|
import { JsonStore } from '../json-store.js';
|
|
7
|
-
import { ReleaseTrack, SidebarOrder } from '../../../shared/server-settings.js';
|
|
7
|
+
import { ReleaseTrack, ServerTrack, SidebarOrder } from '../../../shared/server-settings.js';
|
|
8
8
|
export const ServerConfig = z.object({
|
|
9
9
|
dashboardHost: z.string().min(1).optional(),
|
|
10
10
|
dashboardPort: z.number().int().positive().max(65535).optional(),
|
|
11
11
|
releaseTrack: ReleaseTrack.optional(),
|
|
12
12
|
sidebarOrder: SidebarOrder.optional(),
|
|
13
|
+
track: ServerTrack.optional(),
|
|
13
14
|
}).strict();
|
|
14
15
|
export class ServerConfigStore {
|
|
15
16
|
file = new JsonStore({
|
|
@@ -10,6 +10,9 @@ export declare const WakeQueueFileSchema: z.ZodPreprocess<z.ZodRecord<z.ZodStrin
|
|
|
10
10
|
drainTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
11
11
|
failedAt: z.ZodOptional<z.ZodString>;
|
|
12
12
|
queuedAt: z.ZodOptional<z.ZodString>;
|
|
13
|
+
resumeReason: z.ZodOptional<z.ZodEnum<{
|
|
14
|
+
runtime_restart: "runtime_restart";
|
|
15
|
+
}>>;
|
|
13
16
|
settledAt: z.ZodOptional<z.ZodString>;
|
|
14
17
|
startedAt: z.ZodOptional<z.ZodString>;
|
|
15
18
|
status: z.ZodEnum<{
|
|
@@ -59,6 +62,9 @@ export declare const WakeQueueFileSchema: z.ZodPreprocess<z.ZodRecord<z.ZodStrin
|
|
|
59
62
|
drainTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
60
63
|
failedAt: z.ZodOptional<z.ZodString>;
|
|
61
64
|
queuedAt: z.ZodOptional<z.ZodString>;
|
|
65
|
+
resumeReason: z.ZodOptional<z.ZodEnum<{
|
|
66
|
+
runtime_restart: "runtime_restart";
|
|
67
|
+
}>>;
|
|
62
68
|
settledAt: z.ZodOptional<z.ZodString>;
|
|
63
69
|
startedAt: z.ZodOptional<z.ZodString>;
|
|
64
70
|
status: z.ZodEnum<{
|
|
@@ -83,6 +89,9 @@ export declare const WakeQueueFileSchema: z.ZodPreprocess<z.ZodRecord<z.ZodStrin
|
|
|
83
89
|
drainTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
84
90
|
failedAt: z.ZodOptional<z.ZodString>;
|
|
85
91
|
queuedAt: z.ZodOptional<z.ZodString>;
|
|
92
|
+
resumeReason: z.ZodOptional<z.ZodEnum<{
|
|
93
|
+
runtime_restart: "runtime_restart";
|
|
94
|
+
}>>;
|
|
86
95
|
settledAt: z.ZodOptional<z.ZodString>;
|
|
87
96
|
startedAt: z.ZodOptional<z.ZodString>;
|
|
88
97
|
status: z.ZodEnum<{
|
|
@@ -114,6 +123,9 @@ export declare const WakeQueueFileSchema: z.ZodPreprocess<z.ZodRecord<z.ZodStrin
|
|
|
114
123
|
drainTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
115
124
|
failedAt: z.ZodOptional<z.ZodString>;
|
|
116
125
|
queuedAt: z.ZodOptional<z.ZodString>;
|
|
126
|
+
resumeReason: z.ZodOptional<z.ZodEnum<{
|
|
127
|
+
runtime_restart: "runtime_restart";
|
|
128
|
+
}>>;
|
|
117
129
|
settledAt: z.ZodOptional<z.ZodString>;
|
|
118
130
|
startedAt: z.ZodOptional<z.ZodString>;
|
|
119
131
|
status: z.ZodEnum<{
|
|
@@ -173,7 +185,9 @@ export declare class WakeQueueStore {
|
|
|
173
185
|
timeoutMs: number;
|
|
174
186
|
}): Promise<InboxItem>;
|
|
175
187
|
clearDrainRequest(itemId: string): Promise<InboxItem>;
|
|
176
|
-
requeue(itemId: string
|
|
188
|
+
requeue(itemId: string, options?: {
|
|
189
|
+
resumeReason?: 'runtime_restart';
|
|
190
|
+
}): Promise<void>;
|
|
177
191
|
requestStop(itemId: string): Promise<InboxItem>;
|
|
178
192
|
markRunning(input: {
|
|
179
193
|
itemId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wake-queue.store.d.ts","sourceRoot":"","sources":["../../../../server/storage/schema/wake-queue.store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAsBtD,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"wake-queue.store.d.ts","sourceRoot":"","sources":["../../../../server/storage/schema/wake-queue.store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAsBtD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAAkF,CAAC;AAEnH,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,KAAG,SAAS,CAAC,aAAa,CAO3E,CAAC;AAEL,UAAU,wBAAwB;IAChC,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED,qBAAa,cAAc;IAEvB,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADb,OAAO,EAAE,MAAM,EACP,KAAK,GAAE,wBAAyD;IAG7E,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAKpD,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IASjF,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAQhD,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAM5B,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAKpC,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBtD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvC,WAAW,CAAC,KAAK,EAAE;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAgB5B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnC,YAAY,CAAC,KAAK,EAAE;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,SAAS,CAAC;IAchB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAcrD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,iBAAiB,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1F,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAa/C,WAAW,CAAC,KAAK,EAAE;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,SAAS,CAAC;IAehB,WAAW,CAAC,KAAK,EAAE;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;YAepB,wBAAwB;YAQxB,WAAW;CAK1B"}
|
|
@@ -150,8 +150,8 @@ export class WakeQueueStore {
|
|
|
150
150
|
},
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
|
-
async requeue(itemId) {
|
|
154
|
-
await this.replaceItemWithTimestamp(itemId, requeuedItem);
|
|
153
|
+
async requeue(itemId, options = {}) {
|
|
154
|
+
await this.replaceItemWithTimestamp(itemId, (item, now) => requeuedItem(item, now, options));
|
|
155
155
|
}
|
|
156
156
|
async requestStop(itemId) {
|
|
157
157
|
const now = nowIso();
|
|
@@ -215,17 +215,19 @@ function isSettledBefore(item, cutoffIso) {
|
|
|
215
215
|
const settledAt = item.handling.settledAt ?? item.handling.completedAt ?? item.handling.failedAt ?? item.handling.updatedAt;
|
|
216
216
|
return settledAt < cutoffIso;
|
|
217
217
|
}
|
|
218
|
-
function requeuedItem(item, now) {
|
|
218
|
+
function requeuedItem(item, now, options = {}) {
|
|
219
219
|
const handling = { ...item.handling };
|
|
220
220
|
delete handling.startedAt;
|
|
221
221
|
delete handling.workerId;
|
|
222
222
|
delete handling.settledAt;
|
|
223
223
|
delete handling.drainRequestedAt;
|
|
224
224
|
delete handling.drainTimeoutMs;
|
|
225
|
+
delete handling.resumeReason;
|
|
225
226
|
return {
|
|
226
227
|
...item,
|
|
227
228
|
handling: {
|
|
228
229
|
...handling,
|
|
230
|
+
...(options.resumeReason ? { resumeReason: options.resumeReason } : {}),
|
|
229
231
|
status: 'queued',
|
|
230
232
|
updatedAt: now,
|
|
231
233
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-config.test.d.ts","sourceRoot":"","sources":["../../../server/tests/agent-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import test from 'node:test';
|
|
5
|
+
import assert from 'node:assert/strict';
|
|
6
|
+
import { redactAgentConfig } from '../agents/agent-config-ops.js';
|
|
7
|
+
import { defaultAgentRegistryService } from '../agents/agent.service.js';
|
|
8
|
+
import { KbRegistryStore, KbStore } from '../storage/schema/kb.store.js';
|
|
9
|
+
import { withAnimaHome } from './anima-home.js';
|
|
10
|
+
const agentService = (agentId) => defaultAgentRegistryService.serviceFor(agentId);
|
|
11
|
+
const kbRegistry = () => new KbRegistryStore();
|
|
12
|
+
const kbStore = (id) => new KbStore(id);
|
|
13
|
+
test('agent config update writes editable fields and UI redacts secrets', async () => {
|
|
14
|
+
const configDir = await mkdtemp(join(tmpdir(), 'anima-profile-test-'));
|
|
15
|
+
try {
|
|
16
|
+
await writeConfig(configDir, {
|
|
17
|
+
agents: [
|
|
18
|
+
{
|
|
19
|
+
id: 'milo',
|
|
20
|
+
homePath: 'agents/milo',
|
|
21
|
+
profile: {
|
|
22
|
+
description: 'Profile description',
|
|
23
|
+
displayName: 'Profile Name',
|
|
24
|
+
},
|
|
25
|
+
provider: {
|
|
26
|
+
env: {
|
|
27
|
+
SECRET_NAME: 'secret-value',
|
|
28
|
+
},
|
|
29
|
+
kind: 'codex-cli',
|
|
30
|
+
model: 'old-model',
|
|
31
|
+
},
|
|
32
|
+
slack: {
|
|
33
|
+
botToken: 'xoxb-secret',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
await withAnimaHome(configDir, async () => {
|
|
39
|
+
const milo = agentService('milo');
|
|
40
|
+
const before = redactAgentConfig(await milo.getConfig());
|
|
41
|
+
assert.equal(before.profile?.displayName, 'Profile Name');
|
|
42
|
+
assert.equal(before.profile?.role, 'Profile description');
|
|
43
|
+
assert.deepEqual(Object.keys(before.provider?.env ?? {}), ['SECRET_NAME']);
|
|
44
|
+
assert.equal(before.provider?.env?.['SECRET_NAME'], '');
|
|
45
|
+
assert.equal(before.slack?.botToken, '');
|
|
46
|
+
assert.equal(JSON.stringify(before).includes('secret-value'), false);
|
|
47
|
+
assert.equal(JSON.stringify(before).includes('xoxb-secret'), false);
|
|
48
|
+
await milo.updateProvider({ model: 'gpt-5.4' });
|
|
49
|
+
const updated = await milo.updateProfile({ displayName: 'New Name', role: 'New role' });
|
|
50
|
+
assert.equal(updated.profile?.displayName, 'New Name');
|
|
51
|
+
assert.equal(updated.provider?.model, 'gpt-5.4');
|
|
52
|
+
const agent = await readRawAgentFile(configDir, 'milo');
|
|
53
|
+
assert.equal(agent.profile?.displayName, 'New Name');
|
|
54
|
+
assert.equal(agent.profile?.role, 'New role');
|
|
55
|
+
assert.equal('description' in (agent.profile ?? {}), false);
|
|
56
|
+
assert.equal(agent.provider?.model, 'gpt-5.4');
|
|
57
|
+
assert.equal('runtime' in agent, false);
|
|
58
|
+
assert.equal(agent.homePath, 'agents/milo');
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
await rm(configDir, { force: true, recursive: true });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
test('agent store lists and gets agent configs', async () => {
|
|
66
|
+
const configDir = await mkdtemp(join(tmpdir(), 'anima-profile-test-'));
|
|
67
|
+
try {
|
|
68
|
+
await writeConfig(configDir, {
|
|
69
|
+
agents: [
|
|
70
|
+
{
|
|
71
|
+
id: 'milo',
|
|
72
|
+
profile: {
|
|
73
|
+
displayName: 'Milo',
|
|
74
|
+
},
|
|
75
|
+
provider: {
|
|
76
|
+
kind: 'codex-cli',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
await withAnimaHome(configDir, async () => {
|
|
82
|
+
const agents = await defaultAgentRegistryService.listAgentConfigs();
|
|
83
|
+
assert.equal(agents[0]?.profile?.displayName, 'Milo');
|
|
84
|
+
assert.equal(agents[0]?.id, 'milo');
|
|
85
|
+
const agent = await agentService('milo').getConfig();
|
|
86
|
+
assert.equal(agent.profile?.displayName, 'Milo');
|
|
87
|
+
await assert.rejects(agentService('missing').getConfig(), /Agent not found in config: missing/);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
await rm(configDir, { force: true, recursive: true });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
test('creating default-home agents registers the team kb once', async () => {
|
|
95
|
+
const configDir = await mkdtemp(join(tmpdir(), 'anima-agent-kb-config-'));
|
|
96
|
+
const homeDir = await mkdtemp(join(tmpdir(), 'anima-agent-kb-home-'));
|
|
97
|
+
const customHome = await mkdtemp(join(tmpdir(), 'anima-agent-custom-home-'));
|
|
98
|
+
try {
|
|
99
|
+
await withProcessHome(homeDir, async () => {
|
|
100
|
+
await withAnimaHome(configDir, async () => {
|
|
101
|
+
const teamRoot = join(homeDir, 'anima-team');
|
|
102
|
+
await defaultAgentRegistryService.createAgent({
|
|
103
|
+
name: 'First Agent',
|
|
104
|
+
homePath: '~/anima-team/agents/first-agent',
|
|
105
|
+
role: 'First default-home agent.',
|
|
106
|
+
provider: { kind: 'claude-code', model: 'opus' },
|
|
107
|
+
});
|
|
108
|
+
assert.equal((await stat(join(teamRoot, 'agents', 'first-agent'))).isDirectory(), true);
|
|
109
|
+
assert.deepEqual(await kbRegistry().list(), [{ id: 'team', label: 'Team', path: teamRoot }]);
|
|
110
|
+
await defaultAgentRegistryService.createAgent({
|
|
111
|
+
name: 'Second Agent',
|
|
112
|
+
homePath: '~/anima-team/agents/second-agent',
|
|
113
|
+
role: 'Second default-home agent.',
|
|
114
|
+
provider: { kind: 'claude-code', model: 'opus' },
|
|
115
|
+
});
|
|
116
|
+
assert.deepEqual(await kbRegistry().list(), [{ id: 'team', label: 'Team', path: teamRoot }]);
|
|
117
|
+
await defaultAgentRegistryService.createAgent({
|
|
118
|
+
name: 'Custom Agent',
|
|
119
|
+
homePath: customHome,
|
|
120
|
+
role: 'Custom-home agent.',
|
|
121
|
+
provider: { kind: 'claude-code', model: 'opus' },
|
|
122
|
+
});
|
|
123
|
+
assert.deepEqual(await kbRegistry().list(), [{ id: 'team', label: 'Team', path: teamRoot }]);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
await rm(configDir, { force: true, recursive: true });
|
|
129
|
+
await rm(homeDir, { force: true, recursive: true });
|
|
130
|
+
await rm(customHome, { force: true, recursive: true });
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
test('team kb registration avoids id collisions without clobbering existing roots', async () => {
|
|
134
|
+
const configDir = await mkdtemp(join(tmpdir(), 'anima-agent-kb-collision-config-'));
|
|
135
|
+
const homeDir = await mkdtemp(join(tmpdir(), 'anima-agent-kb-collision-home-'));
|
|
136
|
+
const otherRoot = await mkdtemp(join(tmpdir(), 'anima-agent-kb-other-root-'));
|
|
137
|
+
try {
|
|
138
|
+
await withProcessHome(homeDir, async () => {
|
|
139
|
+
await withAnimaHome(configDir, async () => {
|
|
140
|
+
const teamRoot = join(homeDir, 'anima-team');
|
|
141
|
+
await kbStore('team').write({ id: 'team', label: 'Other Team', path: otherRoot });
|
|
142
|
+
await defaultAgentRegistryService.createAgent({
|
|
143
|
+
name: 'Default Agent',
|
|
144
|
+
homePath: '~/anima-team/agents/default-agent',
|
|
145
|
+
role: 'Default-home agent.',
|
|
146
|
+
provider: { kind: 'claude-code', model: 'opus' },
|
|
147
|
+
});
|
|
148
|
+
assert.deepEqual(await kbRegistry().list(), [
|
|
149
|
+
{ id: 'team', label: 'Other Team', path: otherRoot },
|
|
150
|
+
{ id: 'team-2', label: 'Team', path: teamRoot },
|
|
151
|
+
]);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
await rm(configDir, { force: true, recursive: true });
|
|
157
|
+
await rm(homeDir, { force: true, recursive: true });
|
|
158
|
+
await rm(otherRoot, { force: true, recursive: true });
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
test('legacy operator field is migrated to owner on read, persisted as owner on write', async () => {
|
|
162
|
+
const configDir = await mkdtemp(join(tmpdir(), 'anima-owner-backcompat-'));
|
|
163
|
+
try {
|
|
164
|
+
// Simulate a real legacy agent config as it exists on the 9 live agents —
|
|
165
|
+
// the `operator` field, not `owner`.
|
|
166
|
+
await mkdir(join(configDir, 'agents', 'aria'), { recursive: true });
|
|
167
|
+
await writeFile(join(configDir, 'agents', 'aria', 'config.json'), JSON.stringify({
|
|
168
|
+
id: 'aria',
|
|
169
|
+
homePath: 'agents/aria',
|
|
170
|
+
profile: { displayName: 'Aria', role: 'Test agent' },
|
|
171
|
+
provider: { kind: 'claude-code', model: 'sonnet' },
|
|
172
|
+
operator: {
|
|
173
|
+
slackUserId: 'UFAKEUSER1',
|
|
174
|
+
displayName: 'Test User',
|
|
175
|
+
handle: 'testuser',
|
|
176
|
+
avatarUrl: 'https://example.com/avatar.png',
|
|
177
|
+
onboardingPromptedAt: '2026-05-01T10:00:00.000Z',
|
|
178
|
+
},
|
|
179
|
+
}, null, 2), 'utf8');
|
|
180
|
+
await withAnimaHome(configDir, async () => {
|
|
181
|
+
const aria = agentService('aria');
|
|
182
|
+
// 1. Read: legacy `operator` must surface as `owner`, no `operator` key.
|
|
183
|
+
const config = await aria.getConfig();
|
|
184
|
+
assert.ok(config.owner, 'owner field must be present after migrate-on-read');
|
|
185
|
+
assert.equal(config.owner?.slackUserId, 'UFAKEUSER1');
|
|
186
|
+
assert.equal(config.owner?.displayName, 'Test User');
|
|
187
|
+
assert.equal(config.owner?.handle, 'testuser');
|
|
188
|
+
assert.equal(config.owner?.onboardingPromptedAt, '2026-05-01T10:00:00.000Z');
|
|
189
|
+
assert.equal('operator' in config, false, 'operator must not be present in resolved config');
|
|
190
|
+
// 2. Write: after any save the persisted file must have `owner`, not `operator`.
|
|
191
|
+
await aria.updateProfile({ displayName: 'Aria Updated' });
|
|
192
|
+
const raw = JSON.parse(await readFile(join(configDir, 'agents', 'aria', 'config.json'), 'utf8'));
|
|
193
|
+
assert.ok('owner' in raw, 'persisted config must have owner field');
|
|
194
|
+
assert.equal('operator' in raw, false, 'persisted config must not have legacy operator field');
|
|
195
|
+
const rawOwner = raw.owner;
|
|
196
|
+
assert.equal(rawOwner['slackUserId'], 'UFAKEUSER1');
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
finally {
|
|
200
|
+
await rm(configDir, { force: true, recursive: true });
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
async function writeConfig(configDir, config) {
|
|
204
|
+
await mkdir(configDir, { recursive: true });
|
|
205
|
+
await writeFile(join(configDir, 'config.json'), `${JSON.stringify(config.dashboardPort === undefined ? {} : { dashboardPort: config.dashboardPort }, null, 2)}\n`, 'utf8');
|
|
206
|
+
for (const agent of config.agents) {
|
|
207
|
+
const agentDir = join(configDir, 'agents', agent.id);
|
|
208
|
+
await mkdir(agentDir, { recursive: true });
|
|
209
|
+
await writeFile(join(agentDir, 'config.json'), `${JSON.stringify(agent, null, 2)}\n`, 'utf8');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async function readRawAgentFile(configDir, agentId) {
|
|
213
|
+
return JSON.parse(await readFile(join(configDir, 'agents', agentId, 'config.json'), 'utf8'));
|
|
214
|
+
}
|
|
215
|
+
async function withProcessHome(homeDir, body) {
|
|
216
|
+
const previous = process.env.HOME;
|
|
217
|
+
process.env.HOME = homeDir;
|
|
218
|
+
try {
|
|
219
|
+
return await body();
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
if (previous === undefined) {
|
|
223
|
+
delete process.env.HOME;
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
process.env.HOME = previous;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runtime.test.d.ts","sourceRoot":"","sources":["../../../server/tests/agent-runtime.test.ts"],"names":[],"mappings":""}
|