@xopcai/xopc 0.0.176 → 0.0.178
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DsFM1upC.js → activity-store-BzGX__8I.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DvdMLOga.js → agent-avatar-dicebear-BzxntcaZ.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DC9F12Kw.js +2 -0
- package/dist/gateway/static/root/assets/{api-BdPLCCBm.js → api-hi6f2Xtp.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DMLDOHul.js → app-management-settings-panel-fTY1F7ac.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DbI9foFR.js → appearance-settings-BZ-IxQfB.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-5bKr05Fa.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-Dfdxuwvb.js → archive-plugin-ZSLLG8wB.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-Dn3RlnYD.js → attachment-load-D4YktqIF.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-Bc0Y7A9u.js → automation-suggestion-card-B7mxFRtf.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Dg6dmt5g.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-0XtB-xC0.js → binary-plugins-BIkPxfxj.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-C4fXWbEE.js → block-editor-Q3v_YQom.js} +6 -6
- package/dist/gateway/static/root/assets/{browser-settings-page-lC86-drr.js → browser-settings-page-BHoo6Rpq.js} +4 -4
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-CZmzNymN.js → browser-workflow-inputs-M5lTEW1I.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CBYM9HqG.js → browser-workflows-page-B3T1KYk4.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BlsqN8Fu.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-BiJxmmhW.js → capability-presets-api-DE09c0VB.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJeT8_B4.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BKTUZDp-.js → channel-recipient-api-CFR5FBfS.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-C4VVjYEm.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-vdf8kB16.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-Pr4RIKjj.js → connector-logo-B1mD-3pM.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-DNcrDThX.js +2 -0
- package/dist/gateway/static/root/assets/desktop-pet-B1urphOZ.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CEQacUDF.js → desktop-pet-settings-DTL6J3EP.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-DWnxdZtc.js → directory-picker-path-field-BYQJ2XUS.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-D2e2w2Ho.js → dreaming-settings-BXcb8fwx.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-BLjTGbv3.js → extension-debug-page-O1Xu1r4Q.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-D2_UC6hy.js → extension-page-C2Jraq8l.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BsH6o_PX.js → extension-settings-page-DcXQDTpG.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-C-DkC6UJ.js → gateway-config-api-DmPIZrvg.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DEOGiimF.js → gateway-settings-DmObBx9b.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BlSLh1TF.js → gateway-startup-retry-BZEkOdPm.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-CSFcRE_N.js → goal-create-dialog-BRhmmBe9.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-C1k7_s_O.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-CcdS9qek.js → goals-config-api-Fwu1wjEP.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-BAcErdch.js → goals-page-hOu9uA3q.js} +2 -2
- package/dist/gateway/static/root/assets/{goals-settings-BY7crl0z.js → goals-settings-DY-JjvHz.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-DtTkS0gs.js → heartbeat-settings-BtKu2NWT.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-WGgkbwDZ.js → image-generation-api-05Gg8wsU.js} +1 -1
- package/dist/gateway/static/root/assets/{index-2UImfRDC.js → index-C0CGebQ1.js} +65 -65
- package/dist/gateway/static/root/assets/index-eqq25gvV.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C5lpWQ3f.js → keyboard-shortcuts-settings-CfmDR9Sc.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-EjsNT7nJ.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-b05wWvXG.js → local-apps-page-Df8BW1A_.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-sToMfHX_.js → locale-store-CTwSy7yW.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-cDE1jLJv.js → logs-page-Dswjlraa.js} +3 -3
- package/dist/gateway/static/root/assets/{markdown-split-0gPVst5y.js → markdown-split-B3FvKbaP.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Rxyq_KTm.js → media-plugins-DsjrvvB6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DP6tPKk-.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-DRhNDl_Q.js → notes-page-tuzIwy3c.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DSh3-hMY.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-cOEOQqHh.js → page-tabs-ke9s4nYi.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BopOLFvu.js → preview-open-alternatives-Cp1eI4S9.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DWVPmmOq.js → product-open-page-dXQCMAtH.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-D0QPRHR_.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-CI5Vz62F.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-S1jpzBS5.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BfZmKe1t.js → save-bar-controls-Bl30zjHc.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-Cpi4jCRV.js → schedule-field-DqhmXQKo.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-OXFkcZQe.js → schema-form-DkUCy6vf.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CTm66k7h.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CU52AUVD.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BwqkZCHJ.js → settings-form-section-C6ZbNpdy.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BbqH_S3Y.js → settings-loading-skeleton-Bk58_cr7.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BoxC-JSa.js → settings-page-k8iE_NdX.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-Ddu2iGaW.js → settings-page-layout-DgFSya2e.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-z1Lwv0js.js → setup-status-panel-B_KDlyZA.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CVazOFjy.js → share-preview-page-CV7nL_J9.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DK6XK95e.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-Bvv_u4ii.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-BGHvVbay.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page.utils-DgyB1tSo.js → skills-page.utils-kahBIHg0.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BoLSQL65.js → system-settings-panel-JV3-MG5F.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-CBNcGOfj.js → theme-store-DFLyzoLO.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-gochWrny.js → time-picker-XwpxdZFr.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-DvRnr7YB.js → typed-models-lib-60Aqo-UJ.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CA9BFVB7.js → use-channel-catalog-CnTkHDnw.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-DBCMk-Vn.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-v8tgylEZ.js → voice-api-key-field-CNa8qUgS.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-C1UIdsCl.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-DEAQepB8.js +1 -0
- package/dist/gateway/static/root/assets/work-page-D5qYmCTq.js +3 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CC3cJn5k.js → workflow-run-setup-panel-yV_x595t.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-yrK17ZZ5.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +3 -0
- package/dist/src/agent/embedded/run-for-session.js +18 -5
- package/dist/src/agent/embedded/run-turn.js +6 -3
- package/dist/src/agent/embedded/types.d.ts +2 -0
- package/dist/src/automations/service/automation-service.d.ts +3 -0
- package/dist/src/automations/service/automation-service.js +37 -7
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/connectors/composio-sessions.js +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +18 -2
- package/dist/src/gateway/hono/routes/home.js +19 -0
- package/dist/src/gateway/hono/routes/index.js +2 -2
- package/dist/src/gateway/hono/routes/local-apps.js +1 -1
- package/dist/src/gateway/hono/routes/proactive.d.ts +4 -0
- package/dist/src/gateway/hono/routes/proactive.js +157 -0
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/update.js +2 -2
- package/dist/src/gateway/index.js +1 -1
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/service.d.ts +10 -1
- package/dist/src/gateway/service.js +36 -36
- package/dist/src/infra/gateway-processes.js +1 -1
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/infra/update-runner.js +2 -2
- package/dist/src/infra/update-startup.js +1 -1
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/mobile/notification-service.d.ts +1 -0
- package/dist/src/mobile/notification-service.js +38 -18
- package/dist/src/mobile/notification-types.d.ts +2 -2
- package/dist/src/proactive/events/envelope.d.ts +2 -0
- package/dist/src/proactive/events/envelope.js +54 -0
- package/dist/src/proactive/events/publisher.d.ts +4 -0
- package/dist/src/proactive/events/repository.d.ts +9 -0
- package/dist/src/proactive/events/repository.js +62 -0
- package/dist/src/proactive/events/types.d.ts +44 -0
- package/dist/src/proactive/events/types.js +15 -0
- package/dist/src/proactive/execution/agent-executor.d.ts +16 -0
- package/dist/src/proactive/execution/agent-executor.js +104 -0
- package/dist/src/proactive/execution/context.d.ts +31 -0
- package/dist/src/proactive/execution/context.js +72 -0
- package/dist/src/proactive/execution/insight.d.ts +4 -0
- package/dist/src/proactive/execution/insight.js +74 -0
- package/dist/src/proactive/execution/repository.d.ts +23 -0
- package/dist/src/proactive/execution/repository.js +122 -0
- package/dist/src/proactive/execution/types.d.ts +54 -0
- package/dist/src/proactive/execution/types.js +1 -0
- package/dist/src/proactive/execution/worker.d.ts +15 -0
- package/dist/src/proactive/execution/worker.js +96 -0
- package/dist/src/proactive/inbox/repository.d.ts +24 -0
- package/dist/src/proactive/inbox/repository.js +117 -0
- package/dist/src/proactive/inbox/service.d.ts +17 -0
- package/dist/src/proactive/inbox/service.js +22 -0
- package/dist/src/proactive/inbox/types.d.ts +38 -0
- package/dist/src/proactive/inbox/types.js +1 -0
- package/dist/src/proactive/inbox/worker.d.ts +12 -0
- package/dist/src/proactive/inbox/worker.js +56 -0
- package/dist/src/proactive/index.d.ts +17 -0
- package/dist/src/proactive/index.js +11 -0
- package/dist/src/proactive/routing/batch-repository.d.ts +27 -0
- package/dist/src/proactive/routing/batch-repository.js +56 -0
- package/dist/src/proactive/routing/matcher.d.ts +5 -0
- package/dist/src/proactive/routing/matcher.js +56 -0
- package/dist/src/proactive/routing/types.d.ts +44 -0
- package/dist/src/proactive/routing/types.js +1 -0
- package/dist/src/proactive/scenarios/prompt-composer.d.ts +14 -0
- package/dist/src/proactive/scenarios/prompt-composer.js +24 -0
- package/dist/src/proactive/scenarios/repository.d.ts +23 -0
- package/dist/src/proactive/scenarios/repository.js +162 -0
- package/dist/src/proactive/scenarios/service.d.ts +15 -0
- package/dist/src/proactive/scenarios/service.js +26 -0
- package/dist/src/proactive/scenarios/types.d.ts +36 -0
- package/dist/src/proactive/scenarios/types.js +1 -0
- package/dist/src/proactive/service.d.ts +18 -0
- package/dist/src/proactive/service.js +61 -0
- package/dist/src/projects/project-service.d.ts +3 -1
- package/dist/src/projects/project-service.js +62 -32
- package/dist/src/providers/provider-auth-service.js +3 -0
- package/dist/src/providers/register-bundled-oauth-flows.d.ts +2 -0
- package/dist/src/providers/register-bundled-oauth-flows.js +16 -0
- package/dist/src/session/store.d.ts +2 -0
- package/dist/src/session/store.js +30 -0
- package/dist/src/storage/sqlite/migrations/068_proactive_event_spine.sql +71 -0
- package/dist/src/storage/sqlite/migrations/069_proactive_scenario_control.sql +69 -0
- package/dist/src/storage/sqlite/migrations/070_proactive_execution.sql +55 -0
- package/dist/src/storage/sqlite/migrations/071_proactive_inbox.sql +45 -0
- package/dist/src/storage/sqlite/migrations/072_proactive_judgments.sql +14 -0
- package/dist/src/storage/sqlite/migrations/073_enable_default_proactive_scenarios.sql +13 -0
- package/dist/src/storage/sqlite/migrations/074_deduplicate_blocked_work_routing.sql +5 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/work-discovery/thread-service.d.ts +1 -3
- package/dist/src/work-discovery/thread-service.js +13 -25
- package/dist/src/work-items/work-item-service.d.ts +3 -1
- package/dist/src/work-items/work-item-service.js +67 -36
- package/package.json +3 -11
- package/dist/gateway/static/root/assets/agents-BVjlpbeZ.js +0 -2
- package/dist/gateway/static/root/assets/api-Bop4IQRW.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-njqxLWYD.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-D-eweHZJ.js +0 -6
- package/dist/gateway/static/root/assets/capabilities-settings-panel-6tYNfHqJ.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Co-ymbd9.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-D46eVjaQ.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-BMRAO4zZ.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Dw1eYbRi.js +0 -2
- package/dist/gateway/static/root/assets/copy-VueTIC2x.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-B8cZuQUt.js +0 -1
- package/dist/gateway/static/root/assets/focus-detail-page-BBXUtxRB.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-VjRArfAJ.js +0 -4
- package/dist/gateway/static/root/assets/index-CS9sVShT.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-Cl0fcPL4.js +0 -2
- package/dist/gateway/static/root/assets/messages-CarlxqXV.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-BKNBk0Uf.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-BhjEXNQW.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-B80e69PH.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CwdVob6H.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BGt3Asj6.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BnTdM9Nn.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-C4lXuyQj.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DSuIDkeI.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-xgZczqVe.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-CEfIy4WZ.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-B-3MClaf.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-CEsFEdax.js +0 -1
- package/dist/gateway/static/root/assets/work-page-CT9AHnq6.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-C-1-_Zp1.js +0 -11
- package/dist/src/focuses/candidate-repository.d.ts +0 -15
- package/dist/src/focuses/candidate-repository.js +0 -91
- package/dist/src/focuses/index.d.ts +0 -7
- package/dist/src/focuses/index.js +0 -7
- package/dist/src/focuses/insight-repository.d.ts +0 -22
- package/dist/src/focuses/insight-repository.js +0 -77
- package/dist/src/focuses/prompts.d.ts +0 -2
- package/dist/src/focuses/prompts.js +0 -18
- package/dist/src/focuses/reconciler.d.ts +0 -5
- package/dist/src/focuses/reconciler.js +0 -26
- package/dist/src/focuses/repository.d.ts +0 -61
- package/dist/src/focuses/repository.js +0 -214
- package/dist/src/focuses/run-processor.d.ts +0 -18
- package/dist/src/focuses/run-processor.js +0 -162
- package/dist/src/focuses/service.d.ts +0 -42
- package/dist/src/focuses/service.js +0 -241
- package/dist/src/focuses/types.d.ts +0 -89
- package/dist/src/gateway/hono/routes/focuses.d.ts +0 -3
- package/dist/src/gateway/hono/routes/focuses.js +0 -319
- /package/dist/src/{focuses/types.js → proactive/events/publisher.js} +0 -0
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { createFocusActivity, getFocusMonitorByAutomationId, updateFocusMonitorRuntime } from "./repository.js";
|
|
4
|
-
import { createFocusInsight } from "./insight-repository.js";
|
|
5
|
-
//#region src/focuses/run-processor.ts
|
|
6
|
-
init_logger();
|
|
7
|
-
const log = createLogger("FocusRunProcessor");
|
|
8
|
-
function nonEmptyString(value) {
|
|
9
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
10
|
-
}
|
|
11
|
-
function parseFocusMonitorResult(summary) {
|
|
12
|
-
const start = summary.indexOf("{");
|
|
13
|
-
const end = summary.lastIndexOf("}");
|
|
14
|
-
if (start < 0 || end <= start) return null;
|
|
15
|
-
let value;
|
|
16
|
-
try {
|
|
17
|
-
value = JSON.parse(summary.slice(start, end + 1));
|
|
18
|
-
} catch {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
22
|
-
const result = value;
|
|
23
|
-
if (result.meaningful === false) return { meaningful: false };
|
|
24
|
-
if (result.meaningful !== true) return null;
|
|
25
|
-
const title = nonEmptyString(result.title);
|
|
26
|
-
const resultSummary = nonEmptyString(result.summary);
|
|
27
|
-
const whyItMatters = nonEmptyString(result.whyItMatters);
|
|
28
|
-
const nextAction = nonEmptyString(result.nextAction);
|
|
29
|
-
const evidence = Array.isArray(result.evidence) ? result.evidence.flatMap((item) => {
|
|
30
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) return [];
|
|
31
|
-
const record = item;
|
|
32
|
-
const label = nonEmptyString(record.label);
|
|
33
|
-
const source = nonEmptyString(record.source);
|
|
34
|
-
const publishedAtValue = nonEmptyString(record.publishedAt);
|
|
35
|
-
const publishedAt = publishedAtValue && Number.isFinite(Date.parse(publishedAtValue)) ? new Date(publishedAtValue).toISOString() : null;
|
|
36
|
-
return label ? [{
|
|
37
|
-
label,
|
|
38
|
-
...source ? { source } : {},
|
|
39
|
-
...publishedAt ? { publishedAt } : {}
|
|
40
|
-
}] : [];
|
|
41
|
-
}).slice(0, 8) : [];
|
|
42
|
-
if (!title || !resultSummary || !whyItMatters || !nextAction || evidence.length === 0) return null;
|
|
43
|
-
return {
|
|
44
|
-
meaningful: true,
|
|
45
|
-
title,
|
|
46
|
-
summary: resultSummary,
|
|
47
|
-
whyItMatters,
|
|
48
|
-
nextAction,
|
|
49
|
-
evidence
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function hasDatedExternalEvidence(evidence) {
|
|
53
|
-
return evidence.some((item) => {
|
|
54
|
-
if (!item.source || !item.publishedAt) return false;
|
|
55
|
-
try {
|
|
56
|
-
const url = new URL(item.source);
|
|
57
|
-
return (url.protocol === "https:" || url.protocol === "http:") && Number.isFinite(Date.parse(item.publishedAt));
|
|
58
|
-
} catch {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
function processFocusMonitorRun(run) {
|
|
64
|
-
const monitor = getFocusMonitorByAutomationId(run.automationId);
|
|
65
|
-
if (!monitor) return { handled: false };
|
|
66
|
-
if (monitor.lastRunId === run.id && monitor.lastRunAt != null) return { handled: true };
|
|
67
|
-
const endedAt = run.endedAtMs ?? Date.now();
|
|
68
|
-
if (run.status !== "succeeded" || !run.summary) {
|
|
69
|
-
const errorMessage = run.error || `Monitor run ${run.status}`;
|
|
70
|
-
updateFocusMonitorRuntime({
|
|
71
|
-
id: monitor.id,
|
|
72
|
-
runState: "failed",
|
|
73
|
-
lastRunId: run.id,
|
|
74
|
-
lastRunAt: endedAt,
|
|
75
|
-
error: errorMessage
|
|
76
|
-
});
|
|
77
|
-
createFocusActivity({
|
|
78
|
-
focusId: monitor.focusId,
|
|
79
|
-
monitorId: monitor.id,
|
|
80
|
-
type: "run_failed",
|
|
81
|
-
summary: errorMessage,
|
|
82
|
-
details: { runId: run.id },
|
|
83
|
-
nowMs: endedAt
|
|
84
|
-
});
|
|
85
|
-
return { handled: true };
|
|
86
|
-
}
|
|
87
|
-
const result = parseFocusMonitorResult(run.summary);
|
|
88
|
-
if (!result || result.meaningful && monitor.kind === "external_changes" && !hasDatedExternalEvidence(result.evidence)) {
|
|
89
|
-
updateFocusMonitorRuntime({
|
|
90
|
-
id: monitor.id,
|
|
91
|
-
runState: "failed",
|
|
92
|
-
lastRunId: run.id,
|
|
93
|
-
lastRunAt: endedAt,
|
|
94
|
-
error: "Monitor returned an invalid result"
|
|
95
|
-
});
|
|
96
|
-
createFocusActivity({
|
|
97
|
-
focusId: monitor.focusId,
|
|
98
|
-
monitorId: monitor.id,
|
|
99
|
-
type: "run_failed",
|
|
100
|
-
summary: "Monitor returned an invalid result",
|
|
101
|
-
details: { runId: run.id },
|
|
102
|
-
nowMs: endedAt
|
|
103
|
-
});
|
|
104
|
-
log.warn({
|
|
105
|
-
automationId: run.automationId,
|
|
106
|
-
runId: run.id,
|
|
107
|
-
monitorKind: monitor.kind
|
|
108
|
-
}, "Focus monitor returned an invalid result");
|
|
109
|
-
return { handled: true };
|
|
110
|
-
}
|
|
111
|
-
updateFocusMonitorRuntime({
|
|
112
|
-
id: monitor.id,
|
|
113
|
-
runState: "idle",
|
|
114
|
-
lastRunId: run.id,
|
|
115
|
-
lastRunAt: endedAt,
|
|
116
|
-
meaningful: result.meaningful,
|
|
117
|
-
error: null
|
|
118
|
-
});
|
|
119
|
-
if (!result.meaningful) {
|
|
120
|
-
createFocusActivity({
|
|
121
|
-
focusId: monitor.focusId,
|
|
122
|
-
monitorId: monitor.id,
|
|
123
|
-
type: "run_no_change",
|
|
124
|
-
summary: "No meaningful change found",
|
|
125
|
-
details: { runId: run.id },
|
|
126
|
-
nowMs: endedAt
|
|
127
|
-
});
|
|
128
|
-
return { handled: true };
|
|
129
|
-
}
|
|
130
|
-
const insight = createFocusInsight({
|
|
131
|
-
focusId: monitor.focusId,
|
|
132
|
-
monitorId: monitor.id,
|
|
133
|
-
runId: run.id,
|
|
134
|
-
kind: monitor.kind,
|
|
135
|
-
title: result.title,
|
|
136
|
-
summary: result.summary,
|
|
137
|
-
whyItMatters: result.whyItMatters,
|
|
138
|
-
nextAction: result.nextAction,
|
|
139
|
-
evidence: result.evidence,
|
|
140
|
-
nowMs: endedAt
|
|
141
|
-
});
|
|
142
|
-
if (insight) {
|
|
143
|
-
createFocusActivity({
|
|
144
|
-
focusId: monitor.focusId,
|
|
145
|
-
monitorId: monitor.id,
|
|
146
|
-
type: "insight_created",
|
|
147
|
-
summary: insight.title,
|
|
148
|
-
details: {
|
|
149
|
-
runId: run.id,
|
|
150
|
-
insightId: insight.id
|
|
151
|
-
},
|
|
152
|
-
nowMs: endedAt
|
|
153
|
-
});
|
|
154
|
-
return {
|
|
155
|
-
handled: true,
|
|
156
|
-
insight
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
return { handled: true };
|
|
160
|
-
}
|
|
161
|
-
//#endregion
|
|
162
|
-
export { parseFocusMonitorResult, processFocusMonitorRun };
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { Automation, AutomationRun } from '../automations/index.js';
|
|
2
|
-
import type { FocusCadence, FocusDetail, FocusMonitor, FocusMonitorKind, FocusStatus } from './types.js';
|
|
3
|
-
export interface FocusAutomationPort {
|
|
4
|
-
create(input: Parameters<import('../automations/index.js').AutomationService['create']>[0]): Promise<Automation>;
|
|
5
|
-
get(id: string): Promise<Automation | null>;
|
|
6
|
-
update(id: string, input: Parameters<import('../automations/index.js').AutomationService['update']>[1]): Promise<Automation>;
|
|
7
|
-
pause(id: string): Promise<Automation>;
|
|
8
|
-
resume(id: string): Promise<Automation>;
|
|
9
|
-
remove(id: string): Promise<boolean>;
|
|
10
|
-
runNow(id: string): Promise<AutomationRun>;
|
|
11
|
-
}
|
|
12
|
-
export declare class FocusService {
|
|
13
|
-
private readonly automations;
|
|
14
|
-
constructor(automations: FocusAutomationPort);
|
|
15
|
-
list(statuses?: FocusStatus[]): FocusDetail[];
|
|
16
|
-
get(id: string): FocusDetail | null;
|
|
17
|
-
create(input: {
|
|
18
|
-
title: string;
|
|
19
|
-
summary: string;
|
|
20
|
-
projectIds?: string[];
|
|
21
|
-
goalId?: string;
|
|
22
|
-
}): FocusDetail;
|
|
23
|
-
update(id: string, input: {
|
|
24
|
-
title?: string;
|
|
25
|
-
summary?: string;
|
|
26
|
-
projectIds?: string[];
|
|
27
|
-
}): FocusDetail | null;
|
|
28
|
-
setStatus(id: string, status: FocusStatus): Promise<FocusDetail | null>;
|
|
29
|
-
remove(id: string): Promise<boolean>;
|
|
30
|
-
configureMonitor(input: {
|
|
31
|
-
focusId: string;
|
|
32
|
-
kind: FocusMonitorKind;
|
|
33
|
-
enabled: boolean;
|
|
34
|
-
cadence?: FocusCadence;
|
|
35
|
-
}): Promise<{
|
|
36
|
-
monitor: FocusMonitor;
|
|
37
|
-
initialRunId?: string;
|
|
38
|
-
}>;
|
|
39
|
-
runMonitorNow(focusId: string, kind: FocusMonitorKind): Promise<AutomationRun>;
|
|
40
|
-
reconcile(): Promise<void>;
|
|
41
|
-
private detail;
|
|
42
|
-
}
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { createFocus, createFocusActivity, deleteFocus, getFocus, getFocusMonitor, listAllFocusMonitors, listFocusMonitors, listFocuses, updateFocus, updateFocusMonitorRuntime, upsertFocusMonitor } from "./repository.js";
|
|
4
|
-
import { buildFocusMonitorInstruction } from "./prompts.js";
|
|
5
|
-
//#region src/focuses/service.ts
|
|
6
|
-
init_logger();
|
|
7
|
-
const log = createLogger("FocusService");
|
|
8
|
-
const DEFAULT_CADENCE = {
|
|
9
|
-
kind: "interval",
|
|
10
|
-
everyMs: 864e5
|
|
11
|
-
};
|
|
12
|
-
var FocusService = class {
|
|
13
|
-
constructor(automations) {
|
|
14
|
-
this.automations = automations;
|
|
15
|
-
}
|
|
16
|
-
list(statuses) {
|
|
17
|
-
return listFocuses({ statuses }).map((focus) => this.detail(focus));
|
|
18
|
-
}
|
|
19
|
-
get(id) {
|
|
20
|
-
const focus = getFocus(id);
|
|
21
|
-
return focus ? this.detail(focus) : null;
|
|
22
|
-
}
|
|
23
|
-
create(input) {
|
|
24
|
-
if (!input.title.trim()) throw new Error("Focus title is required");
|
|
25
|
-
const focus = createFocus(input);
|
|
26
|
-
return this.detail(focus);
|
|
27
|
-
}
|
|
28
|
-
update(id, input) {
|
|
29
|
-
if (input.title !== void 0 && !input.title.trim()) throw new Error("Focus title is required");
|
|
30
|
-
if (!updateFocus({
|
|
31
|
-
id,
|
|
32
|
-
...input
|
|
33
|
-
})) return null;
|
|
34
|
-
createFocusActivity({
|
|
35
|
-
focusId: id,
|
|
36
|
-
type: "updated",
|
|
37
|
-
summary: "Focus updated"
|
|
38
|
-
});
|
|
39
|
-
return this.get(id);
|
|
40
|
-
}
|
|
41
|
-
async setStatus(id, status) {
|
|
42
|
-
const focus = getFocus(id);
|
|
43
|
-
if (!focus) return null;
|
|
44
|
-
if (focus.status === status) return this.detail(focus);
|
|
45
|
-
const monitors = listFocusMonitors(id);
|
|
46
|
-
if (status === "active") for (const monitor of monitors.filter((item) => item.enabled && item.automationId)) await this.automations.resume(monitor.automationId);
|
|
47
|
-
else if (status === "paused") for (const monitor of monitors.filter((item) => item.enabled && item.automationId)) await this.automations.pause(monitor.automationId);
|
|
48
|
-
else for (const monitor of monitors.filter((item) => item.automationId)) {
|
|
49
|
-
await this.automations.remove(monitor.automationId);
|
|
50
|
-
upsertFocusMonitor({
|
|
51
|
-
focusId: id,
|
|
52
|
-
kind: monitor.kind,
|
|
53
|
-
enabled: false,
|
|
54
|
-
cadence: monitor.cadence,
|
|
55
|
-
automationId: null
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
if (!updateFocus({
|
|
59
|
-
id,
|
|
60
|
-
status
|
|
61
|
-
})) return null;
|
|
62
|
-
const type = status === "active" ? "resumed" : status === "paused" ? "paused" : "completed";
|
|
63
|
-
createFocusActivity({
|
|
64
|
-
focusId: id,
|
|
65
|
-
type,
|
|
66
|
-
summary: `Focus ${type}`
|
|
67
|
-
});
|
|
68
|
-
return this.get(id);
|
|
69
|
-
}
|
|
70
|
-
async remove(id) {
|
|
71
|
-
if (!getFocus(id)) return false;
|
|
72
|
-
for (const monitor of listFocusMonitors(id).filter((item) => item.automationId)) await this.automations.remove(monitor.automationId);
|
|
73
|
-
return deleteFocus(id);
|
|
74
|
-
}
|
|
75
|
-
async configureMonitor(input) {
|
|
76
|
-
const focus = getFocus(input.focusId);
|
|
77
|
-
if (!focus) throw new Error("Focus not found");
|
|
78
|
-
if (focus.status !== "active") throw new Error("Only active focuses can enable monitoring");
|
|
79
|
-
const existing = getFocusMonitor(input.focusId, input.kind);
|
|
80
|
-
const cadence = input.cadence ?? existing?.cadence ?? DEFAULT_CADENCE;
|
|
81
|
-
if (cadence.kind !== "interval" || cadence.everyMs < 6e4) throw new Error("Invalid monitor cadence");
|
|
82
|
-
if (input.enabled && existing?.enabled && existing.cadence.everyMs === cadence.everyMs) return { monitor: existing };
|
|
83
|
-
if (!input.enabled) {
|
|
84
|
-
if (existing?.automationId) await this.automations.pause(existing.automationId);
|
|
85
|
-
const monitor = upsertFocusMonitor({
|
|
86
|
-
focusId: input.focusId,
|
|
87
|
-
kind: input.kind,
|
|
88
|
-
enabled: false,
|
|
89
|
-
cadence,
|
|
90
|
-
automationId: existing?.automationId
|
|
91
|
-
});
|
|
92
|
-
createFocusActivity({
|
|
93
|
-
focusId: input.focusId,
|
|
94
|
-
monitorId: monitor.id,
|
|
95
|
-
type: "monitor_disabled",
|
|
96
|
-
summary: `${input.kind} monitoring disabled`
|
|
97
|
-
});
|
|
98
|
-
return { monitor };
|
|
99
|
-
}
|
|
100
|
-
let monitor = upsertFocusMonitor({
|
|
101
|
-
focusId: input.focusId,
|
|
102
|
-
kind: input.kind,
|
|
103
|
-
enabled: true,
|
|
104
|
-
runState: "queued",
|
|
105
|
-
cadence,
|
|
106
|
-
automationId: existing?.automationId
|
|
107
|
-
});
|
|
108
|
-
try {
|
|
109
|
-
let automation;
|
|
110
|
-
if (existing?.automationId) if (existing.cadence.everyMs !== cadence.everyMs) automation = await this.automations.update(existing.automationId, { trigger: {
|
|
111
|
-
kind: "schedule",
|
|
112
|
-
schedule: {
|
|
113
|
-
kind: "interval",
|
|
114
|
-
everyMs: cadence.everyMs
|
|
115
|
-
}
|
|
116
|
-
} });
|
|
117
|
-
else automation = await this.automations.resume(existing.automationId);
|
|
118
|
-
else automation = await this.automations.create({
|
|
119
|
-
name: `Monitor: ${focus.title}`.slice(0, 200),
|
|
120
|
-
description: `${input.kind} monitor for a user-confirmed focus.`,
|
|
121
|
-
...focus.projectIds[0] ? { projectId: focus.projectIds[0] } : {},
|
|
122
|
-
trigger: {
|
|
123
|
-
kind: "schedule",
|
|
124
|
-
schedule: {
|
|
125
|
-
kind: "interval",
|
|
126
|
-
everyMs: cadence.everyMs
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
action: {
|
|
130
|
-
kind: "agent",
|
|
131
|
-
instruction: buildFocusMonitorInstruction(focus, input.kind),
|
|
132
|
-
timeoutSeconds: 300
|
|
133
|
-
},
|
|
134
|
-
safety: { mode: "suggest_only" },
|
|
135
|
-
afterRun: { kind: "none" },
|
|
136
|
-
reliability: {
|
|
137
|
-
timeoutSeconds: 300,
|
|
138
|
-
disableAfterConsecutiveFailures: 3
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
monitor = upsertFocusMonitor({
|
|
142
|
-
focusId: input.focusId,
|
|
143
|
-
kind: input.kind,
|
|
144
|
-
enabled: true,
|
|
145
|
-
runState: "queued",
|
|
146
|
-
cadence,
|
|
147
|
-
automationId: automation.id
|
|
148
|
-
});
|
|
149
|
-
createFocusActivity({
|
|
150
|
-
focusId: input.focusId,
|
|
151
|
-
monitorId: monitor.id,
|
|
152
|
-
type: "monitor_enabled",
|
|
153
|
-
summary: `${input.kind} monitoring enabled`
|
|
154
|
-
});
|
|
155
|
-
const run = await this.automations.runNow(automation.id);
|
|
156
|
-
monitor = updateFocusMonitorRuntime({
|
|
157
|
-
id: monitor.id,
|
|
158
|
-
runState: "running",
|
|
159
|
-
lastRunId: run.id,
|
|
160
|
-
nextRunAt: automation.state.nextRunAtMs ?? null
|
|
161
|
-
}) ?? monitor;
|
|
162
|
-
createFocusActivity({
|
|
163
|
-
focusId: input.focusId,
|
|
164
|
-
monitorId: monitor.id,
|
|
165
|
-
type: "run_started",
|
|
166
|
-
summary: "Initial monitor check started",
|
|
167
|
-
details: { runId: run.id }
|
|
168
|
-
});
|
|
169
|
-
return {
|
|
170
|
-
monitor,
|
|
171
|
-
initialRunId: run.id
|
|
172
|
-
};
|
|
173
|
-
} catch (err) {
|
|
174
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
175
|
-
updateFocusMonitorRuntime({
|
|
176
|
-
id: monitor.id,
|
|
177
|
-
runState: "failed",
|
|
178
|
-
error: errorMessage
|
|
179
|
-
});
|
|
180
|
-
log.error({
|
|
181
|
-
err,
|
|
182
|
-
focusId: input.focusId,
|
|
183
|
-
monitorKind: input.kind
|
|
184
|
-
}, `Focus monitor enable failed: ${errorMessage}`);
|
|
185
|
-
throw err;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
async runMonitorNow(focusId, kind) {
|
|
189
|
-
const monitor = getFocusMonitor(focusId, kind);
|
|
190
|
-
if (!monitor?.enabled || !monitor.automationId) throw new Error("Monitor is not enabled");
|
|
191
|
-
updateFocusMonitorRuntime({
|
|
192
|
-
id: monitor.id,
|
|
193
|
-
runState: "queued",
|
|
194
|
-
error: null
|
|
195
|
-
});
|
|
196
|
-
const run = await this.automations.runNow(monitor.automationId);
|
|
197
|
-
updateFocusMonitorRuntime({
|
|
198
|
-
id: monitor.id,
|
|
199
|
-
runState: "running",
|
|
200
|
-
lastRunId: run.id
|
|
201
|
-
});
|
|
202
|
-
createFocusActivity({
|
|
203
|
-
focusId,
|
|
204
|
-
monitorId: monitor.id,
|
|
205
|
-
type: "run_started",
|
|
206
|
-
summary: "Monitor check started",
|
|
207
|
-
details: { runId: run.id }
|
|
208
|
-
});
|
|
209
|
-
return run;
|
|
210
|
-
}
|
|
211
|
-
async reconcile() {
|
|
212
|
-
for (const monitor of listAllFocusMonitors()) {
|
|
213
|
-
const focus = getFocus(monitor.focusId);
|
|
214
|
-
if (!focus) continue;
|
|
215
|
-
const automation = monitor.automationId ? await this.automations.get(monitor.automationId) : null;
|
|
216
|
-
if (monitor.enabled && focus.status === "active" && !automation) try {
|
|
217
|
-
await this.configureMonitor({
|
|
218
|
-
focusId: focus.id,
|
|
219
|
-
kind: monitor.kind,
|
|
220
|
-
enabled: true,
|
|
221
|
-
cadence: monitor.cadence
|
|
222
|
-
});
|
|
223
|
-
} catch (err) {
|
|
224
|
-
log.warn({
|
|
225
|
-
err,
|
|
226
|
-
focusId: focus.id,
|
|
227
|
-
monitorId: monitor.id
|
|
228
|
-
}, "Focus monitor reconciliation failed");
|
|
229
|
-
}
|
|
230
|
-
else if ((!monitor.enabled || focus.status !== "active") && automation?.enabled) await this.automations.pause(automation.id);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
detail(focus) {
|
|
234
|
-
return {
|
|
235
|
-
...focus,
|
|
236
|
-
monitors: listFocusMonitors(focus.id)
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
//#endregion
|
|
241
|
-
export { FocusService };
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
export type FocusStatus = 'active' | 'paused' | 'completed';
|
|
2
|
-
export type FocusSource = 'user' | 'discovery';
|
|
3
|
-
export type FocusCandidateStatus = 'pending' | 'accepted' | 'dismissed';
|
|
4
|
-
export type FocusMonitorKind = 'progress' | 'external_changes';
|
|
5
|
-
export type FocusMonitorRunState = 'idle' | 'queued' | 'running' | 'failed';
|
|
6
|
-
export type FocusInsightStatus = 'unread' | 'dismissed' | 'approved';
|
|
7
|
-
export type FocusActivityType = 'created' | 'updated' | 'paused' | 'resumed' | 'completed' | 'monitor_enabled' | 'monitor_disabled' | 'run_started' | 'run_no_change' | 'run_failed' | 'insight_created' | 'insight_dismissed' | 'insight_approved';
|
|
8
|
-
export interface FocusEvidence {
|
|
9
|
-
label: string;
|
|
10
|
-
source?: string;
|
|
11
|
-
publishedAt?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface FocusCandidate {
|
|
14
|
-
id: string;
|
|
15
|
-
canonicalKey: string;
|
|
16
|
-
title: string;
|
|
17
|
-
summary: string;
|
|
18
|
-
confidence: number;
|
|
19
|
-
evidence: FocusEvidence[];
|
|
20
|
-
projectIds: string[];
|
|
21
|
-
status: FocusCandidateStatus;
|
|
22
|
-
discoveredAt: number;
|
|
23
|
-
updatedAt: number;
|
|
24
|
-
}
|
|
25
|
-
export interface Focus {
|
|
26
|
-
id: string;
|
|
27
|
-
title: string;
|
|
28
|
-
summary: string;
|
|
29
|
-
status: FocusStatus;
|
|
30
|
-
source: FocusSource;
|
|
31
|
-
sourceCandidateId?: string;
|
|
32
|
-
projectIds: string[];
|
|
33
|
-
goalId?: string;
|
|
34
|
-
createdAt: number;
|
|
35
|
-
updatedAt: number;
|
|
36
|
-
completedAt?: number;
|
|
37
|
-
lastActivityAt?: number;
|
|
38
|
-
}
|
|
39
|
-
export interface FocusCadence {
|
|
40
|
-
kind: 'interval';
|
|
41
|
-
everyMs: number;
|
|
42
|
-
}
|
|
43
|
-
export interface FocusMonitor {
|
|
44
|
-
id: string;
|
|
45
|
-
focusId: string;
|
|
46
|
-
kind: FocusMonitorKind;
|
|
47
|
-
enabled: boolean;
|
|
48
|
-
runState: FocusMonitorRunState;
|
|
49
|
-
cadence: FocusCadence;
|
|
50
|
-
automationId?: string;
|
|
51
|
-
lastRunId?: string;
|
|
52
|
-
lastRunAt?: number;
|
|
53
|
-
nextRunAt?: number;
|
|
54
|
-
lastMeaningfulResultAt?: number;
|
|
55
|
-
lastError?: string;
|
|
56
|
-
consecutiveFailures: number;
|
|
57
|
-
createdAt: number;
|
|
58
|
-
updatedAt: number;
|
|
59
|
-
}
|
|
60
|
-
export interface FocusActivity {
|
|
61
|
-
id: string;
|
|
62
|
-
focusId: string;
|
|
63
|
-
monitorId?: string;
|
|
64
|
-
type: FocusActivityType;
|
|
65
|
-
summary: string;
|
|
66
|
-
details: Record<string, unknown>;
|
|
67
|
-
createdAt: number;
|
|
68
|
-
}
|
|
69
|
-
export interface FocusInsight {
|
|
70
|
-
id: string;
|
|
71
|
-
focusId: string;
|
|
72
|
-
monitorId: string;
|
|
73
|
-
runId: string;
|
|
74
|
-
kind: FocusMonitorKind;
|
|
75
|
-
title: string;
|
|
76
|
-
summary: string;
|
|
77
|
-
whyItMatters: string;
|
|
78
|
-
nextAction: string;
|
|
79
|
-
evidence: FocusEvidence[];
|
|
80
|
-
status: FocusInsightStatus;
|
|
81
|
-
valueScore: number;
|
|
82
|
-
valueReasons: string[];
|
|
83
|
-
createdAt: number;
|
|
84
|
-
updatedAt: number;
|
|
85
|
-
}
|
|
86
|
-
export interface FocusDetail extends Focus {
|
|
87
|
-
monitors: FocusMonitor[];
|
|
88
|
-
latestInsight?: FocusInsight;
|
|
89
|
-
}
|