@agent-native/toolkit 0.209.0 → 0.209.1-nightly-20261015005848
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/app/chat/AgentSidebar.d.ts.map +1 -1
- package/dist/app/chat/AgentSidebar.js +22 -11
- package/dist/app/chat/AgentSidebar.js.map +1 -1
- package/dist/app/review/InlineMarkdown.d.ts +2 -0
- package/dist/app/review/InlineMarkdown.d.ts.map +1 -1
- package/dist/app/review/InlineMarkdown.js +25 -7
- package/dist/app/review/InlineMarkdown.js.map +1 -1
- package/dist/composer/MentionChip.d.ts +14 -0
- package/dist/composer/MentionChip.d.ts.map +1 -0
- package/dist/composer/MentionChip.js +11 -0
- package/dist/composer/MentionChip.js.map +1 -0
- package/dist/composer/MentionPopover.d.ts +5 -0
- package/dist/composer/MentionPopover.d.ts.map +1 -1
- package/dist/composer/MentionPopover.js +55 -44
- package/dist/composer/MentionPopover.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +6 -1
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +3 -3
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +18 -2
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +60 -12
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/extensions/MentionReference.d.ts.map +1 -1
- package/dist/composer/extensions/MentionReference.js +16 -5
- package/dist/composer/extensions/MentionReference.js.map +1 -1
- package/dist/composer/index.d.ts +2 -1
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/index.js +1 -0
- package/dist/composer/index.js.map +1 -1
- package/package.json +4 -4
- package/src/app/chat/AgentSidebar.spec.tsx +339 -2
- package/src/app/chat/AgentSidebar.tsx +25 -10
- package/src/app/review/InlineMarkdown.spec.tsx +25 -0
- package/src/app/review/InlineMarkdown.tsx +29 -13
- package/src/composer/MentionChip.tsx +46 -0
- package/src/composer/MentionPopover.tsx +49 -7
- package/src/composer/PromptComposer.text-references.spec.tsx +198 -0
- package/src/composer/PromptComposer.tsx +12 -0
- package/src/composer/TiptapComposer.tsx +100 -10
- package/src/composer/extensions/MentionReference.tsx +22 -14
- package/src/composer/index.ts +2 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionReference.d.ts","sourceRoot":"","sources":["../../../src/composer/extensions/MentionReference.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,IAAI,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"MentionReference.d.ts","sourceRoot":"","sources":["../../../src/composer/extensions/MentionReference.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,IAAI,EAAE,MAAM,cAAc,CAAC;AAiErD,eAAO,MAAM,gBAAgB,gBA0D3B,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { mergeAttributes, Node } from "@tiptap/core";
|
|
3
3
|
import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
|
|
4
|
-
import {
|
|
4
|
+
import { MentionChip } from "../MentionChip.js";
|
|
5
|
+
const NAME_START = /^[\p{L}\p{M}\p{N}_]/u;
|
|
6
|
+
const NAME_END = /[\p{L}\p{M}\p{N}_]$/u;
|
|
5
7
|
function parseMentionItemMedia(value) {
|
|
6
8
|
if (!value)
|
|
7
9
|
return null;
|
|
@@ -39,7 +41,7 @@ function parseMentionItemMedia(value) {
|
|
|
39
41
|
return null;
|
|
40
42
|
}
|
|
41
43
|
const MentionReferenceComponent = ({ node }) => {
|
|
42
|
-
return (_jsx(NodeViewWrapper, { as: "span", className: "inline", children:
|
|
44
|
+
return (_jsx(NodeViewWrapper, { as: "span", className: "inline", children: _jsx(MentionChip, { className: "select-none", title: node.attrs.refPath || node.attrs.refId || node.attrs.label, "data-mention-reference": "", "data-mention-ref-type": node.attrs.refType || undefined, "data-mention-ref-id": node.attrs.refId || undefined, icon: node.attrs.icon, media: node.attrs.media, label: node.attrs.label }) }));
|
|
43
45
|
};
|
|
44
46
|
export const MentionReference = Node.create({
|
|
45
47
|
name: "mentionReference",
|
|
@@ -76,8 +78,17 @@ export const MentionReference = Node.create({
|
|
|
76
78
|
mergeAttributes({ "data-type": "mention-reference" }, HTMLAttributes),
|
|
77
79
|
];
|
|
78
80
|
},
|
|
79
|
-
renderText({ node }) {
|
|
80
|
-
|
|
81
|
+
renderText({ node, parent, index }) {
|
|
82
|
+
const text = `@${node.attrs.label}`;
|
|
83
|
+
// Text matches a mention only as a whole @name token, so a chip right
|
|
84
|
+
// against a word would read as no mention, or as a later one.
|
|
85
|
+
const before = parent.maybeChild(index - 1);
|
|
86
|
+
const after = parent.maybeChild(index + 1);
|
|
87
|
+
const leading = before?.isText && NAME_END.test(before.text ?? "");
|
|
88
|
+
const trailing = NAME_END.test(text) &&
|
|
89
|
+
((after?.isText && NAME_START.test(after.text ?? "")) ||
|
|
90
|
+
after?.type === node.type);
|
|
91
|
+
return `${leading ? " " : ""}${text}${trailing ? " " : ""}`;
|
|
81
92
|
},
|
|
82
93
|
addNodeView() {
|
|
83
94
|
return ReactNodeViewRenderer(MentionReferenceComponent);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionReference.js","sourceRoot":"","sources":["../../../src/composer/extensions/MentionReference.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"MentionReference.js","sourceRoot":"","sources":["../../../src/composer/extensions/MentionReference.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAC1C,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAExC,SAAS,qBAAqB,CAC5B,KAAoB;IAEpB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,IACE,OAAO,MAAM,KAAK,QAAQ;YAC1B,MAAM,KAAK,IAAI;YACf,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACrB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,SAAS,GAAG,MAAiC,CAAC;QACpD,MAAM,eAAe,GACnB,OAAO,SAAS,CAAC,eAAe,KAAK,QAAQ;YAC3C,CAAC,CAAC,SAAS,CAAC,eAAe;YAC3B,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACvD,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpE,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD,CAAC;QACJ,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpE,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,GAAG,EAAE,SAAS,CAAC,GAAG;gBAClB,GAAG,CAAC,SAAS,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtD,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD,CAAC;QACJ,CAAC;QACD,8EAA8E;IAChF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,yBAAyB,GAAG,CAAC,EAAE,IAAI,EAAiB,EAAE,EAAE;IAC5D,OAAO,CACL,KAAC,eAAe,IAAC,EAAE,EAAC,MAAM,EAAC,SAAS,EAAC,QAAQ,YAC3C,KAAC,WAAW,IACV,SAAS,EAAC,aAAa,EACvB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,4BAC1C,EAAE,2BACF,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS,yBACjC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,SAAS,EAClD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EACrB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EACvB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GACvB,GACc,CACnB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,IAAI;IAChB,IAAI,EAAE,IAAI;IAEV,aAAa;QACX,OAAO;YACL,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YACxB,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;YACzB,KAAK,EAAE;gBACL,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CACrB,qBAAqB,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC3D,UAAU,EAAE,CAAC,UAAU,EAAE,EAAE,CACzB,UAAU,CAAC,KAAK;oBACd,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;oBACpD,CAAC,CAAC,EAAE;aACT;YACD,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YACvB,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;YAC5B,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YACxB,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YAC1B,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YAC1B,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YAC5B,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SAC5B,CAAC;IACJ,CAAC;IAED,SAAS;QACP,OAAO,CAAC,EAAE,GAAG,EAAE,qCAAqC,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,UAAU,CAAC,EAAE,cAAc,EAAE;QAC3B,OAAO;YACL,MAAM;YACN,eAAe,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,EAAE,cAAc,CAAC;SACtE,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;QAChC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACpC,sEAAsE;QACtE,8DAA8D;QAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,EAAE,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACnE,MAAM,QAAQ,GACZ,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YACnB,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBACnD,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC9D,CAAC;IAED,WAAW;QACT,OAAO,qBAAqB,CAAC,yBAAyB,CAAC,CAAC;IAC1D,CAAC;CACF,CAAC,CAAC"}
|
package/dist/composer/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { SkillReference } from "./extensions/SkillReference.js";
|
|
|
7
7
|
export { MentionReference } from "./extensions/MentionReference.js";
|
|
8
8
|
export { AgentComposerFrame, type AgentComposerFrameProps, } from "./AgentComposerFrame.js";
|
|
9
9
|
export { AgentSuggestionBar, agentSuggestionPrompt, normalizeAgentSuggestion, type AgentSuggestionBarProps, type AgentSuggestionInput, type AgentSuggestionItem, } from "./AgentSuggestionBar.js";
|
|
10
|
-
export { TiptapComposer, canSubmitComposerContent, displayableComposerModeMessage, getComposerSubmitIntentForEnterKey, findExactMentionItem, handleComposerFileDrop, isLocalRuntimeEngine, getOversizedDocumentAttachmentError, insertComposerHardBreakAndScrollIntoView, composerDraftSnapshot, sameComposerDraft, type ComposerDraftSnapshot, type ComposerSubmitIntent, type TiptapComposerHandle, type ComposerTextSelection, type TiptapComposerProps, type TiptapComposerSubmitOptions, } from "./TiptapComposer.js";
|
|
10
|
+
export { TiptapComposer, canSubmitComposerContent, displayableComposerModeMessage, getComposerSubmitIntentForEnterKey, findExactMentionItem, handleComposerFileDrop, isLocalRuntimeEngine, getOversizedDocumentAttachmentError, insertComposerHardBreakAndScrollIntoView, composerDraftSnapshot, sameComposerDraft, type ComposerDraftSnapshot, type ComposerSubmitIntent, type TiptapComposerHandle, type ComposerTextReference, type ComposerTextSelection, type TiptapComposerProps, type TiptapComposerSubmitOptions, } from "./TiptapComposer.js";
|
|
11
11
|
export { isClaudeCodeAgentId, isLunaModel, resolvePreferredAgentModel, type ComposerModelGroupLike, } from "./model-selection.js";
|
|
12
12
|
export { PromptComposer, type PromptComposerProps, type PromptComposerFile, type PromptComposerSubmitOptions, } from "./PromptComposer.js";
|
|
13
13
|
export { PromptBar, type PromptBarProps, type PromptBarSection, } from "./PromptBar.js";
|
|
@@ -17,6 +17,7 @@ export type { ComposerTerminalModeControl } from "./ComposerPlusMenu.js";
|
|
|
17
17
|
export { RealtimeVoiceModeDock, RealtimeVoiceModeEntry, type RealtimeVoiceModeCopy, type RealtimeVoiceModeDockProps, type RealtimeVoiceModeEntryProps, type RealtimeVoiceModeInlineSettings, type RealtimeVoiceModeSelectSetting, type RealtimeVoiceModeSettingOption, type RealtimeVoiceModeState, } from "./RealtimeVoiceMode.js";
|
|
18
18
|
export { createRealtimeVoiceSession, createRealtimeVoiceSessionWithCapability, executeRealtimeVoiceTool, extractRealtimeVoiceFunctionCalls, readRealtimeVoiceContext, readRealtimeVoiceContextWith, RealtimeVoiceModeBoundary, RealtimeVoiceModeProvider, useRealtimeVoiceMode, useRealtimeVoiceModeCopy, useRealtimeVoiceModeOptional, type RealtimeVoiceModeApi, type RealtimeVoiceModeProviderProps, type RealtimeVoiceSessionAnswer, type RealtimeVoiceToolResult, } from "./useRealtimeVoiceMode.js";
|
|
19
19
|
export { AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES, AGENT_PROMPT_MAX_INLINE_TEXT_CHARS, escapePromptAttachmentAttribute, formatPromptWithAttachments, isInlineableAgentPromptFile, readAgentPromptAttachment, type AgentPromptAttachment, type ReadAgentPromptAttachmentOptions, } from "./prompt-attachments.js";
|
|
20
|
+
export { MentionChip, type MentionChipProps } from "./MentionChip.js";
|
|
20
21
|
export { MentionPopover } from "./MentionPopover.js";
|
|
21
22
|
export { useMentionSearch } from "./use-mention-search.js";
|
|
22
23
|
export { ComposerRuntimeAdaptersProvider, useComposerRuntimeAdapters, type ComposerRuntimeAdapters, type ComposerTranslate, } from "./runtime-adapters.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composer/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composer/index.ts"],"names":[],"mappings":"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"}
|
package/dist/composer/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export { useEagerFileUploads } from "./use-eager-file-uploads.js";
|
|
|
15
15
|
export { RealtimeVoiceModeDock, RealtimeVoiceModeEntry, } from "./RealtimeVoiceMode.js";
|
|
16
16
|
export { createRealtimeVoiceSession, createRealtimeVoiceSessionWithCapability, executeRealtimeVoiceTool, extractRealtimeVoiceFunctionCalls, readRealtimeVoiceContext, readRealtimeVoiceContextWith, RealtimeVoiceModeBoundary, RealtimeVoiceModeProvider, useRealtimeVoiceMode, useRealtimeVoiceModeCopy, useRealtimeVoiceModeOptional, } from "./useRealtimeVoiceMode.js";
|
|
17
17
|
export { AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES, AGENT_PROMPT_MAX_INLINE_TEXT_CHARS, escapePromptAttachmentAttribute, formatPromptWithAttachments, isInlineableAgentPromptFile, readAgentPromptAttachment, } from "./prompt-attachments.js";
|
|
18
|
+
export { MentionChip } from "./MentionChip.js";
|
|
18
19
|
export { MentionPopover } from "./MentionPopover.js";
|
|
19
20
|
export { useMentionSearch } from "./use-mention-search.js";
|
|
20
21
|
export { ComposerRuntimeAdaptersProvider, useComposerRuntimeAdapters, } from "./runtime-adapters.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAG1B,6BAA6B,GAW9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,4BAA4B,EAC5B,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,GAE3B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EACL,kBAAkB,GAEnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,GAIzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,8BAA8B,EAC9B,kCAAkC,EAClC,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,mCAAmC,EACnC,wCAAwC,EACxC,qBAAqB,EACrB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAG1B,6BAA6B,GAW9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,4BAA4B,EAC5B,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,GAE3B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EACL,kBAAkB,GAEnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,GAIzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,8BAA8B,EAC9B,kCAAkC,EAClC,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,mCAAmC,EACnC,wCAAwC,EACxC,qBAAqB,EACrB,iBAAiB,GAQlB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,0BAA0B,GAE3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,GAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,SAAS,GAGV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,GAMnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GAQvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,0BAA0B,EAC1B,wCAAwC,EACxC,wBAAwB,EACxB,iCAAiC,EACjC,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,4BAA4B,GAK7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,2BAA2B,EAC3B,2BAA2B,EAC3B,yBAAyB,GAG1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,+BAA+B,EAC/B,0BAA0B,GAG3B,MAAM,uBAAuB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/toolkit",
|
|
3
|
-
"version": "0.209.
|
|
3
|
+
"version": "0.209.1-nightly-20261015005848",
|
|
4
4
|
"description": "Reusable app-building UI and helpers for Agent-Native apps.",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -678,7 +678,7 @@
|
|
|
678
678
|
"y-protocols": "^1.0.7",
|
|
679
679
|
"yjs": "^13.6.33",
|
|
680
680
|
"zod": "^4.3.6",
|
|
681
|
-
"@agent-native/agentkit": "^0.209.
|
|
681
|
+
"@agent-native/agentkit": "^0.209.1-nightly-20261015005848"
|
|
682
682
|
},
|
|
683
683
|
"devDependencies": {
|
|
684
684
|
"@excalidraw/excalidraw": "0.18.1",
|
|
@@ -702,10 +702,10 @@
|
|
|
702
702
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
703
703
|
"vite": "8.1.0",
|
|
704
704
|
"vitest": "^4.1.5",
|
|
705
|
-
"@agent-native/core": "^0.209.
|
|
705
|
+
"@agent-native/core": "^0.209.1-nightly-20261015005848"
|
|
706
706
|
},
|
|
707
707
|
"peerDependencies": {
|
|
708
|
-
"@agent-native/core": "
|
|
708
|
+
"@agent-native/core": "0.209.1-nightly-20261015005848",
|
|
709
709
|
"@excalidraw/excalidraw": ">=0.18",
|
|
710
710
|
"@excalidraw/mermaid-to-excalidraw": ">=2",
|
|
711
711
|
"@tanstack/react-query": "^5.99.2",
|
|
@@ -132,8 +132,11 @@ vi.mock("@agent-native/core/client/agent-chat", async (importOriginal) => {
|
|
|
132
132
|
await importOriginal<
|
|
133
133
|
typeof import("@agent-native/core/client/agent-chat")
|
|
134
134
|
>();
|
|
135
|
+
const sidebarState =
|
|
136
|
+
await import("../../../../core/src/client/agent-sidebar-state.js");
|
|
135
137
|
return {
|
|
136
138
|
...actual,
|
|
139
|
+
...sidebarState,
|
|
137
140
|
AGENT_CHAT_VIEW_TRANSITION_CLASS: "",
|
|
138
141
|
getAgentChatViewTransitionStyle: (style: React.CSSProperties) => style,
|
|
139
142
|
startAgentChatViewTransition: () => undefined,
|
|
@@ -189,10 +192,12 @@ function renderSidebar(
|
|
|
189
192
|
screenRefreshEnabled = true,
|
|
190
193
|
forceOverlay = false,
|
|
191
194
|
openOnChatRunning = false,
|
|
195
|
+
storageKey?: string,
|
|
196
|
+
strictMode = false,
|
|
192
197
|
) {
|
|
193
198
|
const render = (nextEnabled: boolean) => {
|
|
194
199
|
flushSync(() => {
|
|
195
|
-
|
|
200
|
+
const sidebar = (
|
|
196
201
|
<MemoryRouter>
|
|
197
202
|
<AgentSidebar
|
|
198
203
|
defaultOpen={defaultOpen}
|
|
@@ -202,10 +207,14 @@ function renderSidebar(
|
|
|
202
207
|
openOnChatRunning={openOnChatRunning}
|
|
203
208
|
position={position}
|
|
204
209
|
screenRefreshEnabled={screenRefreshEnabled}
|
|
210
|
+
storageKey={storageKey}
|
|
205
211
|
>
|
|
206
212
|
<div data-testid="app-content">App content</div>
|
|
207
213
|
</AgentSidebar>
|
|
208
|
-
</MemoryRouter
|
|
214
|
+
</MemoryRouter>
|
|
215
|
+
);
|
|
216
|
+
root?.render(
|
|
217
|
+
strictMode ? <React.StrictMode>{sidebar}</React.StrictMode> : sidebar,
|
|
209
218
|
);
|
|
210
219
|
});
|
|
211
220
|
};
|
|
@@ -216,6 +225,17 @@ function renderSidebar(
|
|
|
216
225
|
return render;
|
|
217
226
|
}
|
|
218
227
|
|
|
228
|
+
async function unmountSidebar() {
|
|
229
|
+
const mountedRoot = root;
|
|
230
|
+
const mountedContainer = container;
|
|
231
|
+
await act(async () => {
|
|
232
|
+
mountedRoot?.unmount();
|
|
233
|
+
});
|
|
234
|
+
mountedContainer?.remove();
|
|
235
|
+
root = undefined;
|
|
236
|
+
container = undefined;
|
|
237
|
+
}
|
|
238
|
+
|
|
219
239
|
afterEach(() => {
|
|
220
240
|
root?.unmount();
|
|
221
241
|
container?.remove();
|
|
@@ -234,6 +254,7 @@ beforeEach(() => {
|
|
|
234
254
|
window.history.replaceState({}, "", "/");
|
|
235
255
|
mockHostedHarness.configured = false;
|
|
236
256
|
mockHostedHarness.enabled = false;
|
|
257
|
+
window.sessionStorage.clear();
|
|
237
258
|
const values = new Map<string, string>();
|
|
238
259
|
vi.stubGlobal("localStorage", {
|
|
239
260
|
clear: () => values.clear(),
|
|
@@ -1834,6 +1855,322 @@ describe("AgentSidebar panel", () => {
|
|
|
1834
1855
|
},
|
|
1835
1856
|
);
|
|
1836
1857
|
|
|
1858
|
+
it("keeps a consumed explicit open hint across an enabled sidebar remount", async () => {
|
|
1859
|
+
await act(async () => {
|
|
1860
|
+
mockPanel.resolveImport();
|
|
1861
|
+
await mockPanel.importGate;
|
|
1862
|
+
});
|
|
1863
|
+
window.history.replaceState({}, "", "/overview?agentSidebar=open");
|
|
1864
|
+
const renderDispatchSidebar = (enabled = true) =>
|
|
1865
|
+
renderSidebar(
|
|
1866
|
+
false,
|
|
1867
|
+
undefined,
|
|
1868
|
+
false,
|
|
1869
|
+
enabled,
|
|
1870
|
+
true,
|
|
1871
|
+
false,
|
|
1872
|
+
false,
|
|
1873
|
+
"dispatch",
|
|
1874
|
+
);
|
|
1875
|
+
let setEnabled!: (nextEnabled: boolean) => void;
|
|
1876
|
+
await act(async () => {
|
|
1877
|
+
setEnabled = renderDispatchSidebar(false);
|
|
1878
|
+
});
|
|
1879
|
+
await act(async () => {});
|
|
1880
|
+
|
|
1881
|
+
expect(window.location.search).toBe("?agentSidebar=open");
|
|
1882
|
+
await act(async () => {
|
|
1883
|
+
setEnabled(true);
|
|
1884
|
+
});
|
|
1885
|
+
expect(window.location.search).toBe("");
|
|
1886
|
+
expect(localStorage.getItem("agent-native.dispatch.sidebar-open")).toBe(
|
|
1887
|
+
"true",
|
|
1888
|
+
);
|
|
1889
|
+
expect(
|
|
1890
|
+
container?.querySelector("[data-agent-sidebar-state='open']"),
|
|
1891
|
+
).toBeTruthy();
|
|
1892
|
+
expect(container?.querySelector("textarea")).toBeTruthy();
|
|
1893
|
+
|
|
1894
|
+
await unmountSidebar();
|
|
1895
|
+
|
|
1896
|
+
await act(async () => {
|
|
1897
|
+
renderDispatchSidebar();
|
|
1898
|
+
});
|
|
1899
|
+
const remountedRoot = root;
|
|
1900
|
+
const remountedContainer = container;
|
|
1901
|
+
try {
|
|
1902
|
+
await act(async () => {});
|
|
1903
|
+
|
|
1904
|
+
expect(
|
|
1905
|
+
container?.querySelector("[data-agent-sidebar-state='open']"),
|
|
1906
|
+
).toBeTruthy();
|
|
1907
|
+
expect(container?.querySelector("textarea")).toBeTruthy();
|
|
1908
|
+
await act(async () => {
|
|
1909
|
+
window.dispatchEvent(new CustomEvent("agent-panel:close"));
|
|
1910
|
+
});
|
|
1911
|
+
expect(
|
|
1912
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
1913
|
+
).toBeTruthy();
|
|
1914
|
+
} finally {
|
|
1915
|
+
await unmountSidebar();
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
await act(async () => {
|
|
1919
|
+
renderDispatchSidebar();
|
|
1920
|
+
});
|
|
1921
|
+
try {
|
|
1922
|
+
await act(async () => {});
|
|
1923
|
+
expect(
|
|
1924
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
1925
|
+
).toBeTruthy();
|
|
1926
|
+
expect(container?.querySelector("textarea")).toBeNull();
|
|
1927
|
+
} finally {
|
|
1928
|
+
await unmountSidebar();
|
|
1929
|
+
}
|
|
1930
|
+
});
|
|
1931
|
+
|
|
1932
|
+
it("keeps a manual close after a failed explicit-open storage write", async () => {
|
|
1933
|
+
await act(async () => {
|
|
1934
|
+
mockPanel.resolveImport();
|
|
1935
|
+
await mockPanel.importGate;
|
|
1936
|
+
});
|
|
1937
|
+
window.history.replaceState(
|
|
1938
|
+
{},
|
|
1939
|
+
"",
|
|
1940
|
+
"/overview?keep=1&agentSidebar=open#section",
|
|
1941
|
+
);
|
|
1942
|
+
const failedWrite = vi
|
|
1943
|
+
.spyOn(window.localStorage, "setItem")
|
|
1944
|
+
.mockImplementation(() => {
|
|
1945
|
+
throw new Error("local storage write denied");
|
|
1946
|
+
});
|
|
1947
|
+
const renderDispatchSidebar = () =>
|
|
1948
|
+
renderSidebar(
|
|
1949
|
+
false,
|
|
1950
|
+
undefined,
|
|
1951
|
+
false,
|
|
1952
|
+
true,
|
|
1953
|
+
true,
|
|
1954
|
+
false,
|
|
1955
|
+
false,
|
|
1956
|
+
"dispatch",
|
|
1957
|
+
);
|
|
1958
|
+
|
|
1959
|
+
try {
|
|
1960
|
+
await act(async () => {
|
|
1961
|
+
renderDispatchSidebar();
|
|
1962
|
+
});
|
|
1963
|
+
await act(async () => {});
|
|
1964
|
+
expect(failedWrite).toHaveBeenCalled();
|
|
1965
|
+
expect(window.location.search).toBe("?keep=1&agentSidebar=open");
|
|
1966
|
+
expect(
|
|
1967
|
+
container?.querySelector("[data-agent-sidebar-state='open']"),
|
|
1968
|
+
).toBeTruthy();
|
|
1969
|
+
|
|
1970
|
+
failedWrite.mockRestore();
|
|
1971
|
+
await act(async () => {
|
|
1972
|
+
window.dispatchEvent(new CustomEvent("agent-panel:close"));
|
|
1973
|
+
});
|
|
1974
|
+
expect(window.location.search).toBe("?keep=1");
|
|
1975
|
+
expect(window.location.hash).toBe("#section");
|
|
1976
|
+
expect(
|
|
1977
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
1978
|
+
).toBeTruthy();
|
|
1979
|
+
|
|
1980
|
+
await act(async () => {
|
|
1981
|
+
window.history.pushState({}, "", window.location.href);
|
|
1982
|
+
});
|
|
1983
|
+
expect(
|
|
1984
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
1985
|
+
).toBeTruthy();
|
|
1986
|
+
|
|
1987
|
+
await unmountSidebar();
|
|
1988
|
+
await act(async () => {
|
|
1989
|
+
renderDispatchSidebar();
|
|
1990
|
+
});
|
|
1991
|
+
try {
|
|
1992
|
+
await act(async () => {});
|
|
1993
|
+
expect(
|
|
1994
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
1995
|
+
).toBeTruthy();
|
|
1996
|
+
expect(container?.querySelector("textarea")).toBeNull();
|
|
1997
|
+
} finally {
|
|
1998
|
+
await unmountSidebar();
|
|
1999
|
+
}
|
|
2000
|
+
} finally {
|
|
2001
|
+
failedWrite.mockRestore();
|
|
2002
|
+
}
|
|
2003
|
+
});
|
|
2004
|
+
|
|
2005
|
+
it("keeps a manual close after consumed open intent cannot be cleared", async () => {
|
|
2006
|
+
await act(async () => {
|
|
2007
|
+
mockPanel.resolveImport();
|
|
2008
|
+
await mockPanel.importGate;
|
|
2009
|
+
});
|
|
2010
|
+
window.history.replaceState(
|
|
2011
|
+
{},
|
|
2012
|
+
"",
|
|
2013
|
+
"/overview?keep=1&agentSidebar=open#section",
|
|
2014
|
+
);
|
|
2015
|
+
const renderDispatchSidebar = () =>
|
|
2016
|
+
renderSidebar(
|
|
2017
|
+
false,
|
|
2018
|
+
undefined,
|
|
2019
|
+
false,
|
|
2020
|
+
true,
|
|
2021
|
+
true,
|
|
2022
|
+
false,
|
|
2023
|
+
false,
|
|
2024
|
+
"dispatch",
|
|
2025
|
+
);
|
|
2026
|
+
await act(async () => {
|
|
2027
|
+
renderDispatchSidebar();
|
|
2028
|
+
});
|
|
2029
|
+
expect(window.location.search).toBe("?keep=1");
|
|
2030
|
+
expect(
|
|
2031
|
+
container?.querySelector('[data-agent-sidebar-main-state="open"]'),
|
|
2032
|
+
).toBeTruthy();
|
|
2033
|
+
const deniedClear = vi
|
|
2034
|
+
.spyOn(window.sessionStorage, "removeItem")
|
|
2035
|
+
.mockImplementation(() => {
|
|
2036
|
+
throw new Error("session storage write denied");
|
|
2037
|
+
});
|
|
2038
|
+
const deniedPreference = vi
|
|
2039
|
+
.spyOn(window.localStorage, "setItem")
|
|
2040
|
+
.mockImplementation(() => {
|
|
2041
|
+
throw new Error("local storage write denied");
|
|
2042
|
+
});
|
|
2043
|
+
try {
|
|
2044
|
+
await act(async () => {
|
|
2045
|
+
window.dispatchEvent(new CustomEvent("agent-panel:close"));
|
|
2046
|
+
});
|
|
2047
|
+
expect(window.location.search).toBe("?keep=1&agentSidebar=closed");
|
|
2048
|
+
expect(window.location.hash).toBe("#section");
|
|
2049
|
+
await unmountSidebar();
|
|
2050
|
+
await act(async () => {
|
|
2051
|
+
renderDispatchSidebar();
|
|
2052
|
+
});
|
|
2053
|
+
await act(async () => {});
|
|
2054
|
+
expect(
|
|
2055
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
2056
|
+
).toBeTruthy();
|
|
2057
|
+
expect(container?.querySelector("textarea")).toBeNull();
|
|
2058
|
+
} finally {
|
|
2059
|
+
deniedClear.mockRestore();
|
|
2060
|
+
deniedPreference.mockRestore();
|
|
2061
|
+
await unmountSidebar();
|
|
2062
|
+
}
|
|
2063
|
+
});
|
|
2064
|
+
|
|
2065
|
+
it("lets a user reopen after a denied close leaves a closed URL hint", async () => {
|
|
2066
|
+
await act(async () => {
|
|
2067
|
+
mockPanel.resolveImport();
|
|
2068
|
+
await mockPanel.importGate;
|
|
2069
|
+
});
|
|
2070
|
+
window.history.replaceState(
|
|
2071
|
+
{},
|
|
2072
|
+
"",
|
|
2073
|
+
"/overview?keep=1&agentSidebar=open#section",
|
|
2074
|
+
);
|
|
2075
|
+
const failedWrite = vi
|
|
2076
|
+
.spyOn(window.localStorage, "setItem")
|
|
2077
|
+
.mockImplementation(() => {
|
|
2078
|
+
throw new Error("local storage write denied");
|
|
2079
|
+
});
|
|
2080
|
+
const renderDispatchSidebar = () =>
|
|
2081
|
+
renderSidebar(
|
|
2082
|
+
false,
|
|
2083
|
+
undefined,
|
|
2084
|
+
false,
|
|
2085
|
+
true,
|
|
2086
|
+
true,
|
|
2087
|
+
false,
|
|
2088
|
+
false,
|
|
2089
|
+
"dispatch",
|
|
2090
|
+
);
|
|
2091
|
+
|
|
2092
|
+
try {
|
|
2093
|
+
await act(async () => {
|
|
2094
|
+
renderDispatchSidebar();
|
|
2095
|
+
});
|
|
2096
|
+
await act(async () => {});
|
|
2097
|
+
expect(window.location.search).toBe("?keep=1&agentSidebar=open");
|
|
2098
|
+
expect(
|
|
2099
|
+
container?.querySelector("[data-agent-sidebar-state='open']"),
|
|
2100
|
+
).toBeTruthy();
|
|
2101
|
+
|
|
2102
|
+
await act(async () => {
|
|
2103
|
+
window.dispatchEvent(new CustomEvent("agent-panel:close"));
|
|
2104
|
+
});
|
|
2105
|
+
expect(window.location.search).toBe("?keep=1&agentSidebar=closed");
|
|
2106
|
+
expect(
|
|
2107
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
2108
|
+
).toBeTruthy();
|
|
2109
|
+
|
|
2110
|
+
failedWrite.mockRestore();
|
|
2111
|
+
await act(async () => {
|
|
2112
|
+
window.dispatchEvent(new CustomEvent("agent-panel:open"));
|
|
2113
|
+
});
|
|
2114
|
+
expect(window.location.search).toBe("?keep=1");
|
|
2115
|
+
expect(window.location.hash).toBe("#section");
|
|
2116
|
+
expect(
|
|
2117
|
+
container?.querySelector('[data-agent-sidebar-main-state="open"]'),
|
|
2118
|
+
).toBeTruthy();
|
|
2119
|
+
expect(localStorage.getItem("agent-native.dispatch.sidebar-open")).toBe(
|
|
2120
|
+
"true",
|
|
2121
|
+
);
|
|
2122
|
+
|
|
2123
|
+
await unmountSidebar();
|
|
2124
|
+
await act(async () => {
|
|
2125
|
+
renderDispatchSidebar();
|
|
2126
|
+
});
|
|
2127
|
+
await act(async () => {});
|
|
2128
|
+
expect(
|
|
2129
|
+
container?.querySelector('[data-agent-sidebar-main-state="open"]'),
|
|
2130
|
+
).toBeTruthy();
|
|
2131
|
+
} finally {
|
|
2132
|
+
failedWrite.mockRestore();
|
|
2133
|
+
await unmountSidebar();
|
|
2134
|
+
}
|
|
2135
|
+
});
|
|
2136
|
+
|
|
2137
|
+
it("persists consecutive toggles once each under StrictMode", async () => {
|
|
2138
|
+
const renderStrictDispatchSidebar = () =>
|
|
2139
|
+
renderSidebar(
|
|
2140
|
+
false,
|
|
2141
|
+
undefined,
|
|
2142
|
+
false,
|
|
2143
|
+
true,
|
|
2144
|
+
true,
|
|
2145
|
+
false,
|
|
2146
|
+
false,
|
|
2147
|
+
"dispatch",
|
|
2148
|
+
true,
|
|
2149
|
+
);
|
|
2150
|
+
await act(async () => {
|
|
2151
|
+
renderStrictDispatchSidebar();
|
|
2152
|
+
});
|
|
2153
|
+
const writePreference = vi.spyOn(window.localStorage, "setItem");
|
|
2154
|
+
|
|
2155
|
+
try {
|
|
2156
|
+
await act(async () => {
|
|
2157
|
+
window.dispatchEvent(new CustomEvent("agent-panel:toggle"));
|
|
2158
|
+
window.dispatchEvent(new CustomEvent("agent-panel:toggle"));
|
|
2159
|
+
});
|
|
2160
|
+
|
|
2161
|
+
expect(
|
|
2162
|
+
container?.querySelector('[data-agent-sidebar-main-state="closed"]'),
|
|
2163
|
+
).toBeTruthy();
|
|
2164
|
+
expect(localStorage.getItem("agent-native.dispatch.sidebar-open")).toBe(
|
|
2165
|
+
"false",
|
|
2166
|
+
);
|
|
2167
|
+
expect(writePreference).toHaveBeenCalledTimes(2);
|
|
2168
|
+
} finally {
|
|
2169
|
+
writePreference.mockRestore();
|
|
2170
|
+
await unmountSidebar();
|
|
2171
|
+
}
|
|
2172
|
+
});
|
|
2173
|
+
|
|
1837
2174
|
it("keeps an explicit URL close ahead of a thread link", async () => {
|
|
1838
2175
|
window.history.replaceState(
|
|
1839
2176
|
{},
|
|
@@ -485,6 +485,7 @@ export function AgentSidebar({
|
|
|
485
485
|
ignoreUrlOverride: !enabled,
|
|
486
486
|
}),
|
|
487
487
|
);
|
|
488
|
+
const openRef = useRef(open);
|
|
488
489
|
const [presentationMode, setPresentationMode] = useState(false);
|
|
489
490
|
const [width, setWidth] = useState(initialWidth);
|
|
490
491
|
const [isWideDrawer, setIsWideDrawer] = useState(() => {
|
|
@@ -542,16 +543,22 @@ export function AgentSidebar({
|
|
|
542
543
|
[],
|
|
543
544
|
);
|
|
544
545
|
|
|
546
|
+
const setOpenCurrent = useCallback(
|
|
547
|
+
(next: boolean | ((prev: boolean) => boolean)) => {
|
|
548
|
+
const value = typeof next === "function" ? next(openRef.current) : next;
|
|
549
|
+
openRef.current = value;
|
|
550
|
+
setOpen(value);
|
|
551
|
+
return value;
|
|
552
|
+
},
|
|
553
|
+
[],
|
|
554
|
+
);
|
|
545
555
|
const setOpenPersisted = useCallback(
|
|
546
556
|
(next: boolean | ((prev: boolean) => boolean)) => {
|
|
547
557
|
if (!enabled) return;
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
setAgentSidebarOpenPreference(value, sidebarOpenStorageKey);
|
|
551
|
-
return value;
|
|
552
|
-
});
|
|
558
|
+
const value = setOpenCurrent(next);
|
|
559
|
+
setAgentSidebarOpenPreference(value, sidebarOpenStorageKey);
|
|
553
560
|
},
|
|
554
|
-
[enabled, sidebarOpenStorageKey],
|
|
561
|
+
[enabled, setOpenCurrent, sidebarOpenStorageKey],
|
|
555
562
|
);
|
|
556
563
|
|
|
557
564
|
useEffect(() => {
|
|
@@ -598,8 +605,10 @@ export function AgentSidebar({
|
|
|
598
605
|
}, [applyUrlOpenOverride, enabled]);
|
|
599
606
|
|
|
600
607
|
useEffect(() => {
|
|
601
|
-
if (enabled && openOnChatRunning && !isPerAppChatHosted)
|
|
602
|
-
|
|
608
|
+
if (enabled && openOnChatRunning && !isPerAppChatHosted) {
|
|
609
|
+
setOpenCurrent(true);
|
|
610
|
+
}
|
|
611
|
+
}, [enabled, isPerAppChatHosted, openOnChatRunning, setOpenCurrent]);
|
|
603
612
|
|
|
604
613
|
const [frameCodeMode, setFrameCodeMode] = useState(() =>
|
|
605
614
|
shouldParentFrameOwnAgentPanel(),
|
|
@@ -1011,7 +1020,7 @@ export function AgentSidebar({
|
|
|
1011
1020
|
: "__default__";
|
|
1012
1021
|
|
|
1013
1022
|
if (detail?.isRunning === true) {
|
|
1014
|
-
if (openOnChatRunning && !isPerAppChatHosted)
|
|
1023
|
+
if (openOnChatRunning && !isPerAppChatHosted) setOpenCurrent(true);
|
|
1015
1024
|
setRunningTabIds((prev) => {
|
|
1016
1025
|
const next = new Set(prev);
|
|
1017
1026
|
next.add(tabId);
|
|
@@ -1037,7 +1046,13 @@ export function AgentSidebar({
|
|
|
1037
1046
|
window.removeEventListener(AGENT_PANEL_PREPARE_EVENT, preparePanel);
|
|
1038
1047
|
window.removeEventListener(AGENT_CHAT_RUNNING_EVENT, handleChatRunning);
|
|
1039
1048
|
};
|
|
1040
|
-
}, [
|
|
1049
|
+
}, [
|
|
1050
|
+
enabled,
|
|
1051
|
+
isPerAppChatHosted,
|
|
1052
|
+
openOnChatRunning,
|
|
1053
|
+
setOpenCurrent,
|
|
1054
|
+
setOpenPersisted,
|
|
1055
|
+
]);
|
|
1041
1056
|
|
|
1042
1057
|
// Child composers announce readiness in passive effects, including ownership remounts.
|
|
1043
1058
|
useLayoutEffect(() => {
|
|
@@ -150,4 +150,29 @@ describe("InlineMarkdown", () => {
|
|
|
150
150
|
expect(container.querySelector("em")?.textContent).toBe("after");
|
|
151
151
|
expect(container.querySelector("p")).toBeNull();
|
|
152
152
|
});
|
|
153
|
+
|
|
154
|
+
it("protects overlapping spans once each, at their own occurrences", () => {
|
|
155
|
+
const content = "@Sam Lee and @Sam, not @Sam here";
|
|
156
|
+
act(() => {
|
|
157
|
+
root.render(
|
|
158
|
+
<InlineMarkdown
|
|
159
|
+
content={content}
|
|
160
|
+
inline
|
|
161
|
+
protectedSpans={[
|
|
162
|
+
{ source: "@Sam", label: "@Sam", at: content.indexOf("@Sam,") },
|
|
163
|
+
{ source: "@Sam Lee", label: "@Sam Lee" },
|
|
164
|
+
]}
|
|
165
|
+
renderProtectedSpan={(span, children) => (
|
|
166
|
+
<mark data-protected={span.label}>{children}</mark>
|
|
167
|
+
)}
|
|
168
|
+
/>,
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
expect(
|
|
173
|
+
[...container.querySelectorAll("mark")].map((mark) => mark.textContent),
|
|
174
|
+
).toEqual(["@Sam Lee", "@Sam"]);
|
|
175
|
+
expect(container.querySelector("a")).toBeNull();
|
|
176
|
+
expect(container.textContent).toBe(content);
|
|
177
|
+
});
|
|
153
178
|
});
|