@molecule/app-ide-react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +115 -0
- package/dist/chatTimelineOrdering.d.ts +50 -0
- package/dist/chatTimelineOrdering.d.ts.map +1 -0
- package/dist/chatTimelineOrdering.js +46 -0
- package/dist/chatTimelineOrdering.js.map +1 -0
- package/dist/command-metadata.d.ts +78 -0
- package/dist/command-metadata.d.ts.map +1 -0
- package/dist/command-metadata.js +214 -0
- package/dist/command-metadata.js.map +1 -0
- package/dist/components/ActivityCard.d.ts +28 -0
- package/dist/components/ActivityCard.d.ts.map +1 -0
- package/dist/components/ActivityCard.js +62 -0
- package/dist/components/ActivityCard.js.map +1 -0
- package/dist/components/AutoCommitBadge.d.ts +58 -0
- package/dist/components/AutoCommitBadge.d.ts.map +1 -0
- package/dist/components/AutoCommitBadge.js +78 -0
- package/dist/components/AutoCommitBadge.js.map +1 -0
- package/dist/components/ChatPanel.d.ts +184 -0
- package/dist/components/ChatPanel.d.ts.map +1 -0
- package/dist/components/ChatPanel.js +6691 -0
- package/dist/components/ChatPanel.js.map +1 -0
- package/dist/components/CommandPalette.d.ts +18 -0
- package/dist/components/CommandPalette.d.ts.map +1 -0
- package/dist/components/CommandPalette.js +33 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/DeviceFrameSelector.d.ts +60 -0
- package/dist/components/DeviceFrameSelector.d.ts.map +1 -0
- package/dist/components/DeviceFrameSelector.js +230 -0
- package/dist/components/DeviceFrameSelector.js.map +1 -0
- package/dist/components/EditorPanel.d.ts +17 -0
- package/dist/components/EditorPanel.d.ts.map +1 -0
- package/dist/components/EditorPanel.js +241 -0
- package/dist/components/EditorPanel.js.map +1 -0
- package/dist/components/FileExplorer.d.ts +64 -0
- package/dist/components/FileExplorer.d.ts.map +1 -0
- package/dist/components/FileExplorer.js +1111 -0
- package/dist/components/FileExplorer.js.map +1 -0
- package/dist/components/FileExplorerContextMenu.d.ts +37 -0
- package/dist/components/FileExplorerContextMenu.d.ts.map +1 -0
- package/dist/components/FileExplorerContextMenu.js +241 -0
- package/dist/components/FileExplorerContextMenu.js.map +1 -0
- package/dist/components/HelpCard.d.ts +34 -0
- package/dist/components/HelpCard.d.ts.map +1 -0
- package/dist/components/HelpCard.js +28 -0
- package/dist/components/HelpCard.js.map +1 -0
- package/dist/components/Icon.d.ts +50 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +25 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/KeyboardShortcutsPanel.d.ts +19 -0
- package/dist/components/KeyboardShortcutsPanel.d.ts.map +1 -0
- package/dist/components/KeyboardShortcutsPanel.js +187 -0
- package/dist/components/KeyboardShortcutsPanel.js.map +1 -0
- package/dist/components/MarkdownContent.d.ts +52 -0
- package/dist/components/MarkdownContent.d.ts.map +1 -0
- package/dist/components/MarkdownContent.js +303 -0
- package/dist/components/MarkdownContent.js.map +1 -0
- package/dist/components/ModelsTable.d.ts +38 -0
- package/dist/components/ModelsTable.d.ts.map +1 -0
- package/dist/components/ModelsTable.js +96 -0
- package/dist/components/ModelsTable.js.map +1 -0
- package/dist/components/PreviewPanel.d.ts +66 -0
- package/dist/components/PreviewPanel.d.ts.map +1 -0
- package/dist/components/PreviewPanel.js +1752 -0
- package/dist/components/PreviewPanel.js.map +1 -0
- package/dist/components/QuickOpen.d.ts +20 -0
- package/dist/components/QuickOpen.d.ts.map +1 -0
- package/dist/components/QuickOpen.js +72 -0
- package/dist/components/QuickOpen.js.map +1 -0
- package/dist/components/QuickPicker.d.ts +21 -0
- package/dist/components/QuickPicker.d.ts.map +1 -0
- package/dist/components/QuickPicker.js +174 -0
- package/dist/components/QuickPicker.js.map +1 -0
- package/dist/components/RelevantSkillSuggestion.d.ts +41 -0
- package/dist/components/RelevantSkillSuggestion.d.ts.map +1 -0
- package/dist/components/RelevantSkillSuggestion.js +85 -0
- package/dist/components/RelevantSkillSuggestion.js.map +1 -0
- package/dist/components/ReportModal.d.ts +35 -0
- package/dist/components/ReportModal.d.ts.map +1 -0
- package/dist/components/ReportModal.js +112 -0
- package/dist/components/ReportModal.js.map +1 -0
- package/dist/components/ResizeHandle.d.ts +21 -0
- package/dist/components/ResizeHandle.d.ts.map +1 -0
- package/dist/components/ResizeHandle.js +109 -0
- package/dist/components/ResizeHandle.js.map +1 -0
- package/dist/components/ScriptsCard.d.ts +37 -0
- package/dist/components/ScriptsCard.d.ts.map +1 -0
- package/dist/components/ScriptsCard.js +177 -0
- package/dist/components/ScriptsCard.js.map +1 -0
- package/dist/components/SearchPanel.d.ts +18 -0
- package/dist/components/SearchPanel.d.ts.map +1 -0
- package/dist/components/SearchPanel.js +449 -0
- package/dist/components/SearchPanel.js.map +1 -0
- package/dist/components/SettingsCard.d.ts +49 -0
- package/dist/components/SettingsCard.d.ts.map +1 -0
- package/dist/components/SettingsCard.js +59 -0
- package/dist/components/SettingsCard.js.map +1 -0
- package/dist/components/ShareModal.d.ts +32 -0
- package/dist/components/ShareModal.d.ts.map +1 -0
- package/dist/components/ShareModal.js +126 -0
- package/dist/components/ShareModal.js.map +1 -0
- package/dist/components/SidebarTabs.d.ts +18 -0
- package/dist/components/SidebarTabs.d.ts.map +1 -0
- package/dist/components/SidebarTabs.js +20 -0
- package/dist/components/SidebarTabs.js.map +1 -0
- package/dist/components/SkillsCard.d.ts +86 -0
- package/dist/components/SkillsCard.d.ts.map +1 -0
- package/dist/components/SkillsCard.js +227 -0
- package/dist/components/SkillsCard.js.map +1 -0
- package/dist/components/StreamingIndicator.d.ts +50 -0
- package/dist/components/StreamingIndicator.d.ts.map +1 -0
- package/dist/components/StreamingIndicator.js +142 -0
- package/dist/components/StreamingIndicator.js.map +1 -0
- package/dist/components/TabBar.d.ts +37 -0
- package/dist/components/TabBar.d.ts.map +1 -0
- package/dist/components/TabBar.js +187 -0
- package/dist/components/TabBar.js.map +1 -0
- package/dist/components/TipCard.d.ts +22 -0
- package/dist/components/TipCard.d.ts.map +1 -0
- package/dist/components/TipCard.js +73 -0
- package/dist/components/TipCard.js.map +1 -0
- package/dist/components/ToolCallCard.d.ts +18 -0
- package/dist/components/ToolCallCard.d.ts.map +1 -0
- package/dist/components/ToolCallCard.js +716 -0
- package/dist/components/ToolCallCard.js.map +1 -0
- package/dist/components/UserAvatar.d.ts +45 -0
- package/dist/components/UserAvatar.d.ts.map +1 -0
- package/dist/components/UserAvatar.js +80 -0
- package/dist/components/UserAvatar.js.map +1 -0
- package/dist/components/WorkspaceLayout.d.ts +19 -0
- package/dist/components/WorkspaceLayout.d.ts.map +1 -0
- package/dist/components/WorkspaceLayout.js +56 -0
- package/dist/components/WorkspaceLayout.js.map +1 -0
- package/dist/components/activity-utilities.d.ts +107 -0
- package/dist/components/activity-utilities.d.ts.map +1 -0
- package/dist/components/activity-utilities.js +154 -0
- package/dist/components/activity-utilities.js.map +1 -0
- package/dist/components/chat-autocommit-utilities.d.ts +172 -0
- package/dist/components/chat-autocommit-utilities.d.ts.map +1 -0
- package/dist/components/chat-autocommit-utilities.js +185 -0
- package/dist/components/chat-autocommit-utilities.js.map +1 -0
- package/dist/components/chat-card-style.d.ts +64 -0
- package/dist/components/chat-card-style.d.ts.map +1 -0
- package/dist/components/chat-card-style.js +74 -0
- package/dist/components/chat-card-style.js.map +1 -0
- package/dist/components/chat-commands.d.ts +17 -0
- package/dist/components/chat-commands.d.ts.map +1 -0
- package/dist/components/chat-commands.js +17 -0
- package/dist/components/chat-commands.js.map +1 -0
- package/dist/components/chat-commit-utilities.d.ts +29 -0
- package/dist/components/chat-commit-utilities.d.ts.map +1 -0
- package/dist/components/chat-commit-utilities.js +31 -0
- package/dist/components/chat-commit-utilities.js.map +1 -0
- package/dist/components/chat-cost-utilities.d.ts +62 -0
- package/dist/components/chat-cost-utilities.d.ts.map +1 -0
- package/dist/components/chat-cost-utilities.js +66 -0
- package/dist/components/chat-cost-utilities.js.map +1 -0
- package/dist/components/chat-effort-utilities.d.ts +96 -0
- package/dist/components/chat-effort-utilities.d.ts.map +1 -0
- package/dist/components/chat-effort-utilities.js +97 -0
- package/dist/components/chat-effort-utilities.js.map +1 -0
- package/dist/components/chat-help-utilities.d.ts +89 -0
- package/dist/components/chat-help-utilities.d.ts.map +1 -0
- package/dist/components/chat-help-utilities.js +131 -0
- package/dist/components/chat-help-utilities.js.map +1 -0
- package/dist/components/chat-model-mode-utilities.d.ts +143 -0
- package/dist/components/chat-model-mode-utilities.d.ts.map +1 -0
- package/dist/components/chat-model-mode-utilities.js +191 -0
- package/dist/components/chat-model-mode-utilities.js.map +1 -0
- package/dist/components/chat-models-utilities.d.ts +98 -0
- package/dist/components/chat-models-utilities.d.ts.map +1 -0
- package/dist/components/chat-models-utilities.js +136 -0
- package/dist/components/chat-models-utilities.js.map +1 -0
- package/dist/components/chat-report-utilities.d.ts +149 -0
- package/dist/components/chat-report-utilities.d.ts.map +1 -0
- package/dist/components/chat-report-utilities.js +151 -0
- package/dist/components/chat-report-utilities.js.map +1 -0
- package/dist/components/chat-scripts-utilities.d.ts +140 -0
- package/dist/components/chat-scripts-utilities.d.ts.map +1 -0
- package/dist/components/chat-scripts-utilities.js +158 -0
- package/dist/components/chat-scripts-utilities.js.map +1 -0
- package/dist/components/chat-settings-utilities.d.ts +72 -0
- package/dist/components/chat-settings-utilities.d.ts.map +1 -0
- package/dist/components/chat-settings-utilities.js +56 -0
- package/dist/components/chat-settings-utilities.js.map +1 -0
- package/dist/components/chat-share-utilities.d.ts +104 -0
- package/dist/components/chat-share-utilities.d.ts.map +1 -0
- package/dist/components/chat-share-utilities.js +90 -0
- package/dist/components/chat-share-utilities.js.map +1 -0
- package/dist/components/chat-skills-utilities.d.ts +242 -0
- package/dist/components/chat-skills-utilities.d.ts.map +1 -0
- package/dist/components/chat-skills-utilities.js +433 -0
- package/dist/components/chat-skills-utilities.js.map +1 -0
- package/dist/components/chat-stream-utilities.d.ts +74 -0
- package/dist/components/chat-stream-utilities.d.ts.map +1 -0
- package/dist/components/chat-stream-utilities.js +103 -0
- package/dist/components/chat-stream-utilities.js.map +1 -0
- package/dist/components/chat-tips-utilities.d.ts +108 -0
- package/dist/components/chat-tips-utilities.d.ts.map +1 -0
- package/dist/components/chat-tips-utilities.js +137 -0
- package/dist/components/chat-tips-utilities.js.map +1 -0
- package/dist/components/device-cycle.d.ts +84 -0
- package/dist/components/device-cycle.d.ts.map +1 -0
- package/dist/components/device-cycle.js +77 -0
- package/dist/components/device-cycle.js.map +1 -0
- package/dist/components/index.d.ts +36 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +33 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/tool-call-utilities.d.ts +69 -0
- package/dist/components/tool-call-utilities.d.ts.map +1 -0
- package/dist/components/tool-call-utilities.js +368 -0
- package/dist/components/tool-call-utilities.js.map +1 -0
- package/dist/components/user-avatar-utilities.d.ts +41 -0
- package/dist/components/user-avatar-utilities.d.ts.map +1 -0
- package/dist/components/user-avatar-utilities.js +56 -0
- package/dist/components/user-avatar-utilities.js.map +1 -0
- package/dist/components/workspace-layout-utilities.d.ts +37 -0
- package/dist/components/workspace-layout-utilities.d.ts.map +1 -0
- package/dist/components/workspace-layout-utilities.js +58 -0
- package/dist/components/workspace-layout-utilities.js.map +1 -0
- package/dist/customEventCards.d.ts +117 -0
- package/dist/customEventCards.d.ts.map +1 -0
- package/dist/customEventCards.js +36 -0
- package/dist/customEventCards.js.map +1 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts +48 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.js +112 -0
- package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
- package/dist/hooks/useViewport.d.ts +42 -0
- package/dist/hooks/useViewport.d.ts.map +1 -0
- package/dist/hooks/useViewport.js +61 -0
- package/dist/hooks/useViewport.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/settings-metadata.d.ts +78 -0
- package/dist/settings-metadata.d.ts.map +1 -0
- package/dist/settings-metadata.js +131 -0
- package/dist/settings-metadata.js.map +1 -0
- package/dist/types.d.ts +751 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers backing the `/report` (and `/bug` alias) command and the header
|
|
3
|
+
* bug-report button.
|
|
4
|
+
*
|
|
5
|
+
* The report modal collects a title, description, optional reproduction steps,
|
|
6
|
+
* and an "include recent chat" toggle, then POSTs to
|
|
7
|
+
* `POST /projects/:id/report { title, description, steps?, includeChat, clientInfo? }`.
|
|
8
|
+
* The backend files a GitHub issue when a report repo + token are configured
|
|
9
|
+
* (else records a DB row) and always persists a DB row tagged with
|
|
10
|
+
* projectId+userId, returning `{ ok, url?, id }`.
|
|
11
|
+
*
|
|
12
|
+
* The payload also carries an optional `clientInfo` block of client-side
|
|
13
|
+
* diagnostics — app version, browser/OS (user agent + platform), language,
|
|
14
|
+
* viewport + screen size, theme, and the current URL — collected by
|
|
15
|
+
* {@link collectClientInfo}. Every field is read defensively (each guarded for
|
|
16
|
+
* SSR / missing globals) so the report attaches whatever it can without ever
|
|
17
|
+
* throwing, giving triage real context without the user having to type it.
|
|
18
|
+
*
|
|
19
|
+
* These helpers parse the command, build the exact POST payload (omitting empty
|
|
20
|
+
* optional fields), validate the form, and produce a confirmation message. They
|
|
21
|
+
* are deterministic and side-effect free so they can be unit tested without
|
|
22
|
+
* rendering or a real backend. The confirmation/link rendering uses these values
|
|
23
|
+
* with `t()` in the component — the only translatable strings here are the
|
|
24
|
+
* confirmation defaults, kept i18n-ready by the caller.
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
/** The report modal's form state. */
|
|
29
|
+
export interface ReportFormState {
|
|
30
|
+
/** Short summary / issue title. */
|
|
31
|
+
title: string;
|
|
32
|
+
/** Detailed description of the problem or request. */
|
|
33
|
+
description: string;
|
|
34
|
+
/** Optional reproduction steps (free text). */
|
|
35
|
+
steps: string;
|
|
36
|
+
/** Whether to attach the recent conversation to the report. */
|
|
37
|
+
includeChat: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Client-side diagnostics attached to a report so triage can see the running
|
|
41
|
+
* environment without asking the user. Every field is optional — only what
|
|
42
|
+
* could be read in the current environment is present (see
|
|
43
|
+
* {@link collectClientInfo}).
|
|
44
|
+
*/
|
|
45
|
+
export interface ClientInfo {
|
|
46
|
+
/** The running build version. */
|
|
47
|
+
appVersion?: string;
|
|
48
|
+
/** `navigator.userAgent` (browser + OS). */
|
|
49
|
+
userAgent?: string;
|
|
50
|
+
/** `navigator.platform`. */
|
|
51
|
+
platform?: string;
|
|
52
|
+
/** `navigator.language`. */
|
|
53
|
+
language?: string;
|
|
54
|
+
/** Inner viewport size, `${innerWidth}×${innerHeight}`. */
|
|
55
|
+
viewport?: string;
|
|
56
|
+
/** Physical screen size, `${screen.width}×${screen.height}`. */
|
|
57
|
+
screen?: string;
|
|
58
|
+
/** Active theme — `'light'` or `'dark'`. */
|
|
59
|
+
theme?: string;
|
|
60
|
+
/** The current page URL (`window.location.href`). */
|
|
61
|
+
url?: string;
|
|
62
|
+
}
|
|
63
|
+
/** The `POST /projects/:id/report` request body. */
|
|
64
|
+
export interface ReportPayload {
|
|
65
|
+
/** Short summary / issue title. */
|
|
66
|
+
title: string;
|
|
67
|
+
/** Detailed description. */
|
|
68
|
+
description: string;
|
|
69
|
+
/** Reproduction steps — omitted entirely when blank. */
|
|
70
|
+
steps?: string;
|
|
71
|
+
/** Whether the backend should attach the recent conversation. */
|
|
72
|
+
includeChat: boolean;
|
|
73
|
+
/** Client diagnostics — omitted entirely when none could be collected. */
|
|
74
|
+
clientInfo?: ClientInfo;
|
|
75
|
+
}
|
|
76
|
+
/** The `POST /projects/:id/report` response. */
|
|
77
|
+
export interface ReportResult {
|
|
78
|
+
/** Whether the report was recorded. */
|
|
79
|
+
ok: boolean;
|
|
80
|
+
/** Link to the created issue, when one was filed. */
|
|
81
|
+
url?: string;
|
|
82
|
+
/** The persisted DB row id. */
|
|
83
|
+
id?: string;
|
|
84
|
+
}
|
|
85
|
+
/** An empty report form (the modal's initial state). */
|
|
86
|
+
export declare const EMPTY_REPORT_FORM: ReportFormState;
|
|
87
|
+
/**
|
|
88
|
+
* Parses a `/report [title]` or `/bug [title]` command. Returns the (possibly
|
|
89
|
+
* empty) trimmed title used to seed the modal when the input is one of those
|
|
90
|
+
* commands, else `null`.
|
|
91
|
+
*
|
|
92
|
+
* @param input - The raw chat input.
|
|
93
|
+
* @returns `{ title }` when it's a `/report` or `/bug` command, else `null`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function parseReportCommand(input: string): {
|
|
96
|
+
title: string;
|
|
97
|
+
} | null;
|
|
98
|
+
/**
|
|
99
|
+
* Collects client-side diagnostics for a report. Reads `navigator`
|
|
100
|
+
* (userAgent/platform/language), `window` (inner viewport size, screen size,
|
|
101
|
+
* location href), plus the caller-supplied app version and theme. Every access
|
|
102
|
+
* is guarded (`typeof window/navigator !== 'undefined'` and per-property
|
|
103
|
+
* presence) so it is SSR-safe and never throws — it returns only the fields it
|
|
104
|
+
* could actually read, so the result may be partial or (in a headless
|
|
105
|
+
* environment) empty.
|
|
106
|
+
*
|
|
107
|
+
* @param opts - Caller-supplied context.
|
|
108
|
+
* @param opts.appVersion - The running build version, if known.
|
|
109
|
+
* @param opts.theme - The active theme (`'light'` | `'dark'`), if known.
|
|
110
|
+
* @returns The populated subset of {@link ClientInfo}.
|
|
111
|
+
*/
|
|
112
|
+
export declare function collectClientInfo(opts?: {
|
|
113
|
+
appVersion?: string;
|
|
114
|
+
theme?: string;
|
|
115
|
+
}): ClientInfo;
|
|
116
|
+
/**
|
|
117
|
+
* Builds the `POST /projects/:id/report` body from the form state, trimming all
|
|
118
|
+
* text fields and omitting `steps` entirely when it is blank. When `clientInfo`
|
|
119
|
+
* is supplied and non-empty, it is attached; an `undefined` or empty diagnostics
|
|
120
|
+
* object is omitted from the payload.
|
|
121
|
+
*
|
|
122
|
+
* @param form - The report form state.
|
|
123
|
+
* @param clientInfo - Optional client diagnostics from {@link collectClientInfo}.
|
|
124
|
+
* @returns The normalized report payload.
|
|
125
|
+
*/
|
|
126
|
+
export declare function buildReportPayload(form: ReportFormState, clientInfo?: ClientInfo): ReportPayload;
|
|
127
|
+
/**
|
|
128
|
+
* Whether the report form has the minimum required fields: a non-empty title
|
|
129
|
+
* and a non-empty description.
|
|
130
|
+
*
|
|
131
|
+
* @param form - The report form state.
|
|
132
|
+
* @returns `true` when the form can be submitted.
|
|
133
|
+
*/
|
|
134
|
+
export declare function isReportFormValid(form: ReportFormState): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Builds the confirmation message shown after a report is submitted. Returns the
|
|
137
|
+
* English defaults; the component passes these through `t()` at render. The
|
|
138
|
+
* success `defaultValue` may contain the `{{productName}}` interpolation token,
|
|
139
|
+
* which the caller fills in from the host's product identity (neutral default:
|
|
140
|
+
* "the IDE"). When the result is not `ok`, returns the failure message.
|
|
141
|
+
*
|
|
142
|
+
* @param result - The `POST /projects/:id/report` response.
|
|
143
|
+
* @returns `{ key, defaultValue }` for the confirmation/failure message.
|
|
144
|
+
*/
|
|
145
|
+
export declare function formatReportConfirmation(result: ReportResult): {
|
|
146
|
+
key: string;
|
|
147
|
+
defaultValue: string;
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=chat-report-utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-report-utilities.d.ts","sourceRoot":"","sources":["../../src/components/chat-report-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAA;IACnB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,WAAW,EAAE,OAAO,CAAA;IACpB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,EAAE,EAAE,OAAO,CAAA;IACX,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,+BAA+B;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,EAAE,eAK/B,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI1E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,UAAU,CAwBhG;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,aAAa,CAUhG;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAEhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,YAAY,GAAG;IAC9D,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;CACrB,CAiBA"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers backing the `/report` (and `/bug` alias) command and the header
|
|
3
|
+
* bug-report button.
|
|
4
|
+
*
|
|
5
|
+
* The report modal collects a title, description, optional reproduction steps,
|
|
6
|
+
* and an "include recent chat" toggle, then POSTs to
|
|
7
|
+
* `POST /projects/:id/report { title, description, steps?, includeChat, clientInfo? }`.
|
|
8
|
+
* The backend files a GitHub issue when a report repo + token are configured
|
|
9
|
+
* (else records a DB row) and always persists a DB row tagged with
|
|
10
|
+
* projectId+userId, returning `{ ok, url?, id }`.
|
|
11
|
+
*
|
|
12
|
+
* The payload also carries an optional `clientInfo` block of client-side
|
|
13
|
+
* diagnostics — app version, browser/OS (user agent + platform), language,
|
|
14
|
+
* viewport + screen size, theme, and the current URL — collected by
|
|
15
|
+
* {@link collectClientInfo}. Every field is read defensively (each guarded for
|
|
16
|
+
* SSR / missing globals) so the report attaches whatever it can without ever
|
|
17
|
+
* throwing, giving triage real context without the user having to type it.
|
|
18
|
+
*
|
|
19
|
+
* These helpers parse the command, build the exact POST payload (omitting empty
|
|
20
|
+
* optional fields), validate the form, and produce a confirmation message. They
|
|
21
|
+
* are deterministic and side-effect free so they can be unit tested without
|
|
22
|
+
* rendering or a real backend. The confirmation/link rendering uses these values
|
|
23
|
+
* with `t()` in the component — the only translatable strings here are the
|
|
24
|
+
* confirmation defaults, kept i18n-ready by the caller.
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
/** An empty report form (the modal's initial state). */
|
|
29
|
+
export const EMPTY_REPORT_FORM = {
|
|
30
|
+
title: '',
|
|
31
|
+
description: '',
|
|
32
|
+
steps: '',
|
|
33
|
+
includeChat: true,
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Parses a `/report [title]` or `/bug [title]` command. Returns the (possibly
|
|
37
|
+
* empty) trimmed title used to seed the modal when the input is one of those
|
|
38
|
+
* commands, else `null`.
|
|
39
|
+
*
|
|
40
|
+
* @param input - The raw chat input.
|
|
41
|
+
* @returns `{ title }` when it's a `/report` or `/bug` command, else `null`.
|
|
42
|
+
*/
|
|
43
|
+
export function parseReportCommand(input) {
|
|
44
|
+
const match = input.trim().match(/^\/(?:report|bug)(?:\s+(.*))?$/i);
|
|
45
|
+
if (!match)
|
|
46
|
+
return null;
|
|
47
|
+
return { title: (match[1] ?? '').trim() };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Collects client-side diagnostics for a report. Reads `navigator`
|
|
51
|
+
* (userAgent/platform/language), `window` (inner viewport size, screen size,
|
|
52
|
+
* location href), plus the caller-supplied app version and theme. Every access
|
|
53
|
+
* is guarded (`typeof window/navigator !== 'undefined'` and per-property
|
|
54
|
+
* presence) so it is SSR-safe and never throws — it returns only the fields it
|
|
55
|
+
* could actually read, so the result may be partial or (in a headless
|
|
56
|
+
* environment) empty.
|
|
57
|
+
*
|
|
58
|
+
* @param opts - Caller-supplied context.
|
|
59
|
+
* @param opts.appVersion - The running build version, if known.
|
|
60
|
+
* @param opts.theme - The active theme (`'light'` | `'dark'`), if known.
|
|
61
|
+
* @returns The populated subset of {@link ClientInfo}.
|
|
62
|
+
*/
|
|
63
|
+
export function collectClientInfo(opts = {}) {
|
|
64
|
+
const info = {};
|
|
65
|
+
if (opts.appVersion)
|
|
66
|
+
info.appVersion = opts.appVersion;
|
|
67
|
+
if (opts.theme)
|
|
68
|
+
info.theme = opts.theme;
|
|
69
|
+
if (typeof navigator !== 'undefined') {
|
|
70
|
+
if (navigator.userAgent)
|
|
71
|
+
info.userAgent = navigator.userAgent;
|
|
72
|
+
if (navigator.platform)
|
|
73
|
+
info.platform = navigator.platform;
|
|
74
|
+
if (navigator.language)
|
|
75
|
+
info.language = navigator.language;
|
|
76
|
+
}
|
|
77
|
+
if (typeof window !== 'undefined') {
|
|
78
|
+
if (typeof window.innerWidth === 'number' && typeof window.innerHeight === 'number') {
|
|
79
|
+
info.viewport = `${window.innerWidth}×${window.innerHeight}`;
|
|
80
|
+
}
|
|
81
|
+
if (window.screen) {
|
|
82
|
+
info.screen = `${window.screen.width}×${window.screen.height}`;
|
|
83
|
+
}
|
|
84
|
+
if (window.location?.href) {
|
|
85
|
+
info.url = window.location.href;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return info;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Builds the `POST /projects/:id/report` body from the form state, trimming all
|
|
92
|
+
* text fields and omitting `steps` entirely when it is blank. When `clientInfo`
|
|
93
|
+
* is supplied and non-empty, it is attached; an `undefined` or empty diagnostics
|
|
94
|
+
* object is omitted from the payload.
|
|
95
|
+
*
|
|
96
|
+
* @param form - The report form state.
|
|
97
|
+
* @param clientInfo - Optional client diagnostics from {@link collectClientInfo}.
|
|
98
|
+
* @returns The normalized report payload.
|
|
99
|
+
*/
|
|
100
|
+
export function buildReportPayload(form, clientInfo) {
|
|
101
|
+
const steps = form.steps.trim();
|
|
102
|
+
const payload = {
|
|
103
|
+
title: form.title.trim(),
|
|
104
|
+
description: form.description.trim(),
|
|
105
|
+
includeChat: form.includeChat,
|
|
106
|
+
};
|
|
107
|
+
if (steps)
|
|
108
|
+
payload.steps = steps;
|
|
109
|
+
if (clientInfo && Object.keys(clientInfo).length > 0)
|
|
110
|
+
payload.clientInfo = clientInfo;
|
|
111
|
+
return payload;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Whether the report form has the minimum required fields: a non-empty title
|
|
115
|
+
* and a non-empty description.
|
|
116
|
+
*
|
|
117
|
+
* @param form - The report form state.
|
|
118
|
+
* @returns `true` when the form can be submitted.
|
|
119
|
+
*/
|
|
120
|
+
export function isReportFormValid(form) {
|
|
121
|
+
return form.title.trim().length > 0 && form.description.trim().length > 0;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Builds the confirmation message shown after a report is submitted. Returns the
|
|
125
|
+
* English defaults; the component passes these through `t()` at render. The
|
|
126
|
+
* success `defaultValue` may contain the `{{productName}}` interpolation token,
|
|
127
|
+
* which the caller fills in from the host's product identity (neutral default:
|
|
128
|
+
* "the IDE"). When the result is not `ok`, returns the failure message.
|
|
129
|
+
*
|
|
130
|
+
* @param result - The `POST /projects/:id/report` response.
|
|
131
|
+
* @returns `{ key, defaultValue }` for the confirmation/failure message.
|
|
132
|
+
*/
|
|
133
|
+
export function formatReportConfirmation(result) {
|
|
134
|
+
if (!result.ok) {
|
|
135
|
+
return {
|
|
136
|
+
key: 'ide.chat.report.failed',
|
|
137
|
+
defaultValue: 'Could not submit your report. Please try again.',
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (result.url) {
|
|
141
|
+
return {
|
|
142
|
+
key: 'ide.chat.report.submittedWithLink',
|
|
143
|
+
defaultValue: 'Thanks! Your report was submitted — track it on the linked issue.',
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
key: 'ide.chat.report.submitted',
|
|
148
|
+
defaultValue: "Thanks! Your report was submitted to {{productName}}'s team.",
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=chat-report-utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-report-utilities.js","sourceRoot":"","sources":["../../src/components/chat-report-utilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers backing the `/scripts` browser and the `/run <name>` command.
|
|
3
|
+
*
|
|
4
|
+
* Scripts are saved shell files under the project's `.agents/scripts/` tree
|
|
5
|
+
* (`.agents/scripts/<name>.sh`) carrying a YAML frontmatter header (`name`,
|
|
6
|
+
* `description`, `createdAt`). The UI lists them via `GET /projects/:id/scripts`,
|
|
7
|
+
* runs one via `POST /projects/:id/scripts/:name/run`, and saves a new one (e.g.
|
|
8
|
+
* one the agent just generated) via `POST /projects/:id/scripts`.
|
|
9
|
+
*
|
|
10
|
+
* These helpers parse the slash commands, normalize a script name into the safe
|
|
11
|
+
* filename base the backend expects, resolve a typed `/run` argument against the
|
|
12
|
+
* known scripts, filter the list for the browser, and assemble a run's raw
|
|
13
|
+
* output for display. They are deterministic and side-effect free so they can be
|
|
14
|
+
* unit tested without rendering or a real backend. Any user-facing prose
|
|
15
|
+
* (status labels, empty states) lives in the components via `t()`, never here —
|
|
16
|
+
* `formatRunOutput` returns only the command's own (untranslatable) stdout/stderr.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
/** A saved project script's metadata (the body lives in the sandbox file). */
|
|
21
|
+
export interface ScriptInfo {
|
|
22
|
+
/** Script name — the `<name>` in `.agents/scripts/<name>.sh` (no extension). */
|
|
23
|
+
name: string;
|
|
24
|
+
/** One-line description (from the script's YAML frontmatter `description`). */
|
|
25
|
+
description: string;
|
|
26
|
+
/** ISO 8601 creation timestamp (frontmatter `createdAt`). */
|
|
27
|
+
createdAt: string;
|
|
28
|
+
}
|
|
29
|
+
/** The result of running a script via the sandbox `exec`. */
|
|
30
|
+
export interface ScriptRunResult {
|
|
31
|
+
/** Captured standard output. */
|
|
32
|
+
stdout: string;
|
|
33
|
+
/** Captured standard error. */
|
|
34
|
+
stderr: string;
|
|
35
|
+
/** Process exit code (`0` = success). */
|
|
36
|
+
exitCode: number;
|
|
37
|
+
}
|
|
38
|
+
/** The `POST /projects/:id/scripts` request body for saving a script. */
|
|
39
|
+
export interface SaveScriptPayload {
|
|
40
|
+
/** Normalized script name (the filename base, no `.sh`). */
|
|
41
|
+
name: string;
|
|
42
|
+
/** One-line description stored in the frontmatter header. */
|
|
43
|
+
description: string;
|
|
44
|
+
/** The shell script body. */
|
|
45
|
+
body: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Normalizes a raw, possibly user- or AI-supplied script name into the safe
|
|
49
|
+
* filename base the backend writes as `.agents/scripts/<name>.sh`: lowercased,
|
|
50
|
+
* a trailing `.sh` dropped, every run of disallowed characters collapsed to a
|
|
51
|
+
* single `-`, and leading/trailing `-` trimmed. Returns `''` when nothing usable
|
|
52
|
+
* remains (the caller should treat that as invalid).
|
|
53
|
+
*
|
|
54
|
+
* @param raw - The raw script name (e.g. `'Run Tests.sh'`).
|
|
55
|
+
* @returns The normalized base name (e.g. `'run-tests'`), or `''`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function normalizeScriptName(raw: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* Parses a `/scripts [query]` command. Returns the (possibly empty) trimmed
|
|
60
|
+
* filter query when the input is the `/scripts` command, else `null`.
|
|
61
|
+
*
|
|
62
|
+
* @param input - The raw chat input.
|
|
63
|
+
* @returns `{ query }` when it's a `/scripts` command, else `null`.
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseScriptsCommand(input: string): {
|
|
66
|
+
query: string;
|
|
67
|
+
} | null;
|
|
68
|
+
/**
|
|
69
|
+
* Parses a `/run [name]` command. Returns the (possibly empty) trimmed script
|
|
70
|
+
* name when the input is the `/run` command, else `null`. An empty `name`
|
|
71
|
+
* signals `/run` was typed without an argument.
|
|
72
|
+
*
|
|
73
|
+
* @param input - The raw chat input.
|
|
74
|
+
* @returns `{ name }` when it's a `/run` command, else `null`.
|
|
75
|
+
*/
|
|
76
|
+
export declare function parseRunCommand(input: string): {
|
|
77
|
+
name: string;
|
|
78
|
+
} | null;
|
|
79
|
+
/**
|
|
80
|
+
* Resolves a `/run` name argument against the known scripts. Tries, in order:
|
|
81
|
+
* exact (case-insensitive, `.sh`-insensitive) match, then a unique prefix match,
|
|
82
|
+
* then a unique substring match. Returns `undefined` when there is no match or
|
|
83
|
+
* the match is ambiguous (more than one prefix/substring candidate).
|
|
84
|
+
*
|
|
85
|
+
* @param scripts - The known scripts.
|
|
86
|
+
* @param name - The raw name argument (may include a `.sh` suffix).
|
|
87
|
+
* @returns The single matching script, or `undefined`.
|
|
88
|
+
*/
|
|
89
|
+
export declare function findScriptByName(scripts: readonly ScriptInfo[], name: string): ScriptInfo | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Filters scripts by a free-text query, matching (case-insensitively) against
|
|
92
|
+
* the name and description. An empty/blank query returns all scripts in input
|
|
93
|
+
* order.
|
|
94
|
+
*
|
|
95
|
+
* @param scripts - The scripts to filter.
|
|
96
|
+
* @param query - The search query.
|
|
97
|
+
* @returns The matching scripts, in input order.
|
|
98
|
+
*/
|
|
99
|
+
export declare function filterScripts(scripts: readonly ScriptInfo[], query: string): ScriptInfo[];
|
|
100
|
+
/**
|
|
101
|
+
* Assembles a run's raw output for display: stdout followed by stderr (each
|
|
102
|
+
* trimmed of trailing whitespace), joined by a blank line when both are present.
|
|
103
|
+
* Returns `''` when the run produced no output — the component decides how to
|
|
104
|
+
* render an empty result. Contains no translatable prose; the exit-status label
|
|
105
|
+
* is rendered separately by the component via `t()`.
|
|
106
|
+
*
|
|
107
|
+
* @param result - The script run result.
|
|
108
|
+
* @returns The combined stdout/stderr text (possibly empty).
|
|
109
|
+
*/
|
|
110
|
+
export declare function formatRunOutput(result: ScriptRunResult): string;
|
|
111
|
+
/**
|
|
112
|
+
* Whether a run succeeded (exit code `0`).
|
|
113
|
+
*
|
|
114
|
+
* @param result - The script run result.
|
|
115
|
+
* @returns `true` when `exitCode === 0`.
|
|
116
|
+
*/
|
|
117
|
+
export declare function runSucceeded(result: ScriptRunResult): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Builds the `POST /projects/:id/scripts` body from raw form/AI input,
|
|
120
|
+
* normalizing the name and trimming the description and body. The backend adds
|
|
121
|
+
* the YAML frontmatter header (`name`, `description`, `createdAt`); the body
|
|
122
|
+
* here is the script content only.
|
|
123
|
+
*
|
|
124
|
+
* @param input - The raw `{ name, description, body }` to save.
|
|
125
|
+
* @returns The normalized save payload.
|
|
126
|
+
*/
|
|
127
|
+
export declare function buildSaveScriptPayload(input: {
|
|
128
|
+
name: string;
|
|
129
|
+
description: string;
|
|
130
|
+
body: string;
|
|
131
|
+
}): SaveScriptPayload;
|
|
132
|
+
/**
|
|
133
|
+
* Whether a save payload has the minimum required fields: a non-empty
|
|
134
|
+
* normalized name and a non-empty body.
|
|
135
|
+
*
|
|
136
|
+
* @param payload - The save payload to validate.
|
|
137
|
+
* @returns `true` when the payload can be saved.
|
|
138
|
+
*/
|
|
139
|
+
export declare function isSaveScriptValid(payload: SaveScriptPayload): boolean;
|
|
140
|
+
//# sourceMappingURL=chat-scripts-utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-scripts-utilities.d.ts","sourceRoot":"","sources":["../../src/components/chat-scripts-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAA;IACZ,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAA;IACnB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,yEAAyE;AACzE,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAA;IACnB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI3E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAItE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,IAAI,EAAE,MAAM,GACX,UAAU,GAAG,SAAS,CAUxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAMzF;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAK/D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAE7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,iBAAiB,CAMpB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAErE"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers backing the `/scripts` browser and the `/run <name>` command.
|
|
3
|
+
*
|
|
4
|
+
* Scripts are saved shell files under the project's `.agents/scripts/` tree
|
|
5
|
+
* (`.agents/scripts/<name>.sh`) carrying a YAML frontmatter header (`name`,
|
|
6
|
+
* `description`, `createdAt`). The UI lists them via `GET /projects/:id/scripts`,
|
|
7
|
+
* runs one via `POST /projects/:id/scripts/:name/run`, and saves a new one (e.g.
|
|
8
|
+
* one the agent just generated) via `POST /projects/:id/scripts`.
|
|
9
|
+
*
|
|
10
|
+
* These helpers parse the slash commands, normalize a script name into the safe
|
|
11
|
+
* filename base the backend expects, resolve a typed `/run` argument against the
|
|
12
|
+
* known scripts, filter the list for the browser, and assemble a run's raw
|
|
13
|
+
* output for display. They are deterministic and side-effect free so they can be
|
|
14
|
+
* unit tested without rendering or a real backend. Any user-facing prose
|
|
15
|
+
* (status labels, empty states) lives in the components via `t()`, never here —
|
|
16
|
+
* `formatRunOutput` returns only the command's own (untranslatable) stdout/stderr.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Normalizes a raw, possibly user- or AI-supplied script name into the safe
|
|
22
|
+
* filename base the backend writes as `.agents/scripts/<name>.sh`: lowercased,
|
|
23
|
+
* a trailing `.sh` dropped, every run of disallowed characters collapsed to a
|
|
24
|
+
* single `-`, and leading/trailing `-` trimmed. Returns `''` when nothing usable
|
|
25
|
+
* remains (the caller should treat that as invalid).
|
|
26
|
+
*
|
|
27
|
+
* @param raw - The raw script name (e.g. `'Run Tests.sh'`).
|
|
28
|
+
* @returns The normalized base name (e.g. `'run-tests'`), or `''`.
|
|
29
|
+
*/
|
|
30
|
+
export function normalizeScriptName(raw) {
|
|
31
|
+
return raw
|
|
32
|
+
.trim()
|
|
33
|
+
.replace(/\.sh$/i, '')
|
|
34
|
+
.toLowerCase()
|
|
35
|
+
.replace(/[^a-z0-9_-]+/g, '-')
|
|
36
|
+
.replace(/-+/g, '-')
|
|
37
|
+
.replace(/^-+|-+$/g, '');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parses a `/scripts [query]` command. Returns the (possibly empty) trimmed
|
|
41
|
+
* filter query when the input is the `/scripts` command, else `null`.
|
|
42
|
+
*
|
|
43
|
+
* @param input - The raw chat input.
|
|
44
|
+
* @returns `{ query }` when it's a `/scripts` command, else `null`.
|
|
45
|
+
*/
|
|
46
|
+
export function parseScriptsCommand(input) {
|
|
47
|
+
const match = input.trim().match(/^\/scripts(?:\s+(.*))?$/i);
|
|
48
|
+
if (!match)
|
|
49
|
+
return null;
|
|
50
|
+
return { query: (match[1] ?? '').trim() };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Parses a `/run [name]` command. Returns the (possibly empty) trimmed script
|
|
54
|
+
* name when the input is the `/run` command, else `null`. An empty `name`
|
|
55
|
+
* signals `/run` was typed without an argument.
|
|
56
|
+
*
|
|
57
|
+
* @param input - The raw chat input.
|
|
58
|
+
* @returns `{ name }` when it's a `/run` command, else `null`.
|
|
59
|
+
*/
|
|
60
|
+
export function parseRunCommand(input) {
|
|
61
|
+
const match = input.trim().match(/^\/run(?:\s+(.*))?$/i);
|
|
62
|
+
if (!match)
|
|
63
|
+
return null;
|
|
64
|
+
return { name: (match[1] ?? '').trim() };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Resolves a `/run` name argument against the known scripts. Tries, in order:
|
|
68
|
+
* exact (case-insensitive, `.sh`-insensitive) match, then a unique prefix match,
|
|
69
|
+
* then a unique substring match. Returns `undefined` when there is no match or
|
|
70
|
+
* the match is ambiguous (more than one prefix/substring candidate).
|
|
71
|
+
*
|
|
72
|
+
* @param scripts - The known scripts.
|
|
73
|
+
* @param name - The raw name argument (may include a `.sh` suffix).
|
|
74
|
+
* @returns The single matching script, or `undefined`.
|
|
75
|
+
*/
|
|
76
|
+
export function findScriptByName(scripts, name) {
|
|
77
|
+
const q = normalizeScriptName(name);
|
|
78
|
+
if (!q)
|
|
79
|
+
return undefined;
|
|
80
|
+
const exact = scripts.find((s) => normalizeScriptName(s.name) === q);
|
|
81
|
+
if (exact)
|
|
82
|
+
return exact;
|
|
83
|
+
const prefix = scripts.filter((s) => normalizeScriptName(s.name).startsWith(q));
|
|
84
|
+
if (prefix.length === 1)
|
|
85
|
+
return prefix[0];
|
|
86
|
+
if (prefix.length > 1)
|
|
87
|
+
return undefined;
|
|
88
|
+
const substring = scripts.filter((s) => normalizeScriptName(s.name).includes(q));
|
|
89
|
+
return substring.length === 1 ? substring[0] : undefined;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Filters scripts by a free-text query, matching (case-insensitively) against
|
|
93
|
+
* the name and description. An empty/blank query returns all scripts in input
|
|
94
|
+
* order.
|
|
95
|
+
*
|
|
96
|
+
* @param scripts - The scripts to filter.
|
|
97
|
+
* @param query - The search query.
|
|
98
|
+
* @returns The matching scripts, in input order.
|
|
99
|
+
*/
|
|
100
|
+
export function filterScripts(scripts, query) {
|
|
101
|
+
const q = query.trim().toLowerCase();
|
|
102
|
+
if (!q)
|
|
103
|
+
return [...scripts];
|
|
104
|
+
return scripts.filter((s) => s.name.toLowerCase().includes(q) || s.description.toLowerCase().includes(q));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Assembles a run's raw output for display: stdout followed by stderr (each
|
|
108
|
+
* trimmed of trailing whitespace), joined by a blank line when both are present.
|
|
109
|
+
* Returns `''` when the run produced no output — the component decides how to
|
|
110
|
+
* render an empty result. Contains no translatable prose; the exit-status label
|
|
111
|
+
* is rendered separately by the component via `t()`.
|
|
112
|
+
*
|
|
113
|
+
* @param result - The script run result.
|
|
114
|
+
* @returns The combined stdout/stderr text (possibly empty).
|
|
115
|
+
*/
|
|
116
|
+
export function formatRunOutput(result) {
|
|
117
|
+
const out = (result.stdout ?? '').replace(/\s+$/, '');
|
|
118
|
+
const err = (result.stderr ?? '').replace(/\s+$/, '');
|
|
119
|
+
if (out && err)
|
|
120
|
+
return `${out}\n\n${err}`;
|
|
121
|
+
return out || err;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Whether a run succeeded (exit code `0`).
|
|
125
|
+
*
|
|
126
|
+
* @param result - The script run result.
|
|
127
|
+
* @returns `true` when `exitCode === 0`.
|
|
128
|
+
*/
|
|
129
|
+
export function runSucceeded(result) {
|
|
130
|
+
return result.exitCode === 0;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Builds the `POST /projects/:id/scripts` body from raw form/AI input,
|
|
134
|
+
* normalizing the name and trimming the description and body. The backend adds
|
|
135
|
+
* the YAML frontmatter header (`name`, `description`, `createdAt`); the body
|
|
136
|
+
* here is the script content only.
|
|
137
|
+
*
|
|
138
|
+
* @param input - The raw `{ name, description, body }` to save.
|
|
139
|
+
* @returns The normalized save payload.
|
|
140
|
+
*/
|
|
141
|
+
export function buildSaveScriptPayload(input) {
|
|
142
|
+
return {
|
|
143
|
+
name: normalizeScriptName(input.name),
|
|
144
|
+
description: input.description.trim(),
|
|
145
|
+
body: input.body.replace(/\s+$/, ''),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Whether a save payload has the minimum required fields: a non-empty
|
|
150
|
+
* normalized name and a non-empty body.
|
|
151
|
+
*
|
|
152
|
+
* @param payload - The save payload to validate.
|
|
153
|
+
* @returns `true` when the payload can be saved.
|
|
154
|
+
*/
|
|
155
|
+
export function isSaveScriptValid(payload) {
|
|
156
|
+
return payload.name.length > 0 && payload.body.trim().length > 0;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=chat-scripts-utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-scripts-utilities.js","sourceRoot":"","sources":["../../src/components/chat-scripts-utilities.ts"],"names":[],"mappings":"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"}
|