@opencxh/domain 1.188.0 → 1.191.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,99 @@
1
+ import { LocaleBundle } from '../entities/analytics/dashboard';
2
+ import { NotificationText } from './notification';
3
+ /**
4
+ * Role group of an app that reports what currently needs someone's attention.
5
+ *
6
+ * A constant and not a literal at both ends: `Bridge.providers.list` answers an unknown group
7
+ * with an empty list, so a typo would read as "nothing needs attention".
8
+ */
9
+ export declare const ASSIST_SOURCE_PROVIDER_GROUP = "assist-source";
10
+ /**
11
+ * One thing that needs attention now, as the app that owns it sees it.
12
+ *
13
+ * Declared by the owner rather than derived centrally: only comms knows that an unanswered
14
+ * first reply is worse than an unread newsletter, and only `apps/work` knows that `closedAt`
15
+ * and not a status name decides whether an item is done. A hub that scored this itself would
16
+ * need every app's types.
17
+ */
18
+ export interface AssistNudge {
19
+ /** `<app>.<thing>` — the prefix is the owner, as with memory kinds and dossier keys. */
20
+ id: string;
21
+ /** Short label: "SLA", "Over tijd", "Straks". Bare i18n key; the hub stamps the namespace. */
22
+ tag: string;
23
+ /** Lucide icon name. */
24
+ icon?: string;
25
+ /** One line, in the owner's words. */
26
+ text: NotificationText;
27
+ /** The assignment that handles this — fills the launcher, or the agent's procedure. */
28
+ ask: NotificationText;
29
+ /** What it is about, as `<kind>:<ref>`. Also the scope the walkthrough's composer writes to. */
30
+ subjectKey?: string;
31
+ /** Higher sorts earlier. The source ranks its own; the hub only merges. */
32
+ priority?: number;
33
+ /**
34
+ * Where "open it" goes. `/…` follows the kernel router, `https://…` opens a tab — the same
35
+ * convention `AiToolResult.sources` uses.
36
+ */
37
+ url?: string;
38
+ /**
39
+ * Where "later" posts `{ remindAt }`, as an invoke action
40
+ * (`communication.interaction.<id>.remind`).
41
+ *
42
+ * The owner names the route rather than the board deriving one, because parking checks the
43
+ * resource's own ACL and only the owning app has it. A source without such a route omits this
44
+ * and simply gets no "later" button — better than a button that always fails.
45
+ */
46
+ snoozeAction?: string;
47
+ /**
48
+ * Federated resource that draws this nudge's body in the queue, as `"<app>:<Component>"`.
49
+ *
50
+ * Absent = the queue falls back to `text` plus a button to `url`, so a source that never
51
+ * adopts this keeps working. The component is handed `{ nudge, onHandled }`.
52
+ */
53
+ resource?: string;
54
+ /**
55
+ * Where "done" posts, as an invoke action. Same reasoning as `snoozeAction`: only the owning
56
+ * app knows what done means (comms closes, work leaves the status ladder) and only it holds
57
+ * the ACL. A source without such a route omits this and gets no "done" button.
58
+ */
59
+ resolveAction?: string;
60
+ }
61
+ /** A fixed starting point, offered even when nothing needs attention. */
62
+ export interface AssistStarter {
63
+ id: string;
64
+ label: NotificationText;
65
+ sub?: NotificationText;
66
+ icon?: string;
67
+ ask: NotificationText;
68
+ /**
69
+ * Whether this sets an agent to work or just asks something. The source knows — "handle the
70
+ * SLA conversations" is work, "summarise my open threads" is a question — and guessing it
71
+ * from the wording is the classify step the launcher deliberately does not have. Absent
72
+ * counts as `"task"`: a nudge is always something to be done.
73
+ */
74
+ mode?: "chat" | "task";
75
+ }
76
+ /**
77
+ * Bare payload of `GET /provider/assist/describe` — not wrapped in `ResponseFactory`, the way
78
+ * every fan-out in this repo reads a describe.
79
+ *
80
+ * User-scoped: the hub calls it with an acting identity, because a nudge is per person.
81
+ */
82
+ export interface AssistSourceDescribe {
83
+ /** The declaring app (== manifest name == `req.source.app`). */
84
+ source: string;
85
+ nudges: AssistNudge[];
86
+ starters: AssistStarter[];
87
+ /** Texts for every key above, in every language this app ships. `flattenLocales()` helps. */
88
+ locales?: LocaleBundle;
89
+ }
90
+ /** Every source's answer, merged. */
91
+ export interface AssistBoard {
92
+ nudges: AssistNudge[];
93
+ starters: AssistStarter[];
94
+ /** Which apps answered. */
95
+ sources: string[];
96
+ locales: LocaleBundle;
97
+ /** Apps that answered nothing. Silence is not an answer, so it is named. */
98
+ degradedApps: string[];
99
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The primitives both attention scorers share.
3
+ *
4
+ * Here rather than in one of them, so `apps/work` can score its items without importing
5
+ * interaction types and vice versa: each app owns one half and neither owns the other.
6
+ */
7
+ /** Score of something that must not surface at all. Filter with a single `> INELIGIBLE`. */
8
+ export declare const INELIGIBLE: number;
9
+ /** Priority weight, shared by interactions and work items. */
10
+ export declare const W_PRIORITY: Record<"urgent" | "high" | "normal" | "low", number>;
11
+ export interface Scored {
12
+ score: number;
13
+ /** Human-readable contributors, insertion order. Drives the tag on an assist nudge. */
14
+ reasons: string[];
15
+ }
16
+ /** One user's own "later" mark on a resource, as both scorers read it. */
17
+ export interface ParkMark {
18
+ remindAt: number;
19
+ parkedAt: number;
20
+ }
21
+ export interface AttentionCtx {
22
+ /** Whose attention. Drives the unseen + assigned-to-me boosts. */
23
+ userId: string;
24
+ /** Epoch-ms "now", injected so scoring stays pure and testable. */
25
+ now: number;
26
+ /** Personally parked: resourceId -> own mark. */
27
+ remindersById?: Record<string, ParkMark>;
28
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -13,9 +13,10 @@
13
13
  * later for seeding roles.
14
14
  */
15
15
  export declare const APP_PERMISSIONS: {
16
- readonly ai: readonly ["account.read", "account.write", "agent.read", "agent.write", "assignment.read", "budget.read", "budget.write", "connector.read", "connector.write", "context.read", "context.write", "conversation.read", "conversation.write", "lens.read", "lens.write", "message.read", "message.write", "playbook.read", "playbook.write", "profile.read", "profile.write", "run.read", "run.write", "settings.read", "settings.write", "tool.read", "transcript.write", "usage.read"];
16
+ readonly ai: readonly ["account.read", "account.write", "agent.read", "agent.write", "assignment.read", "assignment.write", "budget.read", "budget.write", "connector.read", "connector.write", "context.read", "context.write", "conversation.read", "conversation.write", "lens.read", "lens.write", "message.read", "message.write", "playbook.read", "playbook.write", "profile.read", "profile.write", "run.read", "run.write", "settings.read", "settings.write", "tool.read", "transcript.write", "usage.read"];
17
17
  readonly analytics: readonly ["report.read"];
18
18
  readonly "app-store": readonly ["app.publish", "app.read", "app.write", "setting.read", "setting.write"];
19
+ readonly assist: readonly ["board.read"];
19
20
  readonly automations: readonly ["sync.read", "sync.write", "webhook.read", "webhook.write"];
20
21
  readonly communication: readonly ["account.read", "account.write", "activity-type.read", "activity.read", "activity.write", "attachment.read", "attribute.read", "attribute.write", "calendar.read", "calendar.write", "channel.read", "channel.write", "custom-field.read", "custom-field.write", "folder.read", "folder.write", "inbox.read", "inbox.write", "interaction.read", "interaction.write", "reminder.read", "template.read", "template.write", "topic.read", "topic.write"];
21
22
  readonly context: readonly ["kind.read", "kind.write", "memory.read", "memory.write"];
@@ -28,6 +28,15 @@ export interface RouteDefinition {
28
28
  * still authenticated unless it opts out with `{ authenticated: false }`.
29
29
  */
30
30
  public?: boolean;
31
+ /**
32
+ * `"none"` drops the navigation column for this route: the content card gets the whole
33
+ * backdrop. For a surface you work *through* rather than navigate — the Assist queue — where
34
+ * a column listing where else you could be is the one thing it is trying to remove.
35
+ *
36
+ * The tools rail and the card itself stay; this is not the chromeless treatment `public` gets,
37
+ * which hands the page to somebody else's brand entirely.
38
+ */
39
+ chrome?: "none";
31
40
  }
32
41
  export interface NamespacedRouteDefinition extends RouteDefinition {
33
42
  appName: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencxh/domain",
3
- "version": "1.188.0",
3
+ "version": "1.191.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",