@agent-native/core 0.12.40 → 0.13.1

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.
Files changed (74) hide show
  1. package/dist/agent/run-manager.d.ts +5 -1
  2. package/dist/agent/run-manager.d.ts.map +1 -1
  3. package/dist/agent/run-manager.js +48 -2
  4. package/dist/agent/run-manager.js.map +1 -1
  5. package/dist/agent/run-store.d.ts +8 -0
  6. package/dist/agent/run-store.d.ts.map +1 -1
  7. package/dist/agent/run-store.js +36 -5
  8. package/dist/agent/run-store.js.map +1 -1
  9. package/dist/cli/templates-meta.js +10 -10
  10. package/dist/cli/templates-meta.js.map +1 -1
  11. package/dist/client/AssistantChat.d.ts.map +1 -1
  12. package/dist/client/AssistantChat.js +42 -3
  13. package/dist/client/AssistantChat.js.map +1 -1
  14. package/dist/client/ConnectBuilderCard.js +1 -1
  15. package/dist/client/ConnectBuilderCard.js.map +1 -1
  16. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  17. package/dist/client/MultiTabAssistantChat.js +27 -16
  18. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  19. package/dist/client/RunStuckBanner.d.ts +35 -0
  20. package/dist/client/RunStuckBanner.d.ts.map +1 -0
  21. package/dist/client/RunStuckBanner.js +66 -0
  22. package/dist/client/RunStuckBanner.js.map +1 -0
  23. package/dist/client/components/AgentPresenceChip.d.ts +1 -1
  24. package/dist/client/components/AgentPresenceChip.js +1 -1
  25. package/dist/client/components/AgentPresenceChip.js.map +1 -1
  26. package/dist/client/components/CodeRequiredDialog.js +5 -5
  27. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  28. package/dist/client/components/PresenceBar.js +1 -1
  29. package/dist/client/components/PresenceBar.js.map +1 -1
  30. package/dist/client/composer/ComposerPlusMenu.d.ts +3 -3
  31. package/dist/client/composer/ComposerPlusMenu.js +3 -3
  32. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  33. package/dist/client/composer/TiptapComposer.js +1 -1
  34. package/dist/client/composer/TiptapComposer.js.map +1 -1
  35. package/dist/client/composer/VoiceButton.js +3 -3
  36. package/dist/client/composer/VoiceButton.js.map +1 -1
  37. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  38. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  39. package/dist/client/index.d.ts +2 -0
  40. package/dist/client/index.d.ts.map +1 -1
  41. package/dist/client/index.js +2 -0
  42. package/dist/client/index.js.map +1 -1
  43. package/dist/client/onboarding/OnboardingPanel.js +1 -1
  44. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  45. package/dist/client/resources/ResourcesPanel.js +2 -2
  46. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  47. package/dist/client/settings/SecretsSection.js +3 -3
  48. package/dist/client/settings/SecretsSection.js.map +1 -1
  49. package/dist/client/use-chat-threads.d.ts +7 -0
  50. package/dist/client/use-chat-threads.d.ts.map +1 -1
  51. package/dist/client/use-chat-threads.js +91 -43
  52. package/dist/client/use-chat-threads.js.map +1 -1
  53. package/dist/client/use-run-stuck-detection.d.ts +47 -0
  54. package/dist/client/use-run-stuck-detection.d.ts.map +1 -0
  55. package/dist/client/use-run-stuck-detection.js +102 -0
  56. package/dist/client/use-run-stuck-detection.js.map +1 -0
  57. package/dist/collab/agent-identity.js +1 -1
  58. package/dist/collab/agent-identity.js.map +1 -1
  59. package/dist/collab/client.js +1 -1
  60. package/dist/collab/client.js.map +1 -1
  61. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  62. package/dist/server/agent-chat-plugin.js +2 -0
  63. package/dist/server/agent-chat-plugin.js.map +1 -1
  64. package/dist/server/google-auth-plugin.d.ts.map +1 -1
  65. package/dist/server/google-auth-plugin.js +28 -2
  66. package/dist/server/google-auth-plugin.js.map +1 -1
  67. package/dist/server/oauth-public-origin.d.ts +2 -0
  68. package/dist/server/oauth-public-origin.d.ts.map +1 -0
  69. package/dist/server/oauth-public-origin.js +28 -0
  70. package/dist/server/oauth-public-origin.js.map +1 -0
  71. package/dist/server/onboarding-html.d.ts.map +1 -1
  72. package/dist/server/onboarding-html.js +24 -0
  73. package/dist/server/onboarding-html.js.map +1 -1
  74. package/package.json +1 -1
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { IconAlertTriangle, IconLoader2 } from "@tabler/icons-react";
4
+ import { useRunStuckDetection, useAbortRun, } from "./use-run-stuck-detection.js";
5
+ import { trackEvent } from "./analytics.js";
6
+ import { cn } from "./utils.js";
7
+ export function RunStuckBanner({ threadId, apiUrl, stuckThresholdMs, onRetry, onStuckStateChange, className, }) {
8
+ const state = useRunStuckDetection({ threadId, stuckThresholdMs, apiUrl });
9
+ const abortRun = useAbortRun(apiUrl);
10
+ const [busy, setBusy] = useState("none");
11
+ const lastReportedRef = useRef({ isStuck: false, runId: null });
12
+ useEffect(() => {
13
+ const last = lastReportedRef.current;
14
+ if (last.isStuck === state.isStuck && last.runId === state.runId)
15
+ return;
16
+ lastReportedRef.current = { isStuck: state.isStuck, runId: state.runId };
17
+ onStuckStateChange?.(state);
18
+ if (state.isStuck && state.runId) {
19
+ trackEvent("agent_chat_stuck_detected", {
20
+ runId: state.runId,
21
+ threadId: threadId ?? null,
22
+ stuckSinceMs: state.stuckSinceMs ?? null,
23
+ stuckSinceSec: state.stuckSinceMs != null
24
+ ? Math.floor(state.stuckSinceMs / 1000)
25
+ : null,
26
+ runStatus: state.status,
27
+ });
28
+ }
29
+ }, [state, onStuckStateChange, threadId]);
30
+ // Reset the busy spinner once the underlying run has flipped away from
31
+ // running — no need to keep showing a stale "Retrying…" indicator.
32
+ useEffect(() => {
33
+ if (state.status !== "running") {
34
+ setBusy("none");
35
+ }
36
+ }, [state.status]);
37
+ if (!state.isStuck || !state.runId)
38
+ return null;
39
+ const handleCancel = async () => {
40
+ if (!state.runId || busy !== "none")
41
+ return;
42
+ setBusy("cancel");
43
+ trackEvent("agent_chat_stuck_cancel", {
44
+ runId: state.runId,
45
+ threadId: threadId ?? null,
46
+ stuckSinceMs: state.stuckSinceMs ?? null,
47
+ });
48
+ await abortRun(state.runId, "user_stuck_cancel");
49
+ };
50
+ const handleRetry = async () => {
51
+ if (!state.runId || busy !== "none")
52
+ return;
53
+ setBusy("retry");
54
+ trackEvent("agent_chat_stuck_retry", {
55
+ runId: state.runId,
56
+ threadId: threadId ?? null,
57
+ stuckSinceMs: state.stuckSinceMs ?? null,
58
+ });
59
+ const aborted = await abortRun(state.runId, "user_stuck_retry");
60
+ if (aborted)
61
+ onRetry?.(aborted);
62
+ };
63
+ const stuckSeconds = state.stuckSinceMs != null ? Math.floor(state.stuckSinceMs / 1000) : null;
64
+ return (_jsxs("div", { role: "status", "aria-live": "polite", className: cn("mx-3 mt-2 flex items-start gap-2.5 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2.5 text-xs text-foreground", className), children: [_jsx(IconAlertTriangle, { size: 16, className: "mt-0.5 shrink-0 text-amber-500", "aria-hidden": "true" }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [_jsxs("div", { className: "leading-snug", children: [_jsx("span", { className: "font-medium", children: "This chat looks stuck." }), " ", _jsxs("span", { className: "text-muted-foreground", children: ["No progress", stuckSeconds != null ? ` for ${stuckSeconds}s` : "", ". The agent may have hit a server timeout or lost its connection."] })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("button", { type: "button", onClick: handleRetry, disabled: busy !== "none", className: "inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60", children: [busy === "retry" ? (_jsx(IconLoader2, { size: 12, className: "animate-spin", "aria-hidden": "true" })) : null, "Retry"] }), _jsxs("button", { type: "button", onClick: handleCancel, disabled: busy !== "none", className: "inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[11px] font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-60", children: [busy === "cancel" ? (_jsx(IconLoader2, { size: 12, className: "animate-spin", "aria-hidden": "true" })) : null, "Cancel"] })] })] })] }));
65
+ }
66
+ //# sourceMappingURL=RunStuckBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunStuckBanner.js","sourceRoot":"","sources":["../../src/client/RunStuckBanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { IconAlertTriangle, IconLoader2 } from \"@tabler/icons-react\";\nimport {\n useRunStuckDetection,\n useAbortRun,\n type RunStuckState,\n} from \"./use-run-stuck-detection.js\";\nimport { trackEvent } from \"./analytics.js\";\nimport { cn } from \"./utils.js\";\n\n/**\n * Surface a user-visible affordance when a chat run hasn't emitted any\n * events for an unusually long time. The adapter's silent reconnect logic\n * keeps trying in the background; this banner is the fallback when those\n * attempts haven't restored progress and the user is staring at a frozen\n * spinner.\n */\nexport interface RunStuckBannerProps {\n /** The thread to monitor. Pass null/undefined to disable. */\n threadId: string | null | undefined;\n /** API base path. Default `/_agent-native/agent-chat`. */\n apiUrl?: string;\n /**\n * Threshold above which an in-flight run is considered stuck.\n * Defaults to 90s (after the adapter's 75s no-progress reconnect\n * has had a chance to recover).\n */\n stuckThresholdMs?: number;\n /**\n * Called when the user clicks Retry. Implementations should re-prompt\n * the agent (typically via `chatHandle.sendMessage(...)`) — the banner\n * itself only handles aborting the prior run.\n */\n onRetry?: (runId: string) => void;\n /**\n * Called whenever the stuck state transitions. Useful for surfacing\n * observability events (Sentry, PostHog) at the call site.\n */\n onStuckStateChange?: (state: RunStuckState) => void;\n /** Extra class on the outer container. */\n className?: string;\n}\n\nexport function RunStuckBanner({\n threadId,\n apiUrl,\n stuckThresholdMs,\n onRetry,\n onStuckStateChange,\n className,\n}: RunStuckBannerProps) {\n const state = useRunStuckDetection({ threadId, stuckThresholdMs, apiUrl });\n const abortRun = useAbortRun(apiUrl);\n const [busy, setBusy] = useState<\"none\" | \"cancel\" | \"retry\">(\"none\");\n\n const lastReportedRef = useRef<{\n isStuck: boolean;\n runId: string | null;\n }>({ isStuck: false, runId: null });\n useEffect(() => {\n const last = lastReportedRef.current;\n if (last.isStuck === state.isStuck && last.runId === state.runId) return;\n lastReportedRef.current = { isStuck: state.isStuck, runId: state.runId };\n onStuckStateChange?.(state);\n if (state.isStuck && state.runId) {\n trackEvent(\"agent_chat_stuck_detected\", {\n runId: state.runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n stuckSinceSec:\n state.stuckSinceMs != null\n ? Math.floor(state.stuckSinceMs / 1000)\n : null,\n runStatus: state.status,\n });\n }\n }, [state, onStuckStateChange, threadId]);\n\n // Reset the busy spinner once the underlying run has flipped away from\n // running — no need to keep showing a stale \"Retrying…\" indicator.\n useEffect(() => {\n if (state.status !== \"running\") {\n setBusy(\"none\");\n }\n }, [state.status]);\n\n if (!state.isStuck || !state.runId) return null;\n\n const handleCancel = async () => {\n if (!state.runId || busy !== \"none\") return;\n setBusy(\"cancel\");\n trackEvent(\"agent_chat_stuck_cancel\", {\n runId: state.runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n await abortRun(state.runId, \"user_stuck_cancel\");\n };\n\n const handleRetry = async () => {\n if (!state.runId || busy !== \"none\") return;\n setBusy(\"retry\");\n trackEvent(\"agent_chat_stuck_retry\", {\n runId: state.runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n const aborted = await abortRun(state.runId, \"user_stuck_retry\");\n if (aborted) onRetry?.(aborted);\n };\n\n const stuckSeconds =\n state.stuckSinceMs != null ? Math.floor(state.stuckSinceMs / 1000) : null;\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\n \"mx-3 mt-2 flex items-start gap-2.5 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2.5 text-xs text-foreground\",\n className,\n )}\n >\n <IconAlertTriangle\n size={16}\n className=\"mt-0.5 shrink-0 text-amber-500\"\n aria-hidden=\"true\"\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <div className=\"leading-snug\">\n <span className=\"font-medium\">This chat looks stuck.</span>{\" \"}\n <span className=\"text-muted-foreground\">\n No progress\n {stuckSeconds != null ? ` for ${stuckSeconds}s` : \"\"}. The agent may\n have hit a server timeout or lost its connection.\n </span>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleRetry}\n disabled={busy !== \"none\"}\n className=\"inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {busy === \"retry\" ? (\n <IconLoader2\n size={12}\n className=\"animate-spin\"\n aria-hidden=\"true\"\n />\n ) : null}\n Retry\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={busy !== \"none\"}\n className=\"inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[11px] font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {busy === \"cancel\" ? (\n <IconLoader2\n size={12}\n className=\"animate-spin\"\n aria-hidden=\"true\"\n />\n ) : null}\n Cancel\n </button>\n </div>\n </div>\n </div>\n );\n}\n"]}
@@ -3,7 +3,7 @@ export interface AgentPresenceChipProps {
3
3
  active: boolean;
4
4
  /** Label text. Default: "AI editing" */
5
5
  label?: string;
6
- /** Color. Default: "#a78bfa" */
6
+ /** Color. Default: "#00B5FF" */
7
7
  color?: string;
8
8
  /** Additional CSS classes. */
9
9
  className?: string;
@@ -14,7 +14,7 @@ function injectStyles() {
14
14
  document.head.appendChild(style);
15
15
  styleInjected = true;
16
16
  }
17
- export function AgentPresenceChip({ active, label = "AI editing", color = "#a78bfa", className, }) {
17
+ export function AgentPresenceChip({ active, label = "AI editing", color = "#00B5FF", className, }) {
18
18
  if (!active)
19
19
  return null;
20
20
  injectStyles();
@@ -1 +1 @@
1
- {"version":3,"file":"AgentPresenceChip.js","sourceRoot":"","sources":["../../../src/client/components/AgentPresenceChip.tsx"],"names":[],"mappings":";AAWA,MAAM,cAAc,GAAG;;;;;CAKtB,CAAC;AAEF,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,SAAS,YAAY;IACnB,IAAI,aAAa,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,WAAW,GAAG,cAAc,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAChC,MAAM,EACN,KAAK,GAAG,YAAY,EACpB,KAAK,GAAG,SAAS,EACjB,SAAS,GACc;IACvB,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,YAAY,EAAE,CAAC;IAEf,OAAO,CACL,gBACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACL,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,CAAC;YACN,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,OAAO;YAChB,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,GAAG,KAAK,IAAI;YAC7B,KAAK;YACL,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,QAAQ;SACrB,aAED,eACE,KAAK,EAAE;oBACL,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC;oBACT,YAAY,EAAE,KAAK;oBACnB,eAAe,EAAE,KAAK;oBACtB,SAAS,EAAE,0BAA0B;oBACrC,UAAU,EAAE,CAAC;iBACd,GACD,EACD,KAAK,IACD,CACR,CAAC;AACJ,CAAC","sourcesContent":["export interface AgentPresenceChipProps {\n /** Whether the agent is actively editing this element. */\n active: boolean;\n /** Label text. Default: \"AI editing\" */\n label?: string;\n /** Color. Default: \"#a78bfa\" */\n color?: string;\n /** Additional CSS classes. */\n className?: string;\n}\n\nconst pulseKeyframes = `\n@keyframes _anChipPulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n`;\n\nlet styleInjected = false;\n\nfunction injectStyles() {\n if (styleInjected || typeof document === \"undefined\") return;\n const style = document.createElement(\"style\");\n style.textContent = pulseKeyframes;\n document.head.appendChild(style);\n styleInjected = true;\n}\n\nexport function AgentPresenceChip({\n active,\n label = \"AI editing\",\n color = \"#a78bfa\",\n className,\n}: AgentPresenceChipProps) {\n if (!active) return null;\n\n injectStyles();\n\n return (\n <span\n className={className}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n height: 20,\n padding: \"0 8px\",\n borderRadius: 9999,\n backgroundColor: `${color}20`,\n color,\n fontSize: 11,\n fontWeight: 600,\n whiteSpace: \"nowrap\",\n }}\n >\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n backgroundColor: color,\n animation: \"_anChipPulse 2s infinite\",\n flexShrink: 0,\n }}\n />\n {label}\n </span>\n );\n}\n"]}
1
+ {"version":3,"file":"AgentPresenceChip.js","sourceRoot":"","sources":["../../../src/client/components/AgentPresenceChip.tsx"],"names":[],"mappings":";AAWA,MAAM,cAAc,GAAG;;;;;CAKtB,CAAC;AAEF,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,SAAS,YAAY;IACnB,IAAI,aAAa,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,WAAW,GAAG,cAAc,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAChC,MAAM,EACN,KAAK,GAAG,YAAY,EACpB,KAAK,GAAG,SAAS,EACjB,SAAS,GACc;IACvB,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,YAAY,EAAE,CAAC;IAEf,OAAO,CACL,gBACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACL,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,CAAC;YACN,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,OAAO;YAChB,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,GAAG,KAAK,IAAI;YAC7B,KAAK;YACL,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,QAAQ;SACrB,aAED,eACE,KAAK,EAAE;oBACL,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC;oBACT,YAAY,EAAE,KAAK;oBACnB,eAAe,EAAE,KAAK;oBACtB,SAAS,EAAE,0BAA0B;oBACrC,UAAU,EAAE,CAAC;iBACd,GACD,EACD,KAAK,IACD,CACR,CAAC;AACJ,CAAC","sourcesContent":["export interface AgentPresenceChipProps {\n /** Whether the agent is actively editing this element. */\n active: boolean;\n /** Label text. Default: \"AI editing\" */\n label?: string;\n /** Color. Default: \"#00B5FF\" */\n color?: string;\n /** Additional CSS classes. */\n className?: string;\n}\n\nconst pulseKeyframes = `\n@keyframes _anChipPulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n`;\n\nlet styleInjected = false;\n\nfunction injectStyles() {\n if (styleInjected || typeof document === \"undefined\") return;\n const style = document.createElement(\"style\");\n style.textContent = pulseKeyframes;\n document.head.appendChild(style);\n styleInjected = true;\n}\n\nexport function AgentPresenceChip({\n active,\n label = \"AI editing\",\n color = \"#00B5FF\",\n className,\n}: AgentPresenceChipProps) {\n if (!active) return null;\n\n injectStyles();\n\n return (\n <span\n className={className}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n height: 20,\n padding: \"0 8px\",\n borderRadius: 9999,\n backgroundColor: `${color}20`,\n color,\n fontSize: 11,\n fontWeight: 600,\n whiteSpace: \"nowrap\",\n }}\n >\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n backgroundColor: color,\n animation: \"_anChipPulse 2s infinite\",\n flexShrink: 0,\n }}\n />\n {label}\n </span>\n );\n}\n"]}
@@ -95,7 +95,7 @@ export function CodeRequiredDialog({ open, onClose, featureLabel, }) {
95
95
  ...s.optionCard,
96
96
  cursor: "default",
97
97
  opacity: 0.85,
98
- }, children: [_jsx("div", { style: s.optionIcon, children: _jsx(IconExternalLink, { size: 24 }) }), _jsxs("div", { style: s.optionText, children: [_jsx("span", { style: s.optionTitle, children: "Builder Cloud Agents unavailable" }), _jsx("span", { style: s.optionDesc, children: "You don't have access yet. Use the desktop app or your local clone for this code change." })] }), _jsx("span", { style: s.badge, children: "Unavailable" })] })) : (_jsxs("a", { href: builderHref, target: "_blank", rel: "noreferrer", style: { ...s.optionCard, ...s.optionLink }, onMouseEnter: (e) => Object.assign(e.currentTarget.style, s.optionCardHover), onMouseLeave: (e) => Object.assign(e.currentTarget.style, {
98
+ }, children: [_jsx("div", { style: s.optionIcon, children: _jsx(IconExternalLink, { size: 24 }) }), _jsxs("div", { style: s.optionText, children: [_jsx("span", { style: s.optionTitle, children: "Builder Cloud Agents coming soon" }), _jsx("span", { style: s.optionDesc, children: "You don't have access yet. Use the desktop app or your local clone for this code change." })] }), _jsx("span", { style: s.badge, children: "Coming soon" })] })) : (_jsxs("a", { href: builderHref, target: "_blank", rel: "noreferrer", style: { ...s.optionCard, ...s.optionLink }, onMouseEnter: (e) => Object.assign(e.currentTarget.style, s.optionCardHover), onMouseLeave: (e) => Object.assign(e.currentTarget.style, {
99
99
  borderColor: "#e5e7eb",
100
100
  }), children: [_jsx("div", { style: s.optionIcon, children: _jsx(IconExternalLink, { size: 24 }) }), _jsxs("div", { style: s.optionText, children: [_jsx("span", { style: s.optionTitle, children: "Connect Builder.io" }), _jsx("span", { style: s.optionDesc, children: "Connect Builder to enable cloud-based code changes from this app." })] }), !connectUrl && _jsx("span", { style: s.badge, children: "Setup required" })] }))] }), branchUrl && (_jsxs("div", { style: s.result, children: [_jsx("span", { style: { fontSize: 13, fontWeight: 600 }, children: "Branch created" }), _jsx("a", { href: branchUrl, target: "_blank", rel: "noopener noreferrer", style: s.resultLink, children: branchUrl })] })), error && (_jsx("p", { style: { color: "#ef4444", fontSize: 12, marginTop: 12 }, children: error })), _jsx("button", { style: s.closeButton, onClick: onClose, "aria-label": "Close", children: _jsx(IconX, { size: 16 }) })] }) }), document.body);
