@feedmepos/mf-miniprogram-v2 0.1.0-dev.4 → 0.1.0-dev.40

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 (36) hide show
  1. package/dist/ControlPlaneView-DcNJs7QW.js +19228 -0
  2. package/dist/app.js +1 -1
  3. package/dist/package.json +4 -2
  4. package/dist/src/api/controlPlane.d.ts +3 -1
  5. package/dist/src/components/AnnotationColorField.vue.d.ts +14 -0
  6. package/dist/src/components/AnnotationMessage.vue.d.ts +8 -0
  7. package/dist/src/components/AnnotationPropertyPanel.vue.d.ts +32 -0
  8. package/dist/src/components/AnnotationStyleControl.vue.d.ts +14 -0
  9. package/dist/src/components/BrandKitPanel.vue.d.ts +9 -0
  10. package/dist/src/components/BrandKitProposalCard.vue.d.ts +7 -0
  11. package/dist/src/components/ChatTextPart.vue.d.ts +6 -0
  12. package/dist/src/components/DiffCard.vue.d.ts +9 -0
  13. package/dist/src/components/MarkdownContent.vue.d.ts +6 -0
  14. package/dist/src/components/MessageItem.vue.d.ts +7 -1
  15. package/dist/src/components/QuestionPrompt.vue.d.ts +16 -0
  16. package/dist/src/components/StatusBadge.vue.d.ts +21 -0
  17. package/dist/src/components/ToolCallGroup.vue.d.ts +11 -0
  18. package/dist/src/composables/annotationEditing.d.ts +130 -0
  19. package/dist/src/composables/annotationTray.d.ts +73 -0
  20. package/dist/src/composables/brandkitProposal.d.ts +14 -0
  21. package/dist/src/composables/imageAttachments.d.ts +23 -0
  22. package/dist/src/composables/latestPoller.d.ts +14 -0
  23. package/dist/src/composables/localPreference.d.ts +10 -0
  24. package/dist/src/composables/previewAnnotations.d.ts +38 -0
  25. package/dist/src/composables/promptQueue.d.ts +20 -0
  26. package/dist/src/composables/questionAnswers.d.ts +4 -0
  27. package/dist/src/composables/status.d.ts +11 -0
  28. package/dist/src/composables/types.d.ts +109 -4
  29. package/dist/src/composables/useAgentBridge.d.ts +35 -0
  30. package/dist/src/composables/useBrandKit.d.ts +45 -0
  31. package/dist/src/composables/useChat.d.ts +181 -2
  32. package/dist/src/composables/useIdleSuspend.d.ts +6 -0
  33. package/dist/src/composables/useProject.d.ts +108 -26
  34. package/dist/style.css +1 -1
  35. package/package.json +4 -2
  36. package/dist/ControlPlaneView-CYpEC-C4.js +0 -9487
