@burdenoff/microfe-subscriberbot 2026.1030.1 → 2026.1030.2
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/subscriberbot/SubscriberBotRoutes.d.ts.map +1 -1
- package/dist/subscriberbot/SubscriberBotRoutes.js +16 -8
- package/dist/subscriberbot/SubscriberBotRoutes.js.map +1 -1
- package/dist/subscriberbot/components/StatusBadge.d.ts.map +1 -1
- package/dist/subscriberbot/components/StatusBadge.js +6 -1
- package/dist/subscriberbot/components/StatusBadge.js.map +1 -1
- package/dist/subscriberbot/components/decisions/DecisionBanners.d.ts +11 -0
- package/dist/subscriberbot/components/decisions/DecisionBanners.d.ts.map +1 -0
- package/dist/subscriberbot/components/decisions/DecisionBanners.js +62 -0
- package/dist/subscriberbot/components/decisions/DecisionBanners.js.map +1 -0
- package/dist/subscriberbot/components/decisions/DecisionCard.d.ts +22 -0
- package/dist/subscriberbot/components/decisions/DecisionCard.d.ts.map +1 -0
- package/dist/subscriberbot/components/decisions/DecisionCard.js +316 -0
- package/dist/subscriberbot/components/decisions/DecisionCard.js.map +1 -0
- package/dist/subscriberbot/components/decisions/decisionModel.d.ts +51 -0
- package/dist/subscriberbot/components/decisions/decisionModel.d.ts.map +1 -0
- package/dist/subscriberbot/components/decisions/decisionModel.js +139 -0
- package/dist/subscriberbot/components/decisions/decisionModel.js.map +1 -0
- package/dist/subscriberbot/components/decisions/index.d.ts +9 -0
- package/dist/subscriberbot/components/decisions/index.d.ts.map +1 -0
- package/dist/subscriberbot/components/decisions/index.js +3 -0
- package/dist/subscriberbot/hooks/index.d.ts +1 -1
- package/dist/subscriberbot/hooks/index.d.ts.map +1 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts +16 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts.map +1 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js +99 -26
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts +7 -0
- package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js +280 -175
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/decisions/DecisionDetailPage.d.ts +12 -0
- package/dist/subscriberbot/pages/decisions/DecisionDetailPage.d.ts.map +1 -0
- package/dist/subscriberbot/pages/decisions/DecisionDetailPage.js +180 -0
- package/dist/subscriberbot/pages/decisions/DecisionDetailPage.js.map +1 -0
- package/dist/subscriberbot/pages/decisions/DecisionsPage.d.ts +13 -0
- package/dist/subscriberbot/pages/decisions/DecisionsPage.d.ts.map +1 -0
- package/dist/subscriberbot/pages/decisions/DecisionsPage.js +154 -0
- package/dist/subscriberbot/pages/decisions/DecisionsPage.js.map +1 -0
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +330 -314
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -1
- package/dist/subscriberbot/types/index.d.ts +66 -0
- package/dist/subscriberbot/types/index.d.ts.map +1 -1
- package/dist/subscriberbot/utils/pageContext.d.ts +1 -0
- package/dist/subscriberbot/utils/pageContext.d.ts.map +1 -1
- package/dist/subscriberbot/utils/pageContext.js +2 -0
- package/dist/subscriberbot/utils/pageContext.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageContext.js","names":[],"sources":["../../../src/subscriberbot/utils/pageContext.ts"],"sourcesContent":["/**\n * Page context for the Subscriber Bot assistant.\n *\n * `gatherPageContext()` runs before every assistant turn and its result is sent\n * to the assistant sandbox, which keeps only the keys in the agent's\n * `ALLOWED_CONTEXT_KEYS` (ai-assistant `src/context-loader.ts`). Nothing filters\n * on this side, so every key returned here crosses the wire: return only\n * allow-listed keys, and never a message body, a payment-instrument detail or\n * anything else that identifies a person. `userAgent` and `timestamp` are\n * deliberately absent for the same reason (AI readiness criteria 3.1 and 3.3).\n *\n * `entityType` + `entityId` are what let the agent act on \"this\" in one turn\n * (\"unsubscribe from this\", \"pause this\", \"cancel this\"), so every page that has\n * an addressable entity in its URL must resolve here.\n */\n\n/**\n * The keys the assistant agent forwards to the model. Kept in step with\n * `ALLOWED_CONTEXT_KEYS` in ai-assistant `src/context-loader.ts`; the unit test\n * asserts that `gatherPageContext()` never returns a key outside this list.\n */\nexport const ASSISTANT_ALLOWED_CONTEXT_KEYS = [\n 'currentUrl',\n 'currentPage',\n 'entityType',\n 'entityId',\n 'entityName',\n 'pageTitle',\n 'pageType',\n 'activeTab',\n 'activeTool',\n 'selectedText',\n 'workspaceId',\n 'workspaceName',\n 'projectId',\n 'projectName',\n 'platform',\n 'version',\n 'viewportSize',\n] as const;\n\nexport type AssistantContextKey = (typeof ASSISTANT_ALLOWED_CONTEXT_KEYS)[number];\n\n/** Entity types the Subscriber Bot routes resolve to. The agent guide documents each one. */\nexport const SUBSCRIBERBOT_ENTITY_TYPES = {\n relationship: 'SUBSCRIBERBOT_RELATIONSHIP',\n provider: 'SUBSCRIBERBOT_PROVIDER',\n agent: 'SUBSCRIBERBOT_AGENT',\n inboxMessage: 'SUBSCRIBERBOT_INBOX_MESSAGE',\n workflow: 'SUBSCRIBERBOT_WORKFLOW',\n} as const;\n\nexport type SubscriberBotEntityType =\n (typeof SUBSCRIBERBOT_ENTITY_TYPES)[keyof typeof SUBSCRIBERBOT_ENTITY_TYPES];\n\nexport interface ConversationContextShape {\n entityType?: SubscriberBotEntityType;\n entityId?: string;\n activeTab?: string;\n}\n\nexport type PageContext = Partial<Record<AssistantContextKey, string>> & {\n currentUrl: string;\n currentPage: string;\n platform: string;\n version: string;\n viewportSize: string;\n};\n\n/**\n * Route segment → entity type, for every route that carries one entity id.\n * Each entry mirrors a route in `SubscriberBotRoutes.tsx`; a pattern for a\n * route the app does not define would never match a real page.\n */\nconst ENTITY_ROUTES: ReadonlyArray<readonly [segment: string, type: SubscriberBotEntityType]> = [\n ['relationships', SUBSCRIBERBOT_ENTITY_TYPES.relationship],\n ['providers', SUBSCRIBERBOT_ENTITY_TYPES.provider],\n ['agents', SUBSCRIBERBOT_ENTITY_TYPES.agent],\n ['inbox', SUBSCRIBERBOT_ENTITY_TYPES.inboxMessage],\n ['workflows', SUBSCRIBERBOT_ENTITY_TYPES.workflow],\n];\n\n/** Static sub-routes that sit where an id would (\"relationships/new\" is a form, not an entity). */\nconst NON_ENTITY_SEGMENTS: ReadonlySet<string> = new Set(['new']);\n\n/** Ids are opaque, but they are path segments: no separators, no whitespace, bounded length. */\nconst ENTITY_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;\n\n/** Tab names are short identifiers; anything else is ignored rather than forwarded. */\nconst TAB_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;\n\nfunction decodeSegment(segment: string): string | undefined {\n try {\n return decodeURIComponent(segment);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve the entity the user is looking at from the router location.\n *\n * `pathname` is the full browser path; the Subscriber Bot routes live under\n * `/subscriberbot`. Anything that is not an entity route resolves to an empty\n * entity, so the agent asks rather than acting on a guessed id.\n */\nexport function resolveSubscriberBotConversationContext(\n pathname: string,\n search: string\n): ConversationContextShape {\n const segments = pathname.split('/').filter(Boolean);\n const root = segments.indexOf('subscriberbot');\n const rest = root === -1 ? [] : segments.slice(root + 1);\n\n const tabParam = new URLSearchParams(search).get('tab');\n const activeTab = tabParam && TAB_PATTERN.test(tabParam) ? tabParam : undefined;\n\n if (rest.length === 2) {\n const [section, rawId] = rest as [string, string];\n const route = ENTITY_ROUTES.find(([segment]) => segment === section);\n const id = decodeSegment(rawId);\n if (route && id && !NON_ENTITY_SEGMENTS.has(id) && ENTITY_ID_PATTERN.test(id)) {\n return { entityType: route[1], entityId: id, ...(activeTab ? { activeTab } : {}) };\n }\n }\n\n return activeTab ? { activeTab } : {};\n}\n\nexport function gatherPageContext(): PageContext {\n const { href, pathname, search } = window.location;\n const currentPage = pathname.split('/').filter(Boolean).slice(0, 3).join('/') || 'home';\n const entity = resolveSubscriberBotConversationContext(pathname, search);\n\n return {\n currentUrl: href,\n currentPage,\n ...(entity.entityType && entity.entityId\n ? { entityType: entity.entityType, entityId: entity.entityId }\n : {}),\n ...(entity.activeTab ? { activeTab: entity.activeTab } : {}),\n platform: 'subscriberbot',\n version: import.meta.env.VITE_APP_VERSION ?? '2026.615.1',\n viewportSize: `${window.innerWidth}x${window.innerHeight}`,\n };\n}\n"],"mappings":";AA4CA,IAAa,IAA6B;CACxC,cAAc;CACd,UAAU;CACV,OAAO;CACP,cAAc;CACd,UAAU;AACZ,GAwBM,IAA0F;CAC9F,CAAC,iBAAiB,EAA2B,YAAY;CACzD,CAAC,aAAa,EAA2B,QAAQ;CACjD,CAAC,UAAU,EAA2B,KAAK;CAC3C,CAAC,SAAS,EAA2B,YAAY;CACjD,CAAC,aAAa,EAA2B,QAAQ;AACnD,GAGM,IAA2C,IAAI,IAAI,CAAC,KAAK,CAAC,GAG1D,IAAoB,0BAGpB,IAAc;AAEpB,SAAS,EAAc,GAAqC;CAC1D,IAAI;EACF,OAAO,mBAAmB,CAAO;CACnC,QAAQ;EACN;CACF;AACF;AASA,SAAgB,EACd,GACA,GAC0B;CAC1B,IAAM,IAAW,EAAS,MAAM,GAAG,EAAE,OAAO,OAAO,GAC7C,IAAO,EAAS,QAAQ,eAAe,GACvC,IAAO,MAAS,KAAK,CAAC,IAAI,EAAS,MAAM,IAAO,CAAC,GAEjD,IAAW,IAAI,gBAAgB,CAAM,EAAE,IAAI,KAAK,GAChD,IAAY,KAAY,EAAY,KAAK,CAAQ,IAAI,IAAW,KAAA;CAEtE,IAAI,EAAK,WAAW,GAAG;EACrB,IAAM,CAAC,GAAS,KAAS,GACnB,IAAQ,EAAc,MAAM,CAAC,OAAa,MAAY,CAAO,GAC7D,IAAK,EAAc,CAAK;EAC9B,IAAI,KAAS,KAAM,CAAC,EAAoB,IAAI,CAAE,KAAK,EAAkB,KAAK,CAAE,GAC1E,OAAO;GAAE,YAAY,EAAM;GAAI,UAAU;GAAI,GAAI,IAAY,EAAE,aAAU,IAAI,CAAC;EAAG;CAErF;CAEA,OAAO,IAAY,EAAE,aAAU,IAAI,CAAC;AACtC;AAEA,SAAgB,IAAiC;CAC/C,IAAM,EAAE,SAAM,aAAU,cAAW,OAAO,UACpC,IAAc,EAAS,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,QAC3E,IAAS,EAAwC,GAAU,CAAM;CAEvE,OAAO;EACL,YAAY;EACZ;EACA,GAAI,EAAO,cAAc,EAAO,WAC5B;GAAE,YAAY,EAAO;GAAY,UAAU,EAAO;EAAS,IAC3D,CAAC;EACL,GAAI,EAAO,YAAY,EAAE,WAAW,EAAO,UAAU,IAAI,CAAC;EAC1D,UAAU;EACV,SAA6C;EAC7C,cAAc,GAAG,OAAO,WAAW,GAAG,OAAO;CAC/C;AACF"}
|
|
1
|
+
{"version":3,"file":"pageContext.js","names":[],"sources":["../../../src/subscriberbot/utils/pageContext.ts"],"sourcesContent":["/**\n * Page context for the Subscriber Bot assistant.\n *\n * `gatherPageContext()` runs before every assistant turn and its result is sent\n * to the assistant sandbox, which keeps only the keys in the agent's\n * `ALLOWED_CONTEXT_KEYS` (ai-assistant `src/context-loader.ts`). Nothing filters\n * on this side, so every key returned here crosses the wire: return only\n * allow-listed keys, and never a message body, a payment-instrument detail or\n * anything else that identifies a person. `userAgent` and `timestamp` are\n * deliberately absent for the same reason (AI readiness criteria 3.1 and 3.3).\n *\n * `entityType` + `entityId` are what let the agent act on \"this\" in one turn\n * (\"unsubscribe from this\", \"pause this\", \"cancel this\"), so every page that has\n * an addressable entity in its URL must resolve here.\n */\n\n/**\n * The keys the assistant agent forwards to the model. Kept in step with\n * `ALLOWED_CONTEXT_KEYS` in ai-assistant `src/context-loader.ts`; the unit test\n * asserts that `gatherPageContext()` never returns a key outside this list.\n */\nexport const ASSISTANT_ALLOWED_CONTEXT_KEYS = [\n 'currentUrl',\n 'currentPage',\n 'entityType',\n 'entityId',\n 'entityName',\n 'pageTitle',\n 'pageType',\n 'activeTab',\n 'activeTool',\n 'selectedText',\n 'workspaceId',\n 'workspaceName',\n 'projectId',\n 'projectName',\n 'platform',\n 'version',\n 'viewportSize',\n] as const;\n\nexport type AssistantContextKey = (typeof ASSISTANT_ALLOWED_CONTEXT_KEYS)[number];\n\n/** Entity types the Subscriber Bot routes resolve to. The agent guide documents each one. */\nexport const SUBSCRIBERBOT_ENTITY_TYPES = {\n relationship: 'SUBSCRIBERBOT_RELATIONSHIP',\n provider: 'SUBSCRIBERBOT_PROVIDER',\n agent: 'SUBSCRIBERBOT_AGENT',\n decision: 'SUBSCRIBERBOT_DECISION',\n inboxMessage: 'SUBSCRIBERBOT_INBOX_MESSAGE',\n workflow: 'SUBSCRIBERBOT_WORKFLOW',\n} as const;\n\nexport type SubscriberBotEntityType =\n (typeof SUBSCRIBERBOT_ENTITY_TYPES)[keyof typeof SUBSCRIBERBOT_ENTITY_TYPES];\n\nexport interface ConversationContextShape {\n entityType?: SubscriberBotEntityType;\n entityId?: string;\n activeTab?: string;\n}\n\nexport type PageContext = Partial<Record<AssistantContextKey, string>> & {\n currentUrl: string;\n currentPage: string;\n platform: string;\n version: string;\n viewportSize: string;\n};\n\n/**\n * Route segment → entity type, for every route that carries one entity id.\n * Each entry mirrors a route in `SubscriberBotRoutes.tsx`; a pattern for a\n * route the app does not define would never match a real page.\n */\nconst ENTITY_ROUTES: ReadonlyArray<readonly [segment: string, type: SubscriberBotEntityType]> = [\n ['relationships', SUBSCRIBERBOT_ENTITY_TYPES.relationship],\n ['providers', SUBSCRIBERBOT_ENTITY_TYPES.provider],\n ['agents', SUBSCRIBERBOT_ENTITY_TYPES.agent],\n ['decisions', SUBSCRIBERBOT_ENTITY_TYPES.decision],\n ['inbox', SUBSCRIBERBOT_ENTITY_TYPES.inboxMessage],\n ['workflows', SUBSCRIBERBOT_ENTITY_TYPES.workflow],\n];\n\n/** Static sub-routes that sit where an id would (\"relationships/new\" is a form, not an entity). */\nconst NON_ENTITY_SEGMENTS: ReadonlySet<string> = new Set(['new']);\n\n/** Ids are opaque, but they are path segments: no separators, no whitespace, bounded length. */\nconst ENTITY_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;\n\n/** Tab names are short identifiers; anything else is ignored rather than forwarded. */\nconst TAB_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;\n\nfunction decodeSegment(segment: string): string | undefined {\n try {\n return decodeURIComponent(segment);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve the entity the user is looking at from the router location.\n *\n * `pathname` is the full browser path; the Subscriber Bot routes live under\n * `/subscriberbot`. Anything that is not an entity route resolves to an empty\n * entity, so the agent asks rather than acting on a guessed id.\n */\nexport function resolveSubscriberBotConversationContext(\n pathname: string,\n search: string\n): ConversationContextShape {\n const segments = pathname.split('/').filter(Boolean);\n const root = segments.indexOf('subscriberbot');\n const rest = root === -1 ? [] : segments.slice(root + 1);\n\n const tabParam = new URLSearchParams(search).get('tab');\n const activeTab = tabParam && TAB_PATTERN.test(tabParam) ? tabParam : undefined;\n\n if (rest.length === 2) {\n const [section, rawId] = rest as [string, string];\n const route = ENTITY_ROUTES.find(([segment]) => segment === section);\n const id = decodeSegment(rawId);\n if (route && id && !NON_ENTITY_SEGMENTS.has(id) && ENTITY_ID_PATTERN.test(id)) {\n return { entityType: route[1], entityId: id, ...(activeTab ? { activeTab } : {}) };\n }\n }\n\n return activeTab ? { activeTab } : {};\n}\n\nexport function gatherPageContext(): PageContext {\n const { href, pathname, search } = window.location;\n const currentPage = pathname.split('/').filter(Boolean).slice(0, 3).join('/') || 'home';\n const entity = resolveSubscriberBotConversationContext(pathname, search);\n\n return {\n currentUrl: href,\n currentPage,\n ...(entity.entityType && entity.entityId\n ? { entityType: entity.entityType, entityId: entity.entityId }\n : {}),\n ...(entity.activeTab ? { activeTab: entity.activeTab } : {}),\n platform: 'subscriberbot',\n version: import.meta.env.VITE_APP_VERSION ?? '2026.615.1',\n viewportSize: `${window.innerWidth}x${window.innerHeight}`,\n };\n}\n"],"mappings":";AA4CA,IAAa,IAA6B;CACxC,cAAc;CACd,UAAU;CACV,OAAO;CACP,UAAU;CACV,cAAc;CACd,UAAU;AACZ,GAwBM,IAA0F;CAC9F,CAAC,iBAAiB,EAA2B,YAAY;CACzD,CAAC,aAAa,EAA2B,QAAQ;CACjD,CAAC,UAAU,EAA2B,KAAK;CAC3C,CAAC,aAAa,EAA2B,QAAQ;CACjD,CAAC,SAAS,EAA2B,YAAY;CACjD,CAAC,aAAa,EAA2B,QAAQ;AACnD,GAGM,IAA2C,IAAI,IAAI,CAAC,KAAK,CAAC,GAG1D,IAAoB,0BAGpB,IAAc;AAEpB,SAAS,EAAc,GAAqC;CAC1D,IAAI;EACF,OAAO,mBAAmB,CAAO;CACnC,QAAQ;EACN;CACF;AACF;AASA,SAAgB,EACd,GACA,GAC0B;CAC1B,IAAM,IAAW,EAAS,MAAM,GAAG,EAAE,OAAO,OAAO,GAC7C,IAAO,EAAS,QAAQ,eAAe,GACvC,IAAO,MAAS,KAAK,CAAC,IAAI,EAAS,MAAM,IAAO,CAAC,GAEjD,IAAW,IAAI,gBAAgB,CAAM,EAAE,IAAI,KAAK,GAChD,IAAY,KAAY,EAAY,KAAK,CAAQ,IAAI,IAAW,KAAA;CAEtE,IAAI,EAAK,WAAW,GAAG;EACrB,IAAM,CAAC,GAAS,KAAS,GACnB,IAAQ,EAAc,MAAM,CAAC,OAAa,MAAY,CAAO,GAC7D,IAAK,EAAc,CAAK;EAC9B,IAAI,KAAS,KAAM,CAAC,EAAoB,IAAI,CAAE,KAAK,EAAkB,KAAK,CAAE,GAC1E,OAAO;GAAE,YAAY,EAAM;GAAI,UAAU;GAAI,GAAI,IAAY,EAAE,aAAU,IAAI,CAAC;EAAG;CAErF;CAEA,OAAO,IAAY,EAAE,aAAU,IAAI,CAAC;AACtC;AAEA,SAAgB,IAAiC;CAC/C,IAAM,EAAE,SAAM,aAAU,cAAW,OAAO,UACpC,IAAc,EAAS,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,QAC3E,IAAS,EAAwC,GAAU,CAAM;CAEvE,OAAO;EACL,YAAY;EACZ;EACA,GAAI,EAAO,cAAc,EAAO,WAC5B;GAAE,YAAY,EAAO;GAAY,UAAU,EAAO;EAAS,IAC3D,CAAC;EACL,GAAI,EAAO,YAAY,EAAE,WAAW,EAAO,UAAU,IAAI,CAAC;EAC1D,UAAU;EACV,SAA6C;EAC7C,cAAc,GAAG,OAAO,WAAW,GAAG,OAAO;CAC/C;AACF"}
|