101
101
  }
@@ -180,7 +180,7 @@ const s = {
180
180
  },
181
181
  optionIcon: {
182
182
  flexShrink: 0,
183
- color: "#6366f1",
183
+ color: "#00B5FF",
184
184
  marginTop: "2px",
185
185
  },
186
186
  optionText: {
@@ -210,8 +210,8 @@ const s = {
210
210
  right: "10px",
211
211
  fontSize: "10px",
212
212
  fontWeight: 600,
213
- color: "#6366f1",
214
- background: "#eef2ff",
213
+ color: "#00B5FF",
214
+ background: "#e0f2fe",
215
215
  padding: "2px 8px",
216
216
  borderRadius: "99px",
217
217
  textTransform: "uppercase",
@@ -243,7 +243,7 @@ const s = {
243
243
  },
244
244
  resultLink: {
245
245
  fontSize: "12px",
246
- color: "#6366f1",
246
+ color: "#00B5FF",
247
247
  textDecoration: "none",
248
248
  wordBreak: "break-all",
249
249
  },
@@ -1 +1 @@
1
- {"version":3,"file":"CodeRequiredDialog.js","sourceRoot":"","sources":["../../../src/client/components/CodeRequiredDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useCallback, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n IconPackageExport,\n IconCode,\n IconExternalLink,\n IconX,\n IconLoader2,\n} from \"@tabler/icons-react\";\nimport { agentNativePath } from \"../api-path.js\";\n\nconst DESKTOP_DOWNLOAD_URL = \"https://www.agent-native.com/download\";\n\nexport interface CodeRequiredDialogProps {\n open: boolean;\n onClose: () => void;\n /** Label describing the feature that requires code changes */\n featureLabel?: string;\n}\n\nfunction useBuilderConnected() {\n const [connected, setConnected] = useState(false);\n const [cloudAgentsAvailable, setCloudAgentsAvailable] = useState(false);\n const [connectUrl, setConnectUrl] = useState<string | null>(null);\n\n useEffect(() => {\n fetch(agentNativePath(\"/_agent-native/builder/status\"))\n .then((r) => (r.ok ? r.json() : null))\n .then((data) => {\n if (data) {\n setConnected(!!data.configured);\n setCloudAgentsAvailable(!!data.builderEnabled);\n setConnectUrl(data.connectUrl || null);\n }\n })\n .catch(() => {});\n }, []);\n\n return { connected, cloudAgentsAvailable, connectUrl };\n}\n\n/**\n * Modal shown when a user tries to use a code-requiring feature where local\n * source access is unavailable. Offers two paths: Agent Native Desktop or the\n * Builder.io agent.\n * Uses inline styles (no Radix/Tailwind dependency).\n */\nexport function CodeRequiredDialog({\n open,\n onClose,\n featureLabel,\n}: CodeRequiredDialogProps) {\n const {\n connected: builderConnected,\n cloudAgentsAvailable,\n connectUrl,\n } = useBuilderConnected();\n const [submitting, setSubmitting] = useState(false);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const builderHref =\n connectUrl || agentNativePath(\"/_agent-native/builder/connect\");\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n },\n [onClose],\n );\n\n useEffect(() => {\n if (open) {\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }\n }, [open, handleKeyDown]);\n\n useEffect(() => {\n if (open) {\n setSubmitting(false);\n setBranchUrl(null);\n setError(null);\n }\n }, [open]);\n\n const handleBuilderAgent = async () => {\n if (!builderConnected) {\n // Open settings tab\n window.dispatchEvent(new Event(\"agent-panel:open-settings\"));\n onClose();\n return;\n }\n\n setSubmitting(true);\n setError(null);\n try {\n const res = await fetch(\n agentNativePath(\"/_agent-native/builder/agents-run\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userMessage:\n featureLabel || \"Make the requested code changes to this app\",\n }),\n },\n );\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error(body?.error || `Failed (${res.status})`);\n }\n const data = await res.json();\n setBranchUrl(data.url || null);\n } catch (err: any) {\n setError(err?.message || \"Failed to create branch\");\n } finally {\n setSubmitting(false);\n }\n };\n\n if (!open || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div style={s.backdrop} onClick={onClose}>\n <div\n style={s.dialog}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n {/* Header */}\n <div style={s.header}>\n <div style={s.iconWrap}>\n <IconPackageExport size={20} />\n </div>\n <div>\n <h2 style={s.title}>Code changes required</h2>\n <p style={s.subtitle}>\n {featureLabel\n ? `\"${featureLabel}\" creates or modifies source code, which needs Desktop or Builder from this surface.`\n : \"This action creates or modifies source code, which needs Desktop or Builder from this surface.\"}\n </p>\n </div>\n </div>\n\n {/* Options */}\n <div style={s.options}>\n <a\n href={DESKTOP_DOWNLOAD_URL}\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{ ...s.optionCard, ...s.optionLink }}\n onMouseEnter={(e) =>\n Object.assign(e.currentTarget.style, s.optionCardHover)\n }\n onMouseLeave={(e) =>\n Object.assign(e.currentTarget.style, { borderColor: \"#e5e7eb\" })\n }\n >\n <div style={s.optionIcon}>\n <IconCode size={24} />\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>Use Agent Native Desktop</span>\n <span style={s.optionDesc}>\n Open the project in the desktop app to enable source edits,\n Workspace files, and CLI access.\n </span>\n </div>\n </a>\n\n {builderConnected && cloudAgentsAvailable ? (\n <button\n style={{\n ...s.optionCard,\n ...(submitting\n ? { opacity: 0.7, pointerEvents: \"none\" as const }\n : {}),\n }}\n onMouseEnter={(e) =>\n Object.assign(e.currentTarget.style, s.optionCardHover)\n }\n onMouseLeave={(e) =>\n Object.assign(e.currentTarget.style, { borderColor: \"#e5e7eb\" })\n }\n onClick={handleBuilderAgent}\n >\n <div style={s.optionIcon}>\n {submitting ? (\n <IconLoader2\n size={24}\n style={{ animation: \"spin 1s linear infinite\" }}\n />\n ) : (\n <IconExternalLink size={24} />\n )}\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>Use Builder.io Agent</span>\n <span style={s.optionDesc}>\n Let our cloud agent make the changes for you. You'll get a\n link to preview and deploy.\n </span>\n </div>\n </button>\n ) : builderConnected ? (\n <div\n style={{\n ...s.optionCard,\n cursor: \"default\",\n opacity: 0.85,\n }}\n >\n <div style={s.optionIcon}>\n <IconExternalLink size={24} />\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>\n Builder Cloud Agents unavailable\n </span>\n <span style={s.optionDesc}>\n You don't have access yet. Use the desktop app or your local\n clone for this code change.\n </span>\n </div>\n <span style={s.badge}>Unavailable</span>\n </div>\n ) : (\n <a\n href={builderHref}\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{ ...s.optionCard, ...s.optionLink }}\n onMouseEnter={(e) =>\n Object.assign(e.currentTarget.style, s.optionCardHover)\n }\n onMouseLeave={(e) =>\n Object.assign(e.currentTarget.style, {\n borderColor: \"#e5e7eb\",\n })\n }\n >\n <div style={s.optionIcon}>\n <IconExternalLink size={24} />\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>Connect Builder.io</span>\n <span style={s.optionDesc}>\n Connect Builder to enable cloud-based code changes from this\n app.\n </span>\n </div>\n {!connectUrl && <span style={s.badge}>Setup required</span>}\n </a>\n )}\n </div>\n\n {/* Branch result */}\n {branchUrl && (\n <div style={s.result}>\n <span style={{ fontSize: 13, fontWeight: 600 }}>\n Branch created\n </span>\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={s.resultLink}\n >\n {branchUrl}\n </a>\n </div>\n )}\n\n {error && (\n <p style={{ color: \"#ef4444\", fontSize: 12, marginTop: 12 }}>\n {error}\n </p>\n )}\n\n {/* Close */}\n <button style={s.closeButton} onClick={onClose} aria-label=\"Close\">\n <IconX size={16} />\n </button>\n </div>\n </div>,\n document.body,\n );\n}\n\nconst s: Record<string, React.CSSProperties> = {\n backdrop: {\n position: \"fixed\",\n inset: 0,\n background: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 99999,\n padding: \"16px\",\n },\n dialog: {\n position: \"relative\",\n background: \"#fff\",\n borderRadius: \"12px\",\n maxWidth: \"460px\",\n width: \"100%\",\n padding: \"24px\",\n boxShadow:\n \"0 20px 25px -5px rgba(0,0,0,.1), 0 8px 10px -6px rgba(0,0,0,.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n color: \"#111827\",\n },\n header: {\n display: \"flex\",\n gap: \"14px\",\n alignItems: \"flex-start\",\n marginBottom: \"20px\",\n },\n iconWrap: {\n flexShrink: 0,\n width: \"40px\",\n height: \"40px\",\n borderRadius: \"10px\",\n background: \"#f3f4f6\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#6b7280\",\n },\n title: {\n margin: 0,\n fontSize: \"16px\",\n fontWeight: 600,\n lineHeight: \"1.4\",\n },\n subtitle: {\n margin: \"4px 0 0\",\n fontSize: \"13px\",\n color: \"#6b7280\",\n lineHeight: \"1.5\",\n },\n options: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"10px\",\n },\n optionCard: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"14px\",\n padding: \"14px\",\n border: \"1px solid #e5e7eb\",\n borderRadius: \"10px\",\n background: \"transparent\",\n cursor: \"pointer\",\n textAlign: \"left\",\n width: \"100%\",\n fontSize: \"inherit\",\n fontFamily: \"inherit\",\n color: \"inherit\",\n },\n optionCardHover: {\n borderColor: \"#a5b4fc\",\n },\n optionLink: {\n textDecoration: \"none\",\n boxSizing: \"border-box\",\n },\n optionIcon: {\n flexShrink: 0,\n color: \"#6366f1\",\n marginTop: \"2px\",\n },\n optionText: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n },\n optionTitle: {\n fontSize: \"14px\",\n fontWeight: 600,\n },\n optionDesc: {\n fontSize: \"12px\",\n color: \"#6b7280\",\n lineHeight: \"1.5\",\n },\n code: {\n background: \"#f3f4f6\",\n padding: \"1px 5px\",\n borderRadius: \"4px\",\n fontSize: \"11px\",\n fontFamily: \"monospace\",\n },\n badge: {\n position: \"absolute\",\n top: \"10px\",\n right: \"10px\",\n fontSize: \"10px\",\n fontWeight: 600,\n color: \"#6366f1\",\n background: \"#eef2ff\",\n padding: \"2px 8px\",\n borderRadius: \"99px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.5px\",\n },\n closeButton: {\n position: \"absolute\",\n top: \"12px\",\n right: \"12px\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"6px\",\n borderRadius: \"6px\",\n color: \"#9ca3af\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n result: {\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"8px\",\n border: \"1px solid #22c55e40\",\n background: \"#f0fdf4\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"4px\",\n },\n resultLink: {\n fontSize: \"12px\",\n color: \"#6366f1\",\n textDecoration: \"none\",\n wordBreak: \"break-all\",\n },\n};\n"]}
1
+ {"version":3,"file":"CodeRequiredDialog.js","sourceRoot":"","sources":["../../../src/client/components/CodeRequiredDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useCallback, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n IconPackageExport,\n IconCode,\n IconExternalLink,\n IconX,\n IconLoader2,\n} from \"@tabler/icons-react\";\nimport { agentNativePath } from \"../api-path.js\";\n\nconst DESKTOP_DOWNLOAD_URL = \"https://www.agent-native.com/download\";\n\nexport interface CodeRequiredDialogProps {\n open: boolean;\n onClose: () => void;\n /** Label describing the feature that requires code changes */\n featureLabel?: string;\n}\n\nfunction useBuilderConnected() {\n const [connected, setConnected] = useState(false);\n const [cloudAgentsAvailable, setCloudAgentsAvailable] = useState(false);\n const [connectUrl, setConnectUrl] = useState<string | null>(null);\n\n useEffect(() => {\n fetch(agentNativePath(\"/_agent-native/builder/status\"))\n .then((r) => (r.ok ? r.json() : null))\n .then((data) => {\n if (data) {\n setConnected(!!data.configured);\n setCloudAgentsAvailable(!!data.builderEnabled);\n setConnectUrl(data.connectUrl || null);\n }\n })\n .catch(() => {});\n }, []);\n\n return { connected, cloudAgentsAvailable, connectUrl };\n}\n\n/**\n * Modal shown when a user tries to use a code-requiring feature where local\n * source access is unavailable. Offers two paths: Agent Native Desktop or the\n * Builder.io agent.\n * Uses inline styles (no Radix/Tailwind dependency).\n */\nexport function CodeRequiredDialog({\n open,\n onClose,\n featureLabel,\n}: CodeRequiredDialogProps) {\n const {\n connected: builderConnected,\n cloudAgentsAvailable,\n connectUrl,\n } = useBuilderConnected();\n const [submitting, setSubmitting] = useState(false);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const builderHref =\n connectUrl || agentNativePath(\"/_agent-native/builder/connect\");\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n },\n [onClose],\n );\n\n useEffect(() => {\n if (open) {\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }\n }, [open, handleKeyDown]);\n\n useEffect(() => {\n if (open) {\n setSubmitting(false);\n setBranchUrl(null);\n setError(null);\n }\n }, [open]);\n\n const handleBuilderAgent = async () => {\n if (!builderConnected) {\n // Open settings tab\n window.dispatchEvent(new Event(\"agent-panel:open-settings\"));\n onClose();\n return;\n }\n\n setSubmitting(true);\n setError(null);\n try {\n const res = await fetch(\n agentNativePath(\"/_agent-native/builder/agents-run\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userMessage:\n featureLabel || \"Make the requested code changes to this app\",\n }),\n },\n );\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error(body?.error || `Failed (${res.status})`);\n }\n const data = await res.json();\n setBranchUrl(data.url || null);\n } catch (err: any) {\n setError(err?.message || \"Failed to create branch\");\n } finally {\n setSubmitting(false);\n }\n };\n\n if (!open || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div style={s.backdrop} onClick={onClose}>\n <div\n style={s.dialog}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n {/* Header */}\n <div style={s.header}>\n <div style={s.iconWrap}>\n <IconPackageExport size={20} />\n </div>\n <div>\n <h2 style={s.title}>Code changes required</h2>\n <p style={s.subtitle}>\n {featureLabel\n ? `\"${featureLabel}\" creates or modifies source code, which needs Desktop or Builder from this surface.`\n : \"This action creates or modifies source code, which needs Desktop or Builder from this surface.\"}\n </p>\n </div>\n </div>\n\n {/* Options */}\n <div style={s.options}>\n <a\n href={DESKTOP_DOWNLOAD_URL}\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{ ...s.optionCard, ...s.optionLink }}\n onMouseEnter={(e) =>\n Object.assign(e.currentTarget.style, s.optionCardHover)\n }\n onMouseLeave={(e) =>\n Object.assign(e.currentTarget.style, { borderColor: \"#e5e7eb\" })\n }\n >\n <div style={s.optionIcon}>\n <IconCode size={24} />\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>Use Agent Native Desktop</span>\n <span style={s.optionDesc}>\n Open the project in the desktop app to enable source edits,\n Workspace files, and CLI access.\n </span>\n </div>\n </a>\n\n {builderConnected && cloudAgentsAvailable ? (\n <button\n style={{\n ...s.optionCard,\n ...(submitting\n ? { opacity: 0.7, pointerEvents: \"none\" as const }\n : {}),\n }}\n onMouseEnter={(e) =>\n Object.assign(e.currentTarget.style, s.optionCardHover)\n }\n onMouseLeave={(e) =>\n Object.assign(e.currentTarget.style, { borderColor: \"#e5e7eb\" })\n }\n onClick={handleBuilderAgent}\n >\n <div style={s.optionIcon}>\n {submitting ? (\n <IconLoader2\n size={24}\n style={{ animation: \"spin 1s linear infinite\" }}\n />\n ) : (\n <IconExternalLink size={24} />\n )}\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>Use Builder.io Agent</span>\n <span style={s.optionDesc}>\n Let our cloud agent make the changes for you. You'll get a\n link to preview and deploy.\n </span>\n </div>\n </button>\n ) : builderConnected ? (\n <div\n style={{\n ...s.optionCard,\n cursor: \"default\",\n opacity: 0.85,\n }}\n >\n <div style={s.optionIcon}>\n <IconExternalLink size={24} />\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>\n Builder Cloud Agents coming soon\n </span>\n <span style={s.optionDesc}>\n You don't have access yet. Use the desktop app or your local\n clone for this code change.\n </span>\n </div>\n <span style={s.badge}>Coming soon</span>\n </div>\n ) : (\n <a\n href={builderHref}\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{ ...s.optionCard, ...s.optionLink }}\n onMouseEnter={(e) =>\n Object.assign(e.currentTarget.style, s.optionCardHover)\n }\n onMouseLeave={(e) =>\n Object.assign(e.currentTarget.style, {\n borderColor: \"#e5e7eb\",\n })\n }\n >\n <div style={s.optionIcon}>\n <IconExternalLink size={24} />\n </div>\n <div style={s.optionText}>\n <span style={s.optionTitle}>Connect Builder.io</span>\n <span style={s.optionDesc}>\n Connect Builder to enable cloud-based code changes from this\n app.\n </span>\n </div>\n {!connectUrl && <span style={s.badge}>Setup required</span>}\n </a>\n )}\n </div>\n\n {/* Branch result */}\n {branchUrl && (\n <div style={s.result}>\n <span style={{ fontSize: 13, fontWeight: 600 }}>\n Branch created\n </span>\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={s.resultLink}\n >\n {branchUrl}\n </a>\n </div>\n )}\n\n {error && (\n <p style={{ color: \"#ef4444\", fontSize: 12, marginTop: 12 }}>\n {error}\n </p>\n )}\n\n {/* Close */}\n <button style={s.closeButton} onClick={onClose} aria-label=\"Close\">\n <IconX size={16} />\n </button>\n </div>\n </div>,\n document.body,\n );\n}\n\nconst s: Record<string, React.CSSProperties> = {\n backdrop: {\n position: \"fixed\",\n inset: 0,\n background: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 99999,\n padding: \"16px\",\n },\n dialog: {\n position: \"relative\",\n background: \"#fff\",\n borderRadius: \"12px\",\n maxWidth: \"460px\",\n width: \"100%\",\n padding: \"24px\",\n boxShadow:\n \"0 20px 25px -5px rgba(0,0,0,.1), 0 8px 10px -6px rgba(0,0,0,.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n color: \"#111827\",\n },\n header: {\n display: \"flex\",\n gap: \"14px\",\n alignItems: \"flex-start\",\n marginBottom: \"20px\",\n },\n iconWrap: {\n flexShrink: 0,\n width: \"40px\",\n height: \"40px\",\n borderRadius: \"10px\",\n background: \"#f3f4f6\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#6b7280\",\n },\n title: {\n margin: 0,\n fontSize: \"16px\",\n fontWeight: 600,\n lineHeight: \"1.4\",\n },\n subtitle: {\n margin: \"4px 0 0\",\n fontSize: \"13px\",\n color: \"#6b7280\",\n lineHeight: \"1.5\",\n },\n options: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"10px\",\n },\n optionCard: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"14px\",\n padding: \"14px\",\n border: \"1px solid #e5e7eb\",\n borderRadius: \"10px\",\n background: \"transparent\",\n cursor: \"pointer\",\n textAlign: \"left\",\n width: \"100%\",\n fontSize: \"inherit\",\n fontFamily: \"inherit\",\n color: \"inherit\",\n },\n optionCardHover: {\n borderColor: \"#a5b4fc\",\n },\n optionLink: {\n textDecoration: \"none\",\n boxSizing: \"border-box\",\n },\n optionIcon: {\n flexShrink: 0,\n color: \"#00B5FF\",\n marginTop: \"2px\",\n },\n optionText: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n },\n optionTitle: {\n fontSize: \"14px\",\n fontWeight: 600,\n },\n optionDesc: {\n fontSize: \"12px\",\n color: \"#6b7280\",\n lineHeight: \"1.5\",\n },\n code: {\n background: \"#f3f4f6\",\n padding: \"1px 5px\",\n borderRadius: \"4px\",\n fontSize: \"11px\",\n fontFamily: \"monospace\",\n },\n badge: {\n position: \"absolute\",\n top: \"10px\",\n right: \"10px\",\n fontSize: \"10px\",\n fontWeight: 600,\n color: \"#00B5FF\",\n background: \"#e0f2fe\",\n padding: \"2px 8px\",\n borderRadius: \"99px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.5px\",\n },\n closeButton: {\n position: \"absolute\",\n top: \"12px\",\n right: \"12px\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"6px\",\n borderRadius: \"6px\",\n color: \"#9ca3af\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n result: {\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"8px\",\n border: \"1px solid #22c55e40\",\n background: \"#f0fdf4\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"4px\",\n },\n resultLink: {\n fontSize: \"12px\",\n color: \"#00B5FF\",\n textDecoration: \"none\",\n wordBreak: \"break-all\",\n },\n};\n"]}
@@ -6,7 +6,7 @@ const AVATAR_SIZE = 28;
6
6
  const OVERLAP = -8;
7
7
  const BORDER_WIDTH = 2;
8
8
  const FONT_SIZE = 12;
9
- const AGENT_COLOR = "#a78bfa";
9
+ const AGENT_COLOR = "#00B5FF";
10
10
  const baseAvatarStyle = {
11
11
  width: AVATAR_SIZE,
12
12
  height: AVATAR_SIZE,
@@ -1 +1 @@
1
- {"version":3,"file":"PresenceBar.js","sourceRoot":"","sources":["../../../src/client/components/PresenceBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from \"react\";\nimport {\n type CollabUser,\n dedupeCollabUsersByEmail,\n emailToColor,\n emailToName,\n} from \"../../collab/client.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./ui/tooltip.js\";\n\nexport interface PresenceBarProps {\n /** Active collaborators on this document. */\n activeUsers: CollabUser[];\n /** Whether the agent has a durable presence entry. */\n agentPresent?: boolean;\n /** Whether the agent is actively making edits right now. */\n agentActive?: boolean;\n /** Current user's email (to exclude from the list). */\n currentUserEmail?: string;\n /** Max visible avatars before \"+N\" overflow. Default: 5 */\n maxVisible?: number;\n /** Additional CSS classes. */\n className?: string;\n}\n\nconst AVATAR_SIZE = 28;\nconst OVERLAP = -8;\nconst BORDER_WIDTH = 2;\nconst FONT_SIZE = 12;\nconst AGENT_COLOR = \"#a78bfa\";\n\nconst baseAvatarStyle: React.CSSProperties = {\n width: AVATAR_SIZE,\n height: AVATAR_SIZE,\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: FONT_SIZE,\n fontWeight: 700,\n color: \"#fff\",\n border: `${BORDER_WIDTH}px solid #fff`,\n flexShrink: 0,\n position: \"relative\",\n cursor: \"default\",\n boxSizing: \"border-box\",\n};\n\nconst containerStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n flexDirection: \"row\",\n};\n\nconst pulseKeyframes = `\n@keyframes _anPresencePulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n`;\n\nlet styleInjected = false;\n\nfunction injectStyles() {\n if (styleInjected || typeof document === \"undefined\") return;\n const style = document.createElement(\"style\");\n style.textContent = pulseKeyframes;\n document.head.appendChild(style);\n styleInjected = true;\n}\n\nfunction UserAvatar({ user, isFirst }: { user: CollabUser; isFirst: boolean }) {\n const color = user.color || emailToColor(user.email);\n const name = user.name || emailToName(user.email);\n const initial = name.charAt(0).toUpperCase();\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <div\n style={{\n ...baseAvatarStyle,\n backgroundColor: color,\n marginLeft: isFirst ? 0 : OVERLAP,\n }}\n aria-label={`${name} (${user.email})`}\n tabIndex={0}\n >\n {initial}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{user.email}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction AgentAvatar({ active }: { active: boolean }) {\n injectStyles();\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n }}\n >\n <div\n style={{\n ...baseAvatarStyle,\n backgroundColor: AGENT_COLOR,\n marginLeft: 0,\n animation: active ? \"_anPresencePulse 2s infinite\" : undefined,\n }}\n title={active ? \"AI is editing\" : \"AI agent\"}\n >\n A\n </div>\n {active && <AgentEditingChip />}\n </div>\n );\n}\n\nfunction AgentEditingChip() {\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n height: 20,\n padding: \"0 8px\",\n borderRadius: 9999,\n backgroundColor: `${AGENT_COLOR}20`,\n color: AGENT_COLOR,\n fontSize: 11,\n fontWeight: 600,\n whiteSpace: \"nowrap\",\n }}\n >\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n backgroundColor: AGENT_COLOR,\n animation: \"_anPresencePulse 2s infinite\",\n flexShrink: 0,\n }}\n />\n AI editing\n </span>\n );\n}\n\nfunction OverflowBadge({\n count,\n isFirst,\n}: {\n count: number;\n isFirst: boolean;\n}) {\n return (\n <div\n style={{\n ...baseAvatarStyle,\n backgroundColor: \"rgba(255,255,255,0.1)\",\n color: \"rgba(255,255,255,0.5)\",\n marginLeft: isFirst ? 0 : OVERLAP,\n fontSize: 10,\n }}\n title={`${count} more collaborator${count === 1 ? \"\" : \"s\"}`}\n >\n +{count}\n </div>\n );\n}\n\nexport function PresenceBar({\n activeUsers,\n agentPresent,\n agentActive,\n currentUserEmail,\n maxVisible = 5,\n className,\n}: PresenceBarProps) {\n const { humanUsers, showAgent } = useMemo(() => {\n const currentEmail = currentUserEmail?.trim().toLowerCase();\n const uniqueUsers = dedupeCollabUsersByEmail(activeUsers);\n const humans = uniqueUsers.filter((u) => {\n const email = u.email.trim().toLowerCase();\n return email !== currentEmail && email !== \"agent@system\";\n });\n const hasAgentUser = uniqueUsers.some(\n (u) => u.email.trim().toLowerCase() === \"agent@system\",\n );\n return {\n humanUsers: humans,\n showAgent: agentPresent || agentActive || hasAgentUser,\n };\n }, [activeUsers, currentUserEmail, agentPresent, agentActive]);\n\n const visibleUsers = humanUsers.slice(0, maxVisible);\n const overflowCount = humanUsers.length - visibleUsers.length;\n\n if (!showAgent && humanUsers.length === 0) return null;\n\n return (\n <TooltipProvider delayDuration={150}>\n <div style={containerStyle} className={className}>\n {showAgent && <AgentAvatar active={!!agentActive} />}\n {visibleUsers.length > 0 && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n marginLeft: showAgent ? 6 : 0,\n }}\n >\n {visibleUsers.map((u, i) => (\n <UserAvatar key={u.email} user={u} isFirst={i === 0} />\n ))}\n {overflowCount > 0 && (\n <OverflowBadge count={overflowCount} isFirst={false} />\n )}\n </div>\n )}\n </div>\n </TooltipProvider>\n );\n}\n"]}
1
+ {"version":3,"file":"PresenceBar.js","sourceRoot":"","sources":["../../../src/client/components/PresenceBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from \"react\";\nimport {\n type CollabUser,\n dedupeCollabUsersByEmail,\n emailToColor,\n emailToName,\n} from \"../../collab/client.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./ui/tooltip.js\";\n\nexport interface PresenceBarProps {\n /** Active collaborators on this document. */\n activeUsers: CollabUser[];\n /** Whether the agent has a durable presence entry. */\n agentPresent?: boolean;\n /** Whether the agent is actively making edits right now. */\n agentActive?: boolean;\n /** Current user's email (to exclude from the list). */\n currentUserEmail?: string;\n /** Max visible avatars before \"+N\" overflow. Default: 5 */\n maxVisible?: number;\n /** Additional CSS classes. */\n className?: string;\n}\n\nconst AVATAR_SIZE = 28;\nconst OVERLAP = -8;\nconst BORDER_WIDTH = 2;\nconst FONT_SIZE = 12;\nconst AGENT_COLOR = \"#00B5FF\";\n\nconst baseAvatarStyle: React.CSSProperties = {\n width: AVATAR_SIZE,\n height: AVATAR_SIZE,\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: FONT_SIZE,\n fontWeight: 700,\n color: \"#fff\",\n border: `${BORDER_WIDTH}px solid #fff`,\n flexShrink: 0,\n position: \"relative\",\n cursor: \"default\",\n boxSizing: \"border-box\",\n};\n\nconst containerStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n flexDirection: \"row\",\n};\n\nconst pulseKeyframes = `\n@keyframes _anPresencePulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n`;\n\nlet styleInjected = false;\n\nfunction injectStyles() {\n if (styleInjected || typeof document === \"undefined\") return;\n const style = document.createElement(\"style\");\n style.textContent = pulseKeyframes;\n document.head.appendChild(style);\n styleInjected = true;\n}\n\nfunction UserAvatar({ user, isFirst }: { user: CollabUser; isFirst: boolean }) {\n const color = user.color || emailToColor(user.email);\n const name = user.name || emailToName(user.email);\n const initial = name.charAt(0).toUpperCase();\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <div\n style={{\n ...baseAvatarStyle,\n backgroundColor: color,\n marginLeft: isFirst ? 0 : OVERLAP,\n }}\n aria-label={`${name} (${user.email})`}\n tabIndex={0}\n >\n {initial}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{user.email}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction AgentAvatar({ active }: { active: boolean }) {\n injectStyles();\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n }}\n >\n <div\n style={{\n ...baseAvatarStyle,\n backgroundColor: AGENT_COLOR,\n marginLeft: 0,\n animation: active ? \"_anPresencePulse 2s infinite\" : undefined,\n }}\n title={active ? \"AI is editing\" : \"AI agent\"}\n >\n A\n </div>\n {active && <AgentEditingChip />}\n </div>\n );\n}\n\nfunction AgentEditingChip() {\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n height: 20,\n padding: \"0 8px\",\n borderRadius: 9999,\n backgroundColor: `${AGENT_COLOR}20`,\n color: AGENT_COLOR,\n fontSize: 11,\n fontWeight: 600,\n whiteSpace: \"nowrap\",\n }}\n >\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n backgroundColor: AGENT_COLOR,\n animation: \"_anPresencePulse 2s infinite\",\n flexShrink: 0,\n }}\n />\n AI editing\n </span>\n );\n}\n\nfunction OverflowBadge({\n count,\n isFirst,\n}: {\n count: number;\n isFirst: boolean;\n}) {\n return (\n <div\n style={{\n ...baseAvatarStyle,\n backgroundColor: \"rgba(255,255,255,0.1)\",\n color: \"rgba(255,255,255,0.5)\",\n marginLeft: isFirst ? 0 : OVERLAP,\n fontSize: 10,\n }}\n title={`${count} more collaborator${count === 1 ? \"\" : \"s\"}`}\n >\n +{count}\n </div>\n );\n}\n\nexport function PresenceBar({\n activeUsers,\n agentPresent,\n agentActive,\n currentUserEmail,\n maxVisible = 5,\n className,\n}: PresenceBarProps) {\n const { humanUsers, showAgent } = useMemo(() => {\n const currentEmail = currentUserEmail?.trim().toLowerCase();\n const uniqueUsers = dedupeCollabUsersByEmail(activeUsers);\n const humans = uniqueUsers.filter((u) => {\n const email = u.email.trim().toLowerCase();\n return email !== currentEmail && email !== \"agent@system\";\n });\n const hasAgentUser = uniqueUsers.some(\n (u) => u.email.trim().toLowerCase() === \"agent@system\",\n );\n return {\n humanUsers: humans,\n showAgent: agentPresent || agentActive || hasAgentUser,\n };\n }, [activeUsers, currentUserEmail, agentPresent, agentActive]);\n\n const visibleUsers = humanUsers.slice(0, maxVisible);\n const overflowCount = humanUsers.length - visibleUsers.length;\n\n if (!showAgent && humanUsers.length === 0) return null;\n\n return (\n <TooltipProvider delayDuration={150}>\n <div style={containerStyle} className={className}>\n {showAgent && <AgentAvatar active={!!agentActive} />}\n {visibleUsers.length > 0 && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n marginLeft: showAgent ? 6 : 0,\n }}\n >\n {visibleUsers.map((u, i) => (\n <UserAvatar key={u.email} user={u} isFirst={i === 0} />\n ))}\n {overflowCount > 0 && (\n <OverflowBadge count={overflowCount} isFirst={false} />\n )}\n </div>\n )}\n </div>\n </TooltipProvider>\n );\n}\n"]}
@@ -2,10 +2,10 @@ import type { ComposerMode } from "./types.js";
2
2
  interface ComposerPlusMenuProps {
3
3
  onSelectMode?: (mode: ComposerMode) => void;
4
4
  /**
5
- * "full" (default): full + menu with Upload File, Create Skill, Scheduled Task,
6
- * Automation, Tool, MCP Server. "upload-only": clicking + opens the file
5
+ * "full" (default): full + menu with Upload File, Create Skill, Schedule Task,
6
+ * Automation, Extension, MCP Server. "upload-only": clicking + opens the file
7
7
  * picker directly — no popover, no other modes. Use for prompt popovers
8
- * (create tool, create deck, create dashboard, etc.) where the only thing
8
+ * (create extension, create deck, create dashboard, etc.) where the only thing
9
9
  * to attach is a file.
10
10
  */
11
11
  mode?: "full" | "upload-only";
@@ -165,7 +165,7 @@ function ComposerPlusMenuFull({ onSelectMode, }) {
165
165
  },
166
166
  {
167
167
  icon: _jsx(IconClock, { className: "h-3.5 w-3.5" }),
168
- label: "Scheduled Task",
168
+ label: "Schedule Task",
169
169
  desc: "Run something on a schedule",
170
170
  action: () => {
171
171
  onSelectMode?.("job");
@@ -183,8 +183,8 @@ function ComposerPlusMenuFull({ onSelectMode, }) {
183
183
  },
184
184
  {
185
185
  icon: _jsx(IconTool, { className: "h-3.5 w-3.5" }),
186
- label: "Create Tool",
187
- desc: "Build an interactive mini app",
186
+ label: "Create Extension",
187
+ desc: "Build a mini app extension",
188
188
  action: () => {
189
189
  onSelectMode?.("extension");
190
190
  setOpen(false);
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerPlusMenu.js","sourceRoot":"","sources":["../../../src/client/composer/ComposerPlusMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport {\n IconPlus,\n IconUpload,\n IconBulb,\n IconClock,\n IconBolt,\n IconTool,\n IconPlugConnected,\n IconLoader2,\n IconCheck,\n IconArrowLeft,\n} from \"@tabler/icons-react\";\nimport { ComposerPrimitive } from \"@assistant-ui/react\";\nimport { cn } from \"../utils.js\";\nimport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n} from \"../components/ui/popover.js\";\nimport { useOrg } from \"../org/hooks.js\";\nimport {\n formatMcpServerError,\n getMcpUrlValidationError,\n useCreateMcpServer,\n testMcpServerUrl,\n type McpServerScope,\n} from \"../resources/use-mcp-servers.js\";\nimport type { ComposerMode } from \"./types.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\ninterface ComposerPlusMenuProps {\n onSelectMode?: (mode: ComposerMode) => void;\n /**\n * \"full\" (default): full + menu with Upload File, Create Skill, Scheduled Task,\n * Automation, Tool, MCP Server. \"upload-only\": clicking + opens the file\n * picker directly — no popover, no other modes. Use for prompt popovers\n * (create tool, create deck, create dashboard, etc.) where the only thing\n * to attach is a file.\n */\n mode?: \"full\" | \"upload-only\";\n}\n\ntype View = \"menu\" | \"mcp-server\";\n\nfunction UploadOnlyAttachButton() {\n // Mirrors the hidden-AddAttachment + visible-button pattern used in the full\n // ComposerPlusMenu. Rendering AddAttachment directly as the visible button\n // can disappear when the runtime reports no eligible adapter; the hidden\n // delegate keeps the visible \"+\" button reliably mounted.\n const hiddenRef = useRef<HTMLButtonElement>(null);\n return (\n <>\n <ComposerPrimitive.AddAttachment asChild>\n <button\n ref={hiddenRef}\n type=\"button\"\n className=\"hidden\"\n tabIndex={-1}\n aria-hidden\n />\n </ComposerPrimitive.AddAttachment>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => hiddenRef.current?.click()}\n className=\"shrink-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50\"\n aria-label=\"Upload file\"\n >\n <IconPlus className=\"h-4 w-4\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>\n Upload image, PDF, PPTX, DOCX, text, Markdown, JSON, CSV, HTML, CSS,\n or XML\n </TooltipContent>\n </Tooltip>\n </>\n );\n}\n\nexport function ComposerPlusMenu({\n onSelectMode,\n mode = \"full\",\n}: ComposerPlusMenuProps) {\n if (mode === \"upload-only\") {\n return <UploadOnlyAttachButton />;\n }\n return <ComposerPlusMenuFull onSelectMode={onSelectMode} />;\n}\n\nfunction ComposerPlusMenuFull({\n onSelectMode,\n}: Pick<ComposerPlusMenuProps, \"onSelectMode\">) {\n const [open, setOpen] = useState(false);\n const [view, setView] = useState<View>(\"menu\");\n\n // MCP state\n const { data: org } = useOrg();\n const canCreateOrgMcp =\n !org?.orgId || org.role === \"owner\" || org.role === \"admin\";\n const hasOrg = !!org?.orgId;\n const defaultMcpScope: McpServerScope =\n hasOrg && canCreateOrgMcp ? \"org\" : \"user\";\n const [mcpScope, setMcpScope] = useState<McpServerScope>(defaultMcpScope);\n const [mcpName, setMcpName] = useState(\"\");\n const [mcpUrl, setMcpUrl] = useState(\"\");\n const [mcpDescription, setMcpDescription] = useState(\"\");\n const [mcpHeadersText, setMcpHeadersText] = useState(\"\");\n const [mcpBusy, setMcpBusy] = useState(false);\n const [mcpError, setMcpError] = useState<string | null>(null);\n const [mcpTestResult, setMcpTestResult] = useState<{\n ok: boolean;\n message: string;\n } | null>(null);\n const createMcp = useCreateMcpServer();\n\n const inputRef = useRef<HTMLInputElement>(null);\n const fileUploadRef = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n if (open) {\n setView(\"menu\");\n setMcpScope(defaultMcpScope);\n setMcpName(\"\");\n setMcpUrl(\"\");\n setMcpDescription(\"\");\n setMcpHeadersText(\"\");\n setMcpError(null);\n setMcpTestResult(null);\n setMcpBusy(false);\n }\n }, [open, defaultMcpScope]);\n\n useEffect(() => {\n if (view === \"mcp-server\") {\n setMcpError(null);\n setMcpTestResult(null);\n const t = setTimeout(() => inputRef.current?.focus(), 50);\n return () => clearTimeout(t);\n }\n }, [view]);\n\n const clearMcpFeedback = () => {\n setMcpError(null);\n setMcpTestResult(null);\n };\n\n const parseHeaderLines = (\n text: string,\n ): Record<string, string> | undefined => {\n const out: Record<string, string> = {};\n for (const line of text.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const idx = trimmed.indexOf(\":\");\n if (idx <= 0) continue;\n const key = trimmed.slice(0, idx).trim();\n const val = trimmed.slice(idx + 1).trim();\n if (!key || !val) continue;\n out[key] = val;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n };\n\n const submitMcpServer = async () => {\n const name = mcpName.trim();\n const url = mcpUrl.trim();\n if (!name || !url || mcpBusy) return;\n const validationError = getMcpUrlValidationError(url);\n if (validationError) {\n setMcpError(validationError);\n setMcpTestResult(null);\n return;\n }\n setMcpError(null);\n setMcpBusy(true);\n try {\n await createMcp.mutateAsync({\n scope: mcpScope,\n name,\n url,\n headers: parseHeaderLines(mcpHeadersText),\n description: mcpDescription.trim() || undefined,\n });\n setOpen(false);\n } catch (err: any) {\n setMcpError(formatMcpServerError(err));\n } finally {\n setMcpBusy(false);\n }\n };\n\n const runMcpTest = async () => {\n const url = mcpUrl.trim();\n if (!url || mcpBusy) return;\n const validationError = getMcpUrlValidationError(url);\n if (validationError) {\n setMcpTestResult({ ok: false, message: validationError });\n setMcpError(null);\n return;\n }\n setMcpTestResult(null);\n setMcpError(null);\n setMcpBusy(true);\n try {\n const res = await testMcpServerUrl(url, parseHeaderLines(mcpHeadersText));\n if (res.ok) {\n setMcpTestResult({\n ok: true,\n message: `${res.toolCount ?? 0} tool${res.toolCount === 1 ? \"\" : \"s\"} available`,\n });\n } else {\n setMcpTestResult({ ok: false, message: res.error ?? \"Failed\" });\n }\n } catch (err: any) {\n setMcpTestResult({ ok: false, message: formatMcpServerError(err) });\n } finally {\n setMcpBusy(false);\n }\n };\n\n const menuItems: {\n icon: React.ReactNode;\n label: string;\n desc: string;\n action: () => void;\n }[] = [\n {\n icon: <IconUpload className=\"h-3.5 w-3.5\" />,\n label: \"Upload File\",\n desc: \"Images, PDFs, text/code, JSON, CSV\",\n action: () => {\n setOpen(false);\n setTimeout(() => fileUploadRef.current?.click(), 0);\n },\n },\n {\n icon: <IconBulb className=\"h-3.5 w-3.5\" />,\n label: \"Create Skill\",\n desc: \"Teach the agent a new ability\",\n action: () => {\n onSelectMode?.(\"skill\");\n setOpen(false);\n },\n },\n {\n icon: <IconClock className=\"h-3.5 w-3.5\" />,\n label: \"Scheduled Task\",\n desc: \"Run something on a schedule\",\n action: () => {\n onSelectMode?.(\"job\");\n setOpen(false);\n },\n },\n {\n icon: <IconBolt className=\"h-3.5 w-3.5\" />,\n label: \"Create Automation\",\n desc: \"Set up a when-X-do-Y rule\",\n action: () => {\n onSelectMode?.(\"automation\");\n setOpen(false);\n },\n },\n {\n icon: <IconTool className=\"h-3.5 w-3.5\" />,\n label: \"Create Tool\",\n desc: \"Build an interactive mini app\",\n action: () => {\n onSelectMode?.(\"extension\");\n setOpen(false);\n },\n },\n {\n icon: <IconPlugConnected className=\"h-3.5 w-3.5\" />,\n label: \"Connect MCP Server\",\n desc: \"Expose external tools to the agent\",\n action: () => setView(\"mcp-server\"),\n },\n ];\n\n const backButton = (\n <button\n type=\"button\"\n onClick={() => {\n clearMcpFeedback();\n setView(\"menu\");\n }}\n className=\"flex items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground mb-1.5\"\n >\n <IconArrowLeft className=\"h-3 w-3\" />\n Back\n </button>\n );\n\n return (\n <>\n {/* Hidden button to trigger the native file upload */}\n <ComposerPrimitive.AddAttachment asChild>\n <button\n ref={fileUploadRef}\n type=\"button\"\n className=\"hidden\"\n tabIndex={-1}\n aria-hidden\n />\n </ComposerPrimitive.AddAttachment>\n\n <Popover open={open} onOpenChange={setOpen}>\n <Tooltip>\n <TooltipTrigger asChild>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"shrink-0 flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50 disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <IconPlus className=\"h-4 w-4\" />\n </button>\n </PopoverTrigger>\n </TooltipTrigger>\n <TooltipContent>Add...</TooltipContent>\n </Tooltip>\n <PopoverContent\n side=\"top\"\n align=\"start\"\n sideOffset={8}\n className=\"w-[260px] p-0 rounded-lg\"\n style={{ fontSize: 13, lineHeight: \"normal\" }}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n {view === \"menu\" && (\n <div className=\"py-1\">\n {menuItems.map((item) => (\n <button\n key={item.label}\n onClick={item.action}\n className=\"flex w-full items-center gap-2.5 px-3 py-2 text-left hover:bg-accent/50\"\n >\n <span className=\"text-muted-foreground\">{item.icon}</span>\n <div className=\"min-w-0\">\n <div className=\"text-[12px] font-medium text-foreground\">\n {item.label}\n </div>\n <div className=\"mt-0.5 text-[10px] text-muted-foreground/60\">\n {item.desc}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n\n {view === \"mcp-server\" && (\n <div className=\"p-3\">\n {backButton}\n <label className=\"mb-1 block text-[11px] font-semibold text-foreground\">\n Connect MCP Server\n </label>\n <p className=\"mb-2 text-[10px] text-muted-foreground/60 leading-relaxed\">\n Point at any Streamable HTTP MCP server. Its tools become\n available to the agent. Use Personal for private or staging\n servers; use Organization only for vetted servers the whole org\n should share.\n </p>\n <div className=\"space-y-2\">\n <div className=\"flex gap-1 rounded-md border border-border p-0.5\">\n <button\n type=\"button\"\n onClick={() => setMcpScope(\"user\")}\n className={cn(\n \"flex-1 rounded px-2 py-1 text-[11px] font-medium\",\n mcpScope === \"user\"\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n >\n Personal\n </button>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() =>\n hasOrg && canCreateOrgMcp && setMcpScope(\"org\")\n }\n disabled={!hasOrg || !canCreateOrgMcp}\n className={cn(\n \"flex-1 rounded px-2 py-1 text-[11px] font-medium\",\n mcpScope === \"org\"\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground hover:text-foreground\",\n (!hasOrg || !canCreateOrgMcp) &&\n \"cursor-not-allowed opacity-50 hover:text-muted-foreground\",\n )}\n >\n Organization\n </button>\n </TooltipTrigger>\n <TooltipContent>\n {!hasOrg\n ? \"Join an organization to share MCP servers\"\n : !canCreateOrgMcp\n ? \"Only owners and admins can add org-scope servers\"\n : undefined}\n </TooltipContent>\n </Tooltip>\n </div>\n <input\n ref={inputRef}\n value={mcpName}\n onChange={(e) => {\n setMcpName(e.target.value);\n clearMcpFeedback();\n }}\n className=\"w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Server name (e.g. zapier-staging)\"\n />\n <input\n value={mcpUrl}\n onChange={(e) => {\n setMcpUrl(e.target.value);\n clearMcpFeedback();\n }}\n className=\"w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"https://mcp.example.com/\"\n />\n <input\n value={mcpDescription}\n onChange={(e) => {\n setMcpDescription(e.target.value);\n clearMcpFeedback();\n }}\n className=\"w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Description (optional)\"\n />\n <div>\n <label className=\"block text-[10px] font-medium text-foreground\">\n Headers\n </label>\n <p className=\"mt-0.5 text-[10px] leading-snug text-muted-foreground/70\">\n Optional. One per line, for example Authorization: Bearer\n sk-...\n </p>\n </div>\n <textarea\n value={mcpHeadersText}\n onChange={(e) => {\n setMcpHeadersText(e.target.value);\n clearMcpFeedback();\n }}\n rows={2}\n className=\"w-full resize-y rounded-md border border-border bg-background px-2.5 py-1.5 text-[12px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n style={{\n fontFamily:\n 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace',\n }}\n placeholder=\"Authorization: Bearer sk-...\"\n />\n {mcpTestResult && (\n <div\n className={cn(\n \"flex items-start gap-1 text-[11px] leading-snug\",\n mcpTestResult.ok\n ? \"text-green-600 dark:text-green-400\"\n : \"text-red-600 dark:text-red-400\",\n )}\n >\n {mcpTestResult.ok && (\n <IconCheck className=\"mt-0.5 h-3 w-3 shrink-0\" />\n )}\n <span className=\"min-w-0 break-words\">\n {mcpTestResult.message}\n </span>\n </div>\n )}\n {mcpError && (\n <div className=\"break-words text-[11px] leading-snug text-red-600 dark:text-red-400\">\n {mcpError}\n </div>\n )}\n </div>\n <div className=\"mt-2.5 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n onClick={runMcpTest}\n disabled={!mcpUrl.trim() || mcpBusy}\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-[11px] font-medium text-foreground hover:bg-accent disabled:opacity-40 disabled:pointer-events-none\"\n >\n Test\n </button>\n <button\n type=\"button\"\n onClick={submitMcpServer}\n disabled={!mcpName.trim() || !mcpUrl.trim() || mcpBusy}\n className=\"rounded-md bg-accent px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40 disabled:pointer-events-none\"\n >\n {mcpBusy ? (\n <IconLoader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n \"Connect\"\n )}\n </button>\n </div>\n </div>\n )}\n </PopoverContent>\n </Popover>\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"ComposerPlusMenu.js","sourceRoot":"","sources":["../../../src/client/composer/ComposerPlusMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport {\n IconPlus,\n IconUpload,\n IconBulb,\n IconClock,\n IconBolt,\n IconTool,\n IconPlugConnected,\n IconLoader2,\n IconCheck,\n IconArrowLeft,\n} from \"@tabler/icons-react\";\nimport { ComposerPrimitive } from \"@assistant-ui/react\";\nimport { cn } from \"../utils.js\";\nimport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n} from \"../components/ui/popover.js\";\nimport { useOrg } from \"../org/hooks.js\";\nimport {\n formatMcpServerError,\n getMcpUrlValidationError,\n useCreateMcpServer,\n testMcpServerUrl,\n type McpServerScope,\n} from \"../resources/use-mcp-servers.js\";\nimport type { ComposerMode } from \"./types.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\ninterface ComposerPlusMenuProps {\n onSelectMode?: (mode: ComposerMode) => void;\n /**\n * \"full\" (default): full + menu with Upload File, Create Skill, Schedule Task,\n * Automation, Extension, MCP Server. \"upload-only\": clicking + opens the file\n * picker directly — no popover, no other modes. Use for prompt popovers\n * (create extension, create deck, create dashboard, etc.) where the only thing\n * to attach is a file.\n */\n mode?: \"full\" | \"upload-only\";\n}\n\ntype View = \"menu\" | \"mcp-server\";\n\nfunction UploadOnlyAttachButton() {\n // Mirrors the hidden-AddAttachment + visible-button pattern used in the full\n // ComposerPlusMenu. Rendering AddAttachment directly as the visible button\n // can disappear when the runtime reports no eligible adapter; the hidden\n // delegate keeps the visible \"+\" button reliably mounted.\n const hiddenRef = useRef<HTMLButtonElement>(null);\n return (\n <>\n <ComposerPrimitive.AddAttachment asChild>\n <button\n ref={hiddenRef}\n type=\"button\"\n className=\"hidden\"\n tabIndex={-1}\n aria-hidden\n />\n </ComposerPrimitive.AddAttachment>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => hiddenRef.current?.click()}\n className=\"shrink-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50\"\n aria-label=\"Upload file\"\n >\n <IconPlus className=\"h-4 w-4\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>\n Upload image, PDF, PPTX, DOCX, text, Markdown, JSON, CSV, HTML, CSS,\n or XML\n </TooltipContent>\n </Tooltip>\n </>\n );\n}\n\nexport function ComposerPlusMenu({\n onSelectMode,\n mode = \"full\",\n}: ComposerPlusMenuProps) {\n if (mode === \"upload-only\") {\n return <UploadOnlyAttachButton />;\n }\n return <ComposerPlusMenuFull onSelectMode={onSelectMode} />;\n}\n\nfunction ComposerPlusMenuFull({\n onSelectMode,\n}: Pick<ComposerPlusMenuProps, \"onSelectMode\">) {\n const [open, setOpen] = useState(false);\n const [view, setView] = useState<View>(\"menu\");\n\n // MCP state\n const { data: org } = useOrg();\n const canCreateOrgMcp =\n !org?.orgId || org.role === \"owner\" || org.role === \"admin\";\n const hasOrg = !!org?.orgId;\n const defaultMcpScope: McpServerScope =\n hasOrg && canCreateOrgMcp ? \"org\" : \"user\";\n const [mcpScope, setMcpScope] = useState<McpServerScope>(defaultMcpScope);\n const [mcpName, setMcpName] = useState(\"\");\n const [mcpUrl, setMcpUrl] = useState(\"\");\n const [mcpDescription, setMcpDescription] = useState(\"\");\n const [mcpHeadersText, setMcpHeadersText] = useState(\"\");\n const [mcpBusy, setMcpBusy] = useState(false);\n const [mcpError, setMcpError] = useState<string | null>(null);\n const [mcpTestResult, setMcpTestResult] = useState<{\n ok: boolean;\n message: string;\n } | null>(null);\n const createMcp = useCreateMcpServer();\n\n const inputRef = useRef<HTMLInputElement>(null);\n const fileUploadRef = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n if (open) {\n setView(\"menu\");\n setMcpScope(defaultMcpScope);\n setMcpName(\"\");\n setMcpUrl(\"\");\n setMcpDescription(\"\");\n setMcpHeadersText(\"\");\n setMcpError(null);\n setMcpTestResult(null);\n setMcpBusy(false);\n }\n }, [open, defaultMcpScope]);\n\n useEffect(() => {\n if (view === \"mcp-server\") {\n setMcpError(null);\n setMcpTestResult(null);\n const t = setTimeout(() => inputRef.current?.focus(), 50);\n return () => clearTimeout(t);\n }\n }, [view]);\n\n const clearMcpFeedback = () => {\n setMcpError(null);\n setMcpTestResult(null);\n };\n\n const parseHeaderLines = (\n text: string,\n ): Record<string, string> | undefined => {\n const out: Record<string, string> = {};\n for (const line of text.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const idx = trimmed.indexOf(\":\");\n if (idx <= 0) continue;\n const key = trimmed.slice(0, idx).trim();\n const val = trimmed.slice(idx + 1).trim();\n if (!key || !val) continue;\n out[key] = val;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n };\n\n const submitMcpServer = async () => {\n const name = mcpName.trim();\n const url = mcpUrl.trim();\n if (!name || !url || mcpBusy) return;\n const validationError = getMcpUrlValidationError(url);\n if (validationError) {\n setMcpError(validationError);\n setMcpTestResult(null);\n return;\n }\n setMcpError(null);\n setMcpBusy(true);\n try {\n await createMcp.mutateAsync({\n scope: mcpScope,\n name,\n url,\n headers: parseHeaderLines(mcpHeadersText),\n description: mcpDescription.trim() || undefined,\n });\n setOpen(false);\n } catch (err: any) {\n setMcpError(formatMcpServerError(err));\n } finally {\n setMcpBusy(false);\n }\n };\n\n const runMcpTest = async () => {\n const url = mcpUrl.trim();\n if (!url || mcpBusy) return;\n const validationError = getMcpUrlValidationError(url);\n if (validationError) {\n setMcpTestResult({ ok: false, message: validationError });\n setMcpError(null);\n return;\n }\n setMcpTestResult(null);\n setMcpError(null);\n setMcpBusy(true);\n try {\n const res = await testMcpServerUrl(url, parseHeaderLines(mcpHeadersText));\n if (res.ok) {\n setMcpTestResult({\n ok: true,\n message: `${res.toolCount ?? 0} tool${res.toolCount === 1 ? \"\" : \"s\"} available`,\n });\n } else {\n setMcpTestResult({ ok: false, message: res.error ?? \"Failed\" });\n }\n } catch (err: any) {\n setMcpTestResult({ ok: false, message: formatMcpServerError(err) });\n } finally {\n setMcpBusy(false);\n }\n };\n\n const menuItems: {\n icon: React.ReactNode;\n label: string;\n desc: string;\n action: () => void;\n }[] = [\n {\n icon: <IconUpload className=\"h-3.5 w-3.5\" />,\n label: \"Upload File\",\n desc: \"Images, PDFs, text/code, JSON, CSV\",\n action: () => {\n setOpen(false);\n setTimeout(() => fileUploadRef.current?.click(), 0);\n },\n },\n {\n icon: <IconBulb className=\"h-3.5 w-3.5\" />,\n label: \"Create Skill\",\n desc: \"Teach the agent a new ability\",\n action: () => {\n onSelectMode?.(\"skill\");\n setOpen(false);\n },\n },\n {\n icon: <IconClock className=\"h-3.5 w-3.5\" />,\n label: \"Schedule Task\",\n desc: \"Run something on a schedule\",\n action: () => {\n onSelectMode?.(\"job\");\n setOpen(false);\n },\n },\n {\n icon: <IconBolt className=\"h-3.5 w-3.5\" />,\n label: \"Create Automation\",\n desc: \"Set up a when-X-do-Y rule\",\n action: () => {\n onSelectMode?.(\"automation\");\n setOpen(false);\n },\n },\n {\n icon: <IconTool className=\"h-3.5 w-3.5\" />,\n label: \"Create Extension\",\n desc: \"Build a mini app extension\",\n action: () => {\n onSelectMode?.(\"extension\");\n setOpen(false);\n },\n },\n {\n icon: <IconPlugConnected className=\"h-3.5 w-3.5\" />,\n label: \"Connect MCP Server\",\n desc: \"Expose external tools to the agent\",\n action: () => setView(\"mcp-server\"),\n },\n ];\n\n const backButton = (\n <button\n type=\"button\"\n onClick={() => {\n clearMcpFeedback();\n setView(\"menu\");\n }}\n className=\"flex items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground mb-1.5\"\n >\n <IconArrowLeft className=\"h-3 w-3\" />\n Back\n </button>\n );\n\n return (\n <>\n {/* Hidden button to trigger the native file upload */}\n <ComposerPrimitive.AddAttachment asChild>\n <button\n ref={fileUploadRef}\n type=\"button\"\n className=\"hidden\"\n tabIndex={-1}\n aria-hidden\n />\n </ComposerPrimitive.AddAttachment>\n\n <Popover open={open} onOpenChange={setOpen}>\n <Tooltip>\n <TooltipTrigger asChild>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"shrink-0 flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50 disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <IconPlus className=\"h-4 w-4\" />\n </button>\n </PopoverTrigger>\n </TooltipTrigger>\n <TooltipContent>Add...</TooltipContent>\n </Tooltip>\n <PopoverContent\n side=\"top\"\n align=\"start\"\n sideOffset={8}\n className=\"w-[260px] p-0 rounded-lg\"\n style={{ fontSize: 13, lineHeight: \"normal\" }}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n {view === \"menu\" && (\n <div className=\"py-1\">\n {menuItems.map((item) => (\n <button\n key={item.label}\n onClick={item.action}\n className=\"flex w-full items-center gap-2.5 px-3 py-2 text-left hover:bg-accent/50\"\n >\n <span className=\"text-muted-foreground\">{item.icon}</span>\n <div className=\"min-w-0\">\n <div className=\"text-[12px] font-medium text-foreground\">\n {item.label}\n </div>\n <div className=\"mt-0.5 text-[10px] text-muted-foreground/60\">\n {item.desc}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n\n {view === \"mcp-server\" && (\n <div className=\"p-3\">\n {backButton}\n <label className=\"mb-1 block text-[11px] font-semibold text-foreground\">\n Connect MCP Server\n </label>\n <p className=\"mb-2 text-[10px] text-muted-foreground/60 leading-relaxed\">\n Point at any Streamable HTTP MCP server. Its tools become\n available to the agent. Use Personal for private or staging\n servers; use Organization only for vetted servers the whole org\n should share.\n </p>\n <div className=\"space-y-2\">\n <div className=\"flex gap-1 rounded-md border border-border p-0.5\">\n <button\n type=\"button\"\n onClick={() => setMcpScope(\"user\")}\n className={cn(\n \"flex-1 rounded px-2 py-1 text-[11px] font-medium\",\n mcpScope === \"user\"\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n >\n Personal\n </button>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() =>\n hasOrg && canCreateOrgMcp && setMcpScope(\"org\")\n }\n disabled={!hasOrg || !canCreateOrgMcp}\n className={cn(\n \"flex-1 rounded px-2 py-1 text-[11px] font-medium\",\n mcpScope === \"org\"\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground hover:text-foreground\",\n (!hasOrg || !canCreateOrgMcp) &&\n \"cursor-not-allowed opacity-50 hover:text-muted-foreground\",\n )}\n >\n Organization\n </button>\n </TooltipTrigger>\n <TooltipContent>\n {!hasOrg\n ? \"Join an organization to share MCP servers\"\n : !canCreateOrgMcp\n ? \"Only owners and admins can add org-scope servers\"\n : undefined}\n </TooltipContent>\n </Tooltip>\n </div>\n <input\n ref={inputRef}\n value={mcpName}\n onChange={(e) => {\n setMcpName(e.target.value);\n clearMcpFeedback();\n }}\n className=\"w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Server name (e.g. zapier-staging)\"\n />\n <input\n value={mcpUrl}\n onChange={(e) => {\n setMcpUrl(e.target.value);\n clearMcpFeedback();\n }}\n className=\"w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"https://mcp.example.com/\"\n />\n <input\n value={mcpDescription}\n onChange={(e) => {\n setMcpDescription(e.target.value);\n clearMcpFeedback();\n }}\n className=\"w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Description (optional)\"\n />\n <div>\n <label className=\"block text-[10px] font-medium text-foreground\">\n Headers\n </label>\n <p className=\"mt-0.5 text-[10px] leading-snug text-muted-foreground/70\">\n Optional. One per line, for example Authorization: Bearer\n sk-...\n </p>\n </div>\n <textarea\n value={mcpHeadersText}\n onChange={(e) => {\n setMcpHeadersText(e.target.value);\n clearMcpFeedback();\n }}\n rows={2}\n className=\"w-full resize-y rounded-md border border-border bg-background px-2.5 py-1.5 text-[12px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n style={{\n fontFamily:\n 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace',\n }}\n placeholder=\"Authorization: Bearer sk-...\"\n />\n {mcpTestResult && (\n <div\n className={cn(\n \"flex items-start gap-1 text-[11px] leading-snug\",\n mcpTestResult.ok\n ? \"text-green-600 dark:text-green-400\"\n : \"text-red-600 dark:text-red-400\",\n )}\n >\n {mcpTestResult.ok && (\n <IconCheck className=\"mt-0.5 h-3 w-3 shrink-0\" />\n )}\n <span className=\"min-w-0 break-words\">\n {mcpTestResult.message}\n </span>\n </div>\n )}\n {mcpError && (\n <div className=\"break-words text-[11px] leading-snug text-red-600 dark:text-red-400\">\n {mcpError}\n </div>\n )}\n </div>\n <div className=\"mt-2.5 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n onClick={runMcpTest}\n disabled={!mcpUrl.trim() || mcpBusy}\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-[11px] font-medium text-foreground hover:bg-accent disabled:opacity-40 disabled:pointer-events-none\"\n >\n Test\n </button>\n <button\n type=\"button\"\n onClick={submitMcpServer}\n disabled={!mcpName.trim() || !mcpUrl.trim() || mcpBusy}\n className=\"rounded-md bg-accent px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40 disabled:pointer-events-none\"\n >\n {mcpBusy ? (\n <IconLoader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n \"Connect\"\n )}\n </button>\n </div>\n </div>\n )}\n </PopoverContent>\n </Popover>\n </>\n );\n}\n"]}
@@ -60,7 +60,7 @@ After creating, update the shared AGENTS.md resource to reference the new skill
60
60
  Keep the skill concise (under 500 lines) and actionable.`,
61
61
  },
62
62
  job: {
63
- label: "Scheduled Task",
63
+ label: "Schedule Task",
64
64
  icon: IconClock,
65
65
  placeholder: "Describe what should happen and when...",
66
66
  messagePrefix: "Create a recurring job: ",