package/dist/app.js CHANGED
@@ -3,7 +3,7 @@ const n = [
3
3
  {
4
4
  path: "/",
5
5
  name: "miniprogram-v2-control",
6
- component: () => import("./ControlPlaneView-CYpEC-C4.js")
6
+ component: () => import("./ControlPlaneView-DcNJs7QW.js")
7
7
  },
8
8
  {
9
9
  path: "/:pathMatch(.*)*",
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feedmepos/mf-miniprogram-v2",
3
- "version": "0.1.0-dev.4",
3
+ "version": "0.1.0-dev.40",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -23,6 +23,7 @@
23
23
  "build": "npm run type-check && npm run build-only:dev",
24
24
  "build:prod": "npm run type-check && npm run build-only:prod",
25
25
  "preview": "vite preview",
26
+ "test": "node --test src/components/*.test.mjs src/composables/*.test.mjs",
26
27
  "type-check": "vue-tsc --build --force",
27
28
  "typecheck": "npm run type-check",
28
29
  "build:mf:dev": "vite build --mode fmmf:dev",
@@ -38,7 +39,8 @@
38
39
  "dependencies": {
39
40
  "@feedmepos/mf-common": "^1.27.9",
40
41
  "@feedmepos/ui-library": "1.8.4",
41
- "@opencode-ai/sdk": "*",
42
+ "@opencode-ai/sdk": "1.17.14",
43
+ "diff": "^9.0.0",
42
44
  "dompurify": "^3.4.11",
43
45
  "highlight.js": "^11.11.1",
44
46
  "marked": "^18.0.5",
@@ -12,10 +12,12 @@ export declare function controlPlaneBaseUrl(): string;
12
12
  export declare function controlPlaneUrl(path: string): string;
13
13
  export declare function currentBusiness(): MaybeBusiness | undefined;
14
14
  export declare function currentBusinessId(): string;
15
- export declare function currentBusinessLabel(): string;
16
15
  export declare function currentBusinessSlug(): string | undefined;
17
16
  export declare function currentBusinessName(): string;
18
17
  export declare function currentBusinessCountry(): string | undefined;
18
+ export declare function currentBusinessLiveUrl(): string;
19
+ export declare function sleep(ms: number): Promise<unknown>;
20
+ export declare function errorMessage(error: unknown): string;
19
21
  export declare function controlPlaneAuthorizationHeader(): Promise<string | null>;
20
22
  export declare function authorizedFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
21
23
  export declare function controlPlaneFetch<T>(path: string, init?: RequestInit): Promise<T>;
@@ -0,0 +1,14 @@
1
+ import { type BrandKitPreset } from '../composables/annotationEditing';
2
+ type __VLS_Props = {
3
+ value: string;
4
+ label: string;
5
+ presets: BrandKitPreset[];
6
+ disabled?: boolean;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ update: (args_0: string) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ onUpdate?: ((args_0: string) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import type { PreviewAnnotationItem } from '../composables/previewAnnotations';
2
+ type __VLS_Props = {
3
+ items: PreviewAnnotationItem[];
4
+ text?: string;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
@@ -0,0 +1,32 @@
1
+ import { type AnnotationStyleKey, type BrandKitPreset } from '../composables/annotationEditing';
2
+ import type { PreviewBridgeElement } from '../composables/types';
3
+ type __VLS_Props = {
4
+ element: PreviewBridgeElement;
5
+ values: Record<string, string>;
6
+ beforeValues: Record<string, string>;
7
+ textValue: string;
8
+ beforeText: string;
9
+ presets: BrandKitPreset[];
10
+ disabled?: boolean;
11
+ };
12
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
+ reset: (args_0: {
14
+ key: AnnotationStyleKey | "text";
15
+ }) => any;
16
+ change: (args_0: {
17
+ key: AnnotationStyleKey | "text";
18
+ value: string;
19
+ }) => any;
20
+ resetAll: () => any;
21
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
22
+ onReset?: ((args_0: {
23
+ key: AnnotationStyleKey | "text";
24
+ }) => any) | undefined;
25
+ onChange?: ((args_0: {
26
+ key: AnnotationStyleKey | "text";
27
+ value: string;
28
+ }) => any) | undefined;
29
+ onResetAll?: (() => any) | undefined;
30
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ declare const _default: typeof __VLS_export;
32
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { type AnnotationFieldSpec, type BrandKitPreset } from '../composables/annotationEditing';
2
+ type __VLS_Props = {
3
+ spec: AnnotationFieldSpec;
4
+ value: string;
5
+ fontPresets: BrandKitPreset[];
6
+ disabled?: boolean;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ update: (args_0: string) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ onUpdate?: ((args_0: string) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -0,0 +1,9 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
2
+ close: () => any;
3
+ saved: () => any;
4
+ }, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
5
+ onClose?: (() => any) | undefined;
6
+ onSaved?: (() => any) | undefined;
7
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import type { BrandKitProposal } from '../composables/brandkitProposal';
2
+ type __VLS_Props = {
3
+ proposal: BrandKitProposal;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ text: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import type { ChatMessage } from '../composables/types';
2
+ type __VLS_Props = {
3
+ files: string[];
4
+ diffs: ChatMessage['diffs'];
5
+ loading?: boolean;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ text: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -1,7 +1,13 @@
1
1
  import type { ChatMessage } from '../composables/types';
2
2
  type __VLS_Props = {
3
3
  message: ChatMessage;
4
+ canUndo?: boolean;
5
+ undoing?: boolean;
4
6
  };
5
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
8
+ undo: () => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onUndo?: (() => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
12
  declare const _default: typeof __VLS_export;
7
13
  export default _default;
@@ -0,0 +1,16 @@
1
+ import type { QuestionAnswer, QuestionRequest } from '@opencode-ai/sdk/v2/client';
2
+ type __VLS_Props = {
3
+ request: QuestionRequest;
4
+ submitting?: boolean;
5
+ error?: string | null;
6
+ pendingCount?: number;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
9
+ reply: (requestID: string, answers: QuestionAnswer[]) => any;
10
+ reject: (requestID: string) => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ onReply?: ((requestID: string, answers: QuestionAnswer[]) => any) | undefined;
13
+ onReject?: ((requestID: string) => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import type { BadgeVariant } from '../composables/status';
2
+ type __VLS_Props = {
3
+ variant?: BadgeVariant;
4
+ size?: 'sm' | 'md';
5
+ };
6
+ declare var __VLS_1: {};
7
+ type __VLS_Slots = {} & {
8
+ default?: (props: typeof __VLS_1) => any;
9
+ };
10
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
11
+ size: "sm" | "md";
12
+ variant: BadgeVariant;
13
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,11 @@
1
+ import type { ChatPart } from '../composables/types';
2
+ type ToolPart = Extract<ChatPart, {
3
+ kind: 'tool';
4
+ }>;
5
+ type __VLS_Props = {
6
+ parts: ToolPart[];
7
+ busy: boolean;
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ declare const _default: typeof __VLS_export;
11
+ export default _default;
@@ -0,0 +1,130 @@
1
+ import type { PreviewBridgeElement } from './types';
2
+ export type AnnotationStyleKey = 'color' | 'backgroundColor' | 'borderColor' | 'opacity' | 'fontFamily' | 'fontSize' | 'fontWeight' | 'lineHeight' | 'letterSpacing' | 'textAlign' | 'borderRadius' | 'borderWidth' | 'width' | 'height' | 'padding' | 'margin' | 'objectFit' | 'aspectRatio' | 'fill' | 'stroke' | 'display' | 'gap' | 'justifyContent' | 'alignItems';
3
+ /** Which editor a property gets. The bridge validates every value with
4
+ * `CSS.supports` and rejects the whole patch on a miss, so controls must only
5
+ * ever emit complete values — never the intermediate state of a keystroke. */
6
+ export type AnnotationControlKind = 'color' | 'length' | 'ratio' | 'choice' | 'align' | 'font' | 'box';
7
+ export interface AnnotationChoice {
8
+ value: string;
9
+ label: string;
10
+ icon?: string;
11
+ /** Computed styles serialize logical alignment as `start`/`end`. Treating those
12
+ * as the physical choice keeps the segment highlighted instead of showing an
13
+ * unset control, and avoids emitting a no-op `start → left` diff. */
14
+ aliases?: readonly string[];
15
+ }
16
+ export interface AnnotationFieldSpec {
17
+ key: AnnotationStyleKey;
18
+ label: string;
19
+ control: AnnotationControlKind;
20
+ units?: readonly string[];
21
+ /** Non-numeric values the property accepts (`auto`, `normal`). Offered in the
22
+ * unit dropdown so the numeric input can stay a number input. */
23
+ keywords?: readonly string[];
24
+ min?: number;
25
+ max?: number;
26
+ step?: number;
27
+ options?: readonly AnnotationChoice[];
28
+ /** One-click common values, offered next to the numeric input. */
29
+ presets?: readonly string[];
30
+ }
31
+ /** Order is load-bearing: it decides the order of `property before → after`
32
+ * lines in the agent prompt. */
33
+ export declare const ANNOTATION_FIELD_SPECS: readonly AnnotationFieldSpec[];
34
+ export declare function annotationFieldSpec(key: AnnotationStyleKey): AnnotationFieldSpec;
35
+ export interface AnnotationSection {
36
+ key: string;
37
+ label: string;
38
+ keys: readonly AnnotationStyleKey[];
39
+ /** Layout properties are the least-used and the most likely to break the
40
+ * preview, so they stay folded until asked for. */
41
+ defaultOpen: boolean;
42
+ }
43
+ export declare const ANNOTATION_SECTIONS: readonly AnnotationSection[];
44
+ export type AnnotationElementKind = 'media' | 'text' | 'container' | 'control';
45
+ /** Which family of controls the element deserves. Deliberately a heuristic used
46
+ * only to order and pre-collapse sections — never to remove a control — because
47
+ * a `<span style="display:block">` or a div used purely as a label would
48
+ * otherwise lose the properties it actually needs. */
49
+ export declare function annotationElementKind(element: PreviewBridgeElement | null): AnnotationElementKind;
50
+ /** Sections ordered for the element, with the relevant ones expanded. */
51
+ export declare function annotationSectionsFor(kind: AnnotationElementKind): AnnotationSection[];
52
+ /** CSS ignores width, height and vertical padding on a non-replaced inline box.
53
+ * The control still works, so this only feeds a tooltip — silently doing
54
+ * nothing is what makes the panel feel broken. */
55
+ export declare function ignoredOnInline(element: PreviewBridgeElement | null, key: AnnotationStyleKey): boolean;
56
+ export interface AnnotationStyleDiff {
57
+ property: AnnotationStyleKey;
58
+ before: string;
59
+ after: string;
60
+ /** BrandKit token the new value came from, when it came from one. Carried into
61
+ * the prompt so the agent reaches for the token instead of hardcoding the
62
+ * literal value it happens to resolve to today. */
63
+ token?: string;
64
+ }
65
+ export interface BrandKitPreset {
66
+ key: string;
67
+ label: string;
68
+ value: string;
69
+ kind: 'color' | 'font';
70
+ }
71
+ export declare function sanitizeAnnotationValue(value: unknown): string;
72
+ /** Hex form for display and for `<input type="color">`. Fully transparent
73
+ * colors have no meaningful hex, so they read as "no color" instead. */
74
+ export declare function normalizeCssColor(value: string | undefined | null): string | null;
75
+ export declare function sameCssColor(a: string | undefined, b: string | undefined): boolean;
76
+ export interface CssLength {
77
+ value: number;
78
+ unit: string;
79
+ }
80
+ export declare function parseCssLength(value: string | undefined | null): CssLength | null;
81
+ export declare function formatCssLength(value: number, unit: string): string;
82
+ export interface CssBox {
83
+ top: string;
84
+ right: string;
85
+ bottom: string;
86
+ left: string;
87
+ }
88
+ /** Expands a 1–4 token padding/margin shorthand. Returns null for anything with
89
+ * `calc()` or keywords so the caller can fall back to raw text editing. */
90
+ export declare function parseCssBox(value: string | undefined | null): CssBox | null;
91
+ export declare function formatCssBox(box: CssBox): string;
92
+ export declare function annotationStyleValues(element: PreviewBridgeElement | null): Record<AnnotationStyleKey, string>;
93
+ export declare function changedStyleKeys(before: Record<string, string>, after: Record<string, string>): AnnotationStyleKey[];
94
+ export interface StyleOverridePatch {
95
+ styles: Record<string, string>;
96
+ appliedKeys: AnnotationStyleKey[];
97
+ }
98
+ /** Builds the temporary-override message for the preview bridge. Only changed
99
+ * properties are pushed: sending the whole computed set would inline
100
+ * width/height/padding onto the element and pin the layout it inherited from
101
+ * source, so an unrelated edit could visibly break it. A property the user
102
+ * reverted is sent as an empty value, which tells the bridge to drop the
103
+ * override instead of leaving the last one stuck on the element. */
104
+ export declare function buildStyleOverridePatch(before: Record<string, string>, draft: Record<string, string>, appliedKeys: readonly AnnotationStyleKey[]): StyleOverridePatch;
105
+ export declare function buildAnnotationStyleDiff(before: Record<string, string>, after: Record<string, string>, presets?: readonly BrandKitPreset[]): AnnotationStyleDiff[];
106
+ export declare function brandKitPresets(colors: Record<string, string>, fonts: Record<string, string>, labels: {
107
+ colors: Record<string, string>;
108
+ fonts: Record<string, string>;
109
+ }): BrandKitPreset[];
110
+ /** An `<img>` reports no nearby text, so without its src and alt the agent is
111
+ * told only that "some image" changed and has to guess which file — the failure
112
+ * mode being an invented asset path that breaks the build. */
113
+ export declare function annotationAssetContext(element: PreviewBridgeElement | null): string | null;
114
+ export declare function serializeAnnotationPrompt(input: {
115
+ id: number;
116
+ route: string;
117
+ device: string;
118
+ element: PreviewBridgeElement | null;
119
+ note: string;
120
+ styleDiffs: AnnotationStyleDiff[];
121
+ textBefore?: string;
122
+ textAfter?: string;
123
+ /** Images the user attached to this marker. One message carries every
124
+ * annotation, so the filename prefix is what pairs a saved upload with the
125
+ * marker it was dropped on. */
126
+ attachments?: {
127
+ count: number;
128
+ prefix: string;
129
+ };
130
+ }): string;
@@ -0,0 +1,73 @@
1
+ import type { OutgoingAttachment } from './types';
2
+ import type { PreviewAnnotationItem } from './previewAnnotations';
3
+ /**
4
+ * Staging area shared by the preview panel, which places markers, and the chat
5
+ * composer, which sends them.
6
+ *
7
+ * Annotations used to pile up in a list beside the preview and were sent from
8
+ * there. That split the conversation in two — you asked in one place and read
9
+ * the answer in another — and a stack of open note cards buried the preview it
10
+ * was annotating. A marker now lands in the composer as a chip the moment it is
11
+ * placed, so one Send carries the typed message together with every marker, and
12
+ * the preview panel only ever shows the one marker being edited.
13
+ *
14
+ * Only a flat summary lives here. The annotation itself — its inspected element,
15
+ * temporary style overrides, attached images — stays in the preview panel,
16
+ * because that is the only place that can revert an override inside the iframe.
17
+ * The panel registers a controller so the composer can act on a chip without
18
+ * owning any of that state.
19
+ */
20
+ /** What the composer needs to render one staged marker. */
21
+ export interface AnnotationChip {
22
+ id: number;
23
+ /** Human label for the annotated element, e.g. `<button> “Order now”`. */
24
+ label: string;
25
+ note: string;
26
+ changeCount: number;
27
+ attachmentCount: number;
28
+ /** The element is still being inspected; the chip is sendable either way. */
29
+ pending: boolean;
30
+ }
31
+ export interface StagedAnnotations {
32
+ /** Agent-facing prose, one block per marker. */
33
+ blocks: string;
34
+ items: PreviewAnnotationItem[];
35
+ files: OutgoingAttachment[];
36
+ }
37
+ export interface AnnotationTrayController {
38
+ /** Reopens a marker in the preview panel's editor. */
39
+ focus(id: number): void;
40
+ /** Drops a marker and reverts its temporary overrides in the preview. */
41
+ remove(id: number): void;
42
+ clear(): void;
43
+ build(): StagedAnnotations | null;
44
+ }
45
+ export declare function useAnnotationTray(): {
46
+ chips: import("vue").Ref<{
47
+ id: number;
48
+ label: string;
49
+ note: string;
50
+ changeCount: number;
51
+ attachmentCount: number;
52
+ pending: boolean;
53
+ }[], AnnotationChip[] | {
54
+ id: number;
55
+ label: string;
56
+ note: string;
57
+ changeCount: number;
58
+ attachmentCount: number;
59
+ pending: boolean;
60
+ }[]>;
61
+ attachmentCount: import("vue").ComputedRef<number>;
62
+ annotationAttachments: import("vue").ComputedRef<number>;
63
+ composerAttachments: import("vue").Ref<number, number>;
64
+ setChips(next: AnnotationChip[]): void;
65
+ setComposerAttachmentCount(count: number): void;
66
+ /** Called by the preview panel on mount, and with null on unmount — nothing
67
+ * staged can be sent once the panel that owns it is gone. */
68
+ connect(next: AnnotationTrayController | null): void;
69
+ focus(id: number): void;
70
+ remove(id: number): void;
71
+ clear(): void;
72
+ build(): StagedAnnotations | null;
73
+ };
@@ -0,0 +1,14 @@
1
+ export interface BrandKitProposal {
2
+ name?: string;
3
+ colors: Record<string, string>;
4
+ fonts: Record<string, string>;
5
+ }
6
+ export type ChatSegment = {
7
+ kind: 'markdown';
8
+ text: string;
9
+ } | {
10
+ kind: 'proposal';
11
+ proposal: BrandKitProposal;
12
+ };
13
+ export declare function parseBrandKitProposal(json: string): BrandKitProposal | null;
14
+ export declare function splitBrandKitProposals(text: string): ChatSegment[] | null;
@@ -0,0 +1,23 @@
1
+ import type { OutgoingAttachment } from './types';
2
+ export interface PendingImage extends OutgoingAttachment {
3
+ id: string;
4
+ }
5
+ export declare const ACCEPTED_IMAGE_MIME: Set<string>;
6
+ export declare const MAX_ATTACHMENT_BYTES: number;
7
+ export declare const MAX_ATTACHMENTS = 4;
8
+ export declare function readAsDataUrl(file: File): Promise<string>;
9
+ export declare function imageFilesFromPaste(event: ClipboardEvent): File[];
10
+ export declare function imageFilesFromDrop(event: DragEvent): File[];
11
+ /** Reads files into pending attachments. Returns rather than mutates so each
12
+ * caller keeps ownership of its own list (the chat has one, an annotation has
13
+ * one per marker). */
14
+ export declare function collectImages(files: File[], existingCount: number, max?: number): Promise<{
15
+ added: PendingImage[];
16
+ error: string | null;
17
+ }>;
18
+ /** One chat message carries every annotation, so an image has to say which
19
+ * marker it belongs to. The upload endpoint keeps the name it is given (after
20
+ * sanitizing and adding a timestamp prefix), so the marker survives into the
21
+ * saved path and the agent can pair them up. */
22
+ export declare function annotationAttachmentPrefix(marker: number): string;
23
+ export declare function annotationAttachmentName(marker: number, filename?: string): string;
@@ -0,0 +1,14 @@
1
+ export interface PollResult<T> {
2
+ value: T;
3
+ done: boolean;
4
+ }
5
+ export interface LatestPollerOptions {
6
+ intervalMs: number;
7
+ maxAttempts: number;
8
+ wait?: (intervalMs: number, signal: AbortSignal) => Promise<void>;
9
+ }
10
+ export declare function createLatestPoller(options: LatestPollerOptions): {
11
+ start: <T>(request: (signal: AbortSignal) => Promise<PollResult<T>>, apply: (value: T) => void) => Promise<void>;
12
+ cancel: () => void;
13
+ dispose: () => void;
14
+ };
@@ -0,0 +1,10 @@
1
+ /** Small UI preferences that should survive a reload (panel widths, collapsed
2
+ * state). Every access is guarded: localStorage throws in embedded and private
3
+ * browsing contexts, and a lost preference must never break the layout.
4
+ *
5
+ * Keys are namespaced `mpv2:<name>` so they cannot collide with the portal
6
+ * shell this microfrontend is mounted into. */
7
+ export declare function readStoredBoolean(key: string, fallback: boolean): boolean;
8
+ export declare function readStoredNumber(key: string, fallback: number): number;
9
+ export declare function writeStoredValue(key: string, value: string): void;
10
+ export declare function writeStoredBoolean(key: string, value: boolean): void;
@@ -0,0 +1,38 @@
1
+ /** One property (or the element's text) the user changed, in display terms. The
2
+ * card has to show the intent, not merely that some intent existed, so the
3
+ * before/after values travel with it rather than being summarized to a flag. */
4
+ export interface PreviewAnnotationChange {
5
+ label: string;
6
+ before: string;
7
+ after: string;
8
+ token?: string;
9
+ }
10
+ export interface PreviewAnnotationItem {
11
+ id: number;
12
+ note: string;
13
+ label: string;
14
+ route?: string;
15
+ device?: string;
16
+ changes?: PreviewAnnotationChange[];
17
+ /** Superseded by `changes`. Still read so cards in already-sent transcripts
18
+ * keep showing that properties were edited. */
19
+ hasProperties?: boolean;
20
+ source?: string;
21
+ }
22
+ export interface PreviewAnnotationMessage {
23
+ /** What the user typed in the composer alongside the markers. Empty for a
24
+ * message that was nothing but annotations. */
25
+ text: string;
26
+ items: PreviewAnnotationItem[];
27
+ }
28
+ export declare function wrapAnnotationPayload(items: PreviewAnnotationItem[], text?: string): string;
29
+ export declare function parseAnnotationMessage(text: string): PreviewAnnotationMessage | null;
30
+ /** Assembles the single message the composer sends: the user's own words first,
31
+ * then the agent-facing marker blocks, then the card payload. The markers are
32
+ * where a request applies, so when the user typed something the prose leads and
33
+ * the blocks are introduced as its targets rather than as a second request. */
34
+ export declare function composeAnnotationMessage(input: {
35
+ text: string;
36
+ blocks: string;
37
+ items: PreviewAnnotationItem[];
38
+ }): string;
@@ -0,0 +1,20 @@
1
+ export interface PromptQueueState<T> {
2
+ pending: readonly T[];
3
+ active: T | null;
4
+ }
5
+ export declare function emptyPromptQueue<T>(): PromptQueueState<T>;
6
+ export declare function enqueuePrompt<T>(queue: PromptQueueState<T>, item: T): PromptQueueState<T>;
7
+ export declare function startNextPrompt<T>(queue: PromptQueueState<T>): {
8
+ queue: PromptQueueState<T>;
9
+ item: T | null;
10
+ };
11
+ export declare function finishActivePrompt<T>(queue: PromptQueueState<T>): {
12
+ queue: PromptQueueState<T>;
13
+ item: T | null;
14
+ };
15
+ export interface AscendingMessageIdState {
16
+ lastTimestamp: number;
17
+ counter: number;
18
+ }
19
+ export declare function createAscendingMessageIdState(): AscendingMessageIdState;
20
+ export declare function makeOpencodeMessageId(state: AscendingMessageIdState, timestamp?: number, randomBytes?: Uint8Array): string;
@@ -0,0 +1,4 @@
1
+ import type { QuestionAnswer, QuestionInfo } from '@opencode-ai/sdk/v2/client';
2
+ export declare function toggleQuestionOption(selected: readonly string[], label: string): string[];
3
+ export declare function answerForQuestion(question: QuestionInfo, selected: readonly string[], customValue: string): QuestionAnswer;
4
+ export declare function buildQuestionAnswers(questions: readonly QuestionInfo[], selected: readonly (readonly string[])[], customValues: readonly string[]): QuestionAnswer[];
@@ -0,0 +1,11 @@
1
+ import type { AgentSessionSummary, ConnectionStatus, ReleaseSummary } from './types';
2
+ export type BadgeVariant = 'success' | 'warning' | 'error' | 'info' | 'neutral' | 'primary';
3
+ export declare function sessionStatusVariant(status: AgentSessionSummary['status']): BadgeVariant;
4
+ export declare function sessionStatusLabel(status: AgentSessionSummary['status']): string;
5
+ export declare function buildStatusVariant(status: string | null): BadgeVariant;
6
+ export declare function buildStatusLabel(status: string | null): string;
7
+ export declare function provisioningStatusLabel(status: string | null | undefined): string;
8
+ export declare function releaseHasPreview(release: Pick<ReleaseSummary, 'status'>): boolean;
9
+ export declare function releaseDisplayStatus(release: ReleaseSummary): string;
10
+ export declare function releaseDisplayVariant(release: ReleaseSummary): BadgeVariant;
11
+ export declare function connectionStatusVariant(status: ConnectionStatus): BadgeVariant;