@burdenoff/microfe-vibecontrols 2026.602.9 → 2026.608.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/actions/ActionForm.js +260 -252
- package/dist/components/actions/ActionForm.js.map +1 -1
- package/dist/components/ai/InstructionFilesManager.js +138 -135
- package/dist/components/ai/InstructionFilesManager.js.map +1 -1
- package/dist/components/aliases/AliasManager.js +225 -224
- package/dist/components/aliases/AliasManager.js.map +1 -1
- package/dist/components/common/ActionAgentTargetNotice.js +125 -0
- package/dist/components/common/ActionAgentTargetNotice.js.map +1 -0
- package/dist/components/common/CommandEditor.js +49 -0
- package/dist/components/common/CommandEditor.js.map +1 -0
- package/dist/components/common/actionAgentTarget.js +55 -0
- package/dist/components/common/actionAgentTarget.js.map +1 -0
- package/dist/components/common/commandHighlight.js +190 -0
- package/dist/components/common/commandHighlight.js.map +1 -0
- package/dist/components/vibecalendar/ScheduleTaskModal.js +151 -149
- package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckButtonForm.js +231 -219
- package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
- package/dist/pages/ActionsPage.js +233 -224
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/AgentDetailsPage.js +490 -489
- package/dist/pages/AgentDetailsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,10 +4,11 @@ import { LINK_TO_VIBE_DEFAULT as c, LinkToVibePanel as l } from "../shared/LinkT
|
|
|
4
4
|
import { EntityVibeLinkControl as u } from "../shared/EntityVibeLinkControl.js";
|
|
5
5
|
import { EntityShareButton as d } from "../sharing/EntityShareButton.js";
|
|
6
6
|
import "../sharing/index.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { CommandEditor as f } from "../common/CommandEditor.js";
|
|
8
|
+
import { useMemo as p, useState as m } from "react";
|
|
9
|
+
import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
9
10
|
//#region src/components/ai/InstructionFilesManager.tsx
|
|
10
|
-
var
|
|
11
|
+
var v = [
|
|
11
12
|
{
|
|
12
13
|
value: i.AgentsMd,
|
|
13
14
|
label: "AGENTS.md"
|
|
@@ -24,14 +25,14 @@ var _ = [
|
|
|
24
25
|
value: i.Custom,
|
|
25
26
|
label: "Custom"
|
|
26
27
|
}
|
|
27
|
-
],
|
|
28
|
+
], y = [{
|
|
28
29
|
value: a.Agent,
|
|
29
30
|
label: "Agent"
|
|
30
31
|
}, {
|
|
31
32
|
value: a.Vibe,
|
|
32
33
|
label: "Vibe"
|
|
33
|
-
}],
|
|
34
|
-
function
|
|
34
|
+
}], b = "w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary", x = "inline-flex items-center rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50", S = "inline-flex items-center rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken", C = "inline-flex items-center rounded-md bg-action-danger-bg px-3 py-2 text-sm font-medium text-action-danger-text disabled:opacity-50", w = "inline-flex items-center rounded bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary";
|
|
35
|
+
function T() {
|
|
35
36
|
return {
|
|
36
37
|
filename: i.AgentsMd,
|
|
37
38
|
customName: "",
|
|
@@ -40,13 +41,13 @@ function w() {
|
|
|
40
41
|
link: c
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
|
-
function
|
|
44
|
+
function E(e) {
|
|
44
45
|
return e === s.SharedWithVibe ? "SHARED_WITH_VIBE" : "PRIVATE";
|
|
45
46
|
}
|
|
46
|
-
function
|
|
47
|
+
function D(e) {
|
|
47
48
|
return e === "SHARED_WITH_VIBE" ? s.SharedWithVibe : s.Private;
|
|
48
49
|
}
|
|
49
|
-
function
|
|
50
|
+
function O(e) {
|
|
50
51
|
return {
|
|
51
52
|
filename: e.filename,
|
|
52
53
|
customName: e.customName ?? "",
|
|
@@ -54,16 +55,16 @@ function D(e) {
|
|
|
54
55
|
content: e.content,
|
|
55
56
|
link: {
|
|
56
57
|
vibeId: e.vibeId ?? null,
|
|
57
|
-
visibility:
|
|
58
|
+
visibility: E(e.visibility)
|
|
58
59
|
}
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
|
-
function
|
|
62
|
+
function k(e) {
|
|
62
63
|
let t = new Date(e);
|
|
63
64
|
return Number.isNaN(t.getTime()) ? e : t.toLocaleString();
|
|
64
65
|
}
|
|
65
|
-
function
|
|
66
|
-
let { data:
|
|
66
|
+
function A({ agentId: c }) {
|
|
67
|
+
let { data: E, loading: A, error: j } = n({
|
|
67
68
|
variables: {
|
|
68
69
|
filter: c ? { agentId: c } : void 0,
|
|
69
70
|
pagination: {
|
|
@@ -72,265 +73,267 @@ function k({ agentId: c }) {
|
|
|
72
73
|
}
|
|
73
74
|
},
|
|
74
75
|
fetchPolicy: "cache-and-network"
|
|
75
|
-
}), [
|
|
76
|
-
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
},
|
|
82
|
-
if (
|
|
83
|
-
|
|
76
|
+
}), [M, { loading: N }] = e({ refetchQueries: ["ListAgentInstructionFiles"] }), [P, { loading: F }] = r({ refetchQueries: ["ListAgentInstructionFiles"] }), [I, { loading: L }] = t({ refetchQueries: ["ListAgentInstructionFiles"] }), [R, z] = m(!1), [B, V] = m(null), [H, U] = m(T), [W, G] = m(null), [K, q] = m(null), J = p(() => E?.agentInstructionFiles?.items ?? [], [E?.agentInstructionFiles?.items]), Y = N || F, X = () => {
|
|
77
|
+
V(null), U(T()), q(null), z(!0);
|
|
78
|
+
}, Z = (e) => {
|
|
79
|
+
V(e.id), U(O(e)), q(null), z(!0);
|
|
80
|
+
}, Q = () => {
|
|
81
|
+
z(!1), V(null), U(T()), q(null);
|
|
82
|
+
}, $ = async () => {
|
|
83
|
+
if (q(null), H.filename === i.Custom && H.customName.trim() === "") {
|
|
84
|
+
q("Please provide a name for the custom instruction file.");
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
86
|
-
if (
|
|
87
|
-
|
|
87
|
+
if (H.content.trim() === "") {
|
|
88
|
+
q("Instruction file content cannot be empty.");
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
|
-
let e =
|
|
91
|
+
let e = H.filename === i.Custom ? H.customName.trim() : null;
|
|
91
92
|
try {
|
|
92
|
-
if (
|
|
93
|
-
id:
|
|
93
|
+
if (B) await P({ variables: {
|
|
94
|
+
id: B,
|
|
94
95
|
input: {
|
|
95
|
-
content:
|
|
96
|
-
filename:
|
|
96
|
+
content: H.content,
|
|
97
|
+
filename: H.filename,
|
|
97
98
|
customName: e
|
|
98
99
|
}
|
|
99
100
|
} });
|
|
100
101
|
else {
|
|
101
|
-
if (
|
|
102
|
-
|
|
102
|
+
if (H.scope === a.Vibe && !H.link.vibeId) {
|
|
103
|
+
q("Pick a vibe to link before saving a vibe-scoped file.");
|
|
103
104
|
return;
|
|
104
105
|
}
|
|
105
106
|
let t = {
|
|
106
|
-
filename:
|
|
107
|
+
filename: H.filename,
|
|
107
108
|
customName: e,
|
|
108
|
-
content:
|
|
109
|
-
scope:
|
|
109
|
+
content: H.content,
|
|
110
|
+
scope: H.scope
|
|
110
111
|
};
|
|
111
|
-
|
|
112
|
+
H.scope === a.Vibe && H.link.vibeId ? (t.vibeId = H.link.vibeId, t.visibility = D(H.link.visibility)) : t.agentId = c ?? null, await M({ variables: { input: t } });
|
|
112
113
|
}
|
|
113
|
-
|
|
114
|
+
Q();
|
|
114
115
|
} catch (e) {
|
|
115
|
-
|
|
116
|
+
q(e instanceof Error ? e.message : "Failed to save the instruction file.");
|
|
116
117
|
}
|
|
117
|
-
},
|
|
118
|
+
}, ee = async (e) => {
|
|
118
119
|
try {
|
|
119
|
-
await
|
|
120
|
+
await I({ variables: { id: e } });
|
|
120
121
|
} finally {
|
|
121
|
-
|
|
122
|
+
G(null);
|
|
122
123
|
}
|
|
123
124
|
};
|
|
124
|
-
return /* @__PURE__ */
|
|
125
|
+
return /* @__PURE__ */ _("section", {
|
|
125
126
|
"data-testid": "instruction-files-manager",
|
|
126
127
|
className: "space-y-4 rounded-lg border border-border-default bg-bg-surface p-4",
|
|
127
128
|
children: [
|
|
128
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ _("header", {
|
|
129
130
|
className: "flex flex-wrap items-start justify-between gap-3",
|
|
130
|
-
children: [/* @__PURE__ */
|
|
131
|
+
children: [/* @__PURE__ */ _("div", {
|
|
131
132
|
className: "space-y-1",
|
|
132
|
-
children: [/* @__PURE__ */
|
|
133
|
+
children: [/* @__PURE__ */ g("h2", {
|
|
133
134
|
className: "text-lg font-semibold text-text-primary",
|
|
134
135
|
children: "Instruction files"
|
|
135
|
-
}), /* @__PURE__ */
|
|
136
|
+
}), /* @__PURE__ */ g("p", {
|
|
136
137
|
className: "max-w-2xl text-sm text-text-secondary",
|
|
137
138
|
children: "AGENTS.md / CLAUDE.md / GEMINI.md maintained centrally and pushed to your agent on chat open."
|
|
138
139
|
})]
|
|
139
|
-
}), /* @__PURE__ */
|
|
140
|
+
}), /* @__PURE__ */ g("button", {
|
|
140
141
|
type: "button",
|
|
141
142
|
"data-testid": "instruction-file-new",
|
|
142
|
-
className:
|
|
143
|
-
onClick:
|
|
144
|
-
children:
|
|
143
|
+
className: x,
|
|
144
|
+
onClick: R && !B ? Q : X,
|
|
145
|
+
children: R && !B ? "Close" : "New file"
|
|
145
146
|
})]
|
|
146
147
|
}),
|
|
147
|
-
|
|
148
|
+
R && /* @__PURE__ */ _("div", {
|
|
148
149
|
className: "space-y-4 rounded-md border border-border-default bg-bg-elevated p-4",
|
|
149
150
|
children: [
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ g("h3", {
|
|
151
152
|
className: "text-sm font-medium text-text-primary",
|
|
152
|
-
children:
|
|
153
|
+
children: B ? "Edit instruction file" : "New instruction file"
|
|
153
154
|
}),
|
|
154
|
-
/* @__PURE__ */
|
|
155
|
+
/* @__PURE__ */ _("div", {
|
|
155
156
|
className: "grid gap-4 sm:grid-cols-2",
|
|
156
|
-
children: [/* @__PURE__ */
|
|
157
|
+
children: [/* @__PURE__ */ _("label", {
|
|
157
158
|
className: "space-y-1.5",
|
|
158
|
-
children: [/* @__PURE__ */
|
|
159
|
+
children: [/* @__PURE__ */ g("span", {
|
|
159
160
|
className: "block text-sm font-medium text-text-secondary",
|
|
160
161
|
children: "Filename"
|
|
161
|
-
}), /* @__PURE__ */
|
|
162
|
-
className:
|
|
163
|
-
value:
|
|
164
|
-
onChange: (e) =>
|
|
162
|
+
}), /* @__PURE__ */ g("select", {
|
|
163
|
+
className: b,
|
|
164
|
+
value: H.filename,
|
|
165
|
+
onChange: (e) => U((t) => ({
|
|
165
166
|
...t,
|
|
166
167
|
filename: e.target.value
|
|
167
168
|
})),
|
|
168
|
-
children:
|
|
169
|
+
children: v.map((e) => /* @__PURE__ */ g("option", {
|
|
169
170
|
value: e.value,
|
|
170
171
|
children: e.label
|
|
171
172
|
}, e.value))
|
|
172
173
|
})]
|
|
173
|
-
}), /* @__PURE__ */
|
|
174
|
+
}), /* @__PURE__ */ _("label", {
|
|
174
175
|
className: "space-y-1.5",
|
|
175
|
-
children: [/* @__PURE__ */
|
|
176
|
+
children: [/* @__PURE__ */ g("span", {
|
|
176
177
|
className: "block text-sm font-medium text-text-secondary",
|
|
177
178
|
children: "Scope"
|
|
178
|
-
}), /* @__PURE__ */
|
|
179
|
-
className:
|
|
180
|
-
value:
|
|
181
|
-
disabled:
|
|
182
|
-
onChange: (e) =>
|
|
179
|
+
}), /* @__PURE__ */ g("select", {
|
|
180
|
+
className: b,
|
|
181
|
+
value: H.scope,
|
|
182
|
+
disabled: B !== null,
|
|
183
|
+
onChange: (e) => U((t) => ({
|
|
183
184
|
...t,
|
|
184
185
|
scope: e.target.value
|
|
185
186
|
})),
|
|
186
|
-
children:
|
|
187
|
+
children: y.map((e) => /* @__PURE__ */ g("option", {
|
|
187
188
|
value: e.value,
|
|
188
189
|
children: e.label
|
|
189
190
|
}, e.value))
|
|
190
191
|
})]
|
|
191
192
|
})]
|
|
192
193
|
}),
|
|
193
|
-
|
|
194
|
+
H.filename === i.Custom && /* @__PURE__ */ _("label", {
|
|
194
195
|
className: "space-y-1.5",
|
|
195
|
-
children: [/* @__PURE__ */
|
|
196
|
+
children: [/* @__PURE__ */ g("span", {
|
|
196
197
|
className: "block text-sm font-medium text-text-secondary",
|
|
197
198
|
children: "Custom name"
|
|
198
|
-
}), /* @__PURE__ */
|
|
199
|
+
}), /* @__PURE__ */ g("input", {
|
|
199
200
|
type: "text",
|
|
200
|
-
className:
|
|
201
|
+
className: b,
|
|
201
202
|
placeholder: "e.g. CONTRIBUTING.md",
|
|
202
|
-
value:
|
|
203
|
-
onChange: (e) =>
|
|
203
|
+
value: H.customName,
|
|
204
|
+
onChange: (e) => U((t) => ({
|
|
204
205
|
...t,
|
|
205
206
|
customName: e.target.value
|
|
206
207
|
}))
|
|
207
208
|
})]
|
|
208
209
|
}),
|
|
209
|
-
!
|
|
210
|
-
value:
|
|
211
|
-
onChange: (e) =>
|
|
210
|
+
!B && H.scope === a.Vibe && /* @__PURE__ */ g(l, {
|
|
211
|
+
value: H.link,
|
|
212
|
+
onChange: (e) => U((t) => ({
|
|
212
213
|
...t,
|
|
213
214
|
link: e
|
|
214
215
|
})),
|
|
215
|
-
disabled:
|
|
216
|
+
disabled: Y
|
|
216
217
|
}),
|
|
217
|
-
/* @__PURE__ */
|
|
218
|
+
/* @__PURE__ */ _("label", {
|
|
218
219
|
className: "space-y-1.5",
|
|
219
|
-
children: [/* @__PURE__ */
|
|
220
|
+
children: [/* @__PURE__ */ g("span", {
|
|
220
221
|
className: "block text-sm font-medium text-text-secondary",
|
|
221
222
|
children: "Content"
|
|
222
|
-
}), /* @__PURE__ */
|
|
223
|
-
|
|
223
|
+
}), /* @__PURE__ */ g(f, {
|
|
224
|
+
language: "markdown",
|
|
225
|
+
rows: 12,
|
|
226
|
+
style: { minHeight: "14rem" },
|
|
224
227
|
placeholder: "# Project instructions…",
|
|
225
|
-
value:
|
|
226
|
-
onChange: (e) =>
|
|
228
|
+
value: H.content,
|
|
229
|
+
onChange: (e) => U((t) => ({
|
|
227
230
|
...t,
|
|
228
231
|
content: e.target.value
|
|
229
232
|
}))
|
|
230
233
|
})]
|
|
231
234
|
}),
|
|
232
|
-
|
|
235
|
+
K && /* @__PURE__ */ g("p", {
|
|
233
236
|
className: "text-sm text-action-danger-text",
|
|
234
237
|
role: "alert",
|
|
235
|
-
children:
|
|
238
|
+
children: K
|
|
236
239
|
}),
|
|
237
|
-
/* @__PURE__ */
|
|
240
|
+
/* @__PURE__ */ _("div", {
|
|
238
241
|
className: "flex items-center gap-2",
|
|
239
|
-
children: [/* @__PURE__ */
|
|
242
|
+
children: [/* @__PURE__ */ g("button", {
|
|
240
243
|
type: "button",
|
|
241
244
|
"data-testid": "instruction-file-save",
|
|
242
|
-
className:
|
|
243
|
-
disabled:
|
|
245
|
+
className: x,
|
|
246
|
+
disabled: Y,
|
|
244
247
|
onClick: () => {
|
|
245
|
-
|
|
248
|
+
$();
|
|
246
249
|
},
|
|
247
|
-
children:
|
|
248
|
-
}), /* @__PURE__ */
|
|
250
|
+
children: Y ? "Saving…" : "Save"
|
|
251
|
+
}), /* @__PURE__ */ g("button", {
|
|
249
252
|
type: "button",
|
|
250
|
-
className:
|
|
251
|
-
disabled:
|
|
252
|
-
onClick:
|
|
253
|
+
className: S,
|
|
254
|
+
disabled: Y,
|
|
255
|
+
onClick: Q,
|
|
253
256
|
children: "Cancel"
|
|
254
257
|
})]
|
|
255
258
|
})
|
|
256
259
|
]
|
|
257
260
|
}),
|
|
258
|
-
|
|
261
|
+
j ? /* @__PURE__ */ _("p", {
|
|
259
262
|
className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-action-danger-text",
|
|
260
|
-
children: ["Could not load instruction files: ",
|
|
261
|
-
}) :
|
|
263
|
+
children: ["Could not load instruction files: ", j.message]
|
|
264
|
+
}) : A && J.length === 0 ? /* @__PURE__ */ g("p", {
|
|
262
265
|
className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary",
|
|
263
266
|
children: "Loading instruction files…"
|
|
264
|
-
}) :
|
|
267
|
+
}) : J.length === 0 ? /* @__PURE__ */ g("p", {
|
|
265
268
|
className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary",
|
|
266
269
|
children: "No instruction files yet. Create one to share it with your agent."
|
|
267
|
-
}) : /* @__PURE__ */
|
|
270
|
+
}) : /* @__PURE__ */ g("ul", {
|
|
268
271
|
className: "space-y-2",
|
|
269
|
-
children:
|
|
270
|
-
let t =
|
|
271
|
-
return /* @__PURE__ */
|
|
272
|
+
children: J.map((e) => {
|
|
273
|
+
let t = W === e.id, n = e.visibility === s.SharedWithVibe, r = e.scope === a.Vibe ? "Vibe" : "Agent";
|
|
274
|
+
return /* @__PURE__ */ _("li", {
|
|
272
275
|
"data-testid": "instruction-file-row",
|
|
273
276
|
className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-border-default bg-bg-elevated p-3",
|
|
274
|
-
children: [/* @__PURE__ */
|
|
277
|
+
children: [/* @__PURE__ */ _("div", {
|
|
275
278
|
className: "min-w-0 space-y-1",
|
|
276
|
-
children: [/* @__PURE__ */
|
|
279
|
+
children: [/* @__PURE__ */ _("div", {
|
|
277
280
|
className: "flex flex-wrap items-center gap-2",
|
|
278
281
|
children: [
|
|
279
|
-
/* @__PURE__ */
|
|
282
|
+
/* @__PURE__ */ g("span", {
|
|
280
283
|
className: "font-mono text-sm font-bold text-text-primary",
|
|
281
284
|
children: e.effectiveFilename
|
|
282
285
|
}),
|
|
283
|
-
/* @__PURE__ */
|
|
284
|
-
className:
|
|
286
|
+
/* @__PURE__ */ g("span", {
|
|
287
|
+
className: w,
|
|
285
288
|
children: r
|
|
286
289
|
}),
|
|
287
|
-
/* @__PURE__ */
|
|
288
|
-
className:
|
|
290
|
+
/* @__PURE__ */ g("span", {
|
|
291
|
+
className: w,
|
|
289
292
|
children: n ? "Shared" : "Private"
|
|
290
293
|
})
|
|
291
294
|
]
|
|
292
|
-
}), /* @__PURE__ */
|
|
295
|
+
}), /* @__PURE__ */ _("p", {
|
|
293
296
|
className: "text-xs text-text-tertiary",
|
|
294
|
-
children: ["Updated ",
|
|
297
|
+
children: ["Updated ", k(e.updatedAt)]
|
|
295
298
|
})]
|
|
296
|
-
}), /* @__PURE__ */
|
|
299
|
+
}), /* @__PURE__ */ g("div", {
|
|
297
300
|
className: "flex items-center gap-2",
|
|
298
|
-
children: t ? /* @__PURE__ */
|
|
299
|
-
/* @__PURE__ */
|
|
301
|
+
children: t ? /* @__PURE__ */ _(h, { children: [
|
|
302
|
+
/* @__PURE__ */ g("span", {
|
|
300
303
|
className: "text-xs text-text-secondary",
|
|
301
304
|
children: "Delete this file?"
|
|
302
305
|
}),
|
|
303
|
-
/* @__PURE__ */
|
|
306
|
+
/* @__PURE__ */ g("button", {
|
|
304
307
|
type: "button",
|
|
305
|
-
className:
|
|
306
|
-
disabled:
|
|
308
|
+
className: C,
|
|
309
|
+
disabled: L,
|
|
307
310
|
onClick: () => {
|
|
308
|
-
|
|
311
|
+
ee(e.id);
|
|
309
312
|
},
|
|
310
|
-
children:
|
|
313
|
+
children: L ? "Deleting…" : "Confirm"
|
|
311
314
|
}),
|
|
312
|
-
/* @__PURE__ */
|
|
315
|
+
/* @__PURE__ */ g("button", {
|
|
313
316
|
type: "button",
|
|
314
|
-
className:
|
|
315
|
-
disabled:
|
|
316
|
-
onClick: () =>
|
|
317
|
+
className: S,
|
|
318
|
+
disabled: L,
|
|
319
|
+
onClick: () => G(null),
|
|
317
320
|
children: "Cancel"
|
|
318
321
|
})
|
|
319
|
-
] }) : /* @__PURE__ */
|
|
320
|
-
/* @__PURE__ */
|
|
322
|
+
] }) : /* @__PURE__ */ _(h, { children: [
|
|
323
|
+
/* @__PURE__ */ g("button", {
|
|
321
324
|
type: "button",
|
|
322
|
-
className:
|
|
323
|
-
onClick: () =>
|
|
325
|
+
className: S,
|
|
326
|
+
onClick: () => Z(e),
|
|
324
327
|
children: "Edit"
|
|
325
328
|
}),
|
|
326
|
-
/* @__PURE__ */
|
|
329
|
+
/* @__PURE__ */ g(u, {
|
|
327
330
|
entityType: o.InstructionFile,
|
|
328
331
|
entityId: e.id,
|
|
329
332
|
currentVibeId: e.vibeId ?? null,
|
|
330
333
|
currentVisibility: e.visibility,
|
|
331
334
|
refetchQueries: ["ListAgentInstructionFiles"]
|
|
332
335
|
}),
|
|
333
|
-
/* @__PURE__ */
|
|
336
|
+
/* @__PURE__ */ g(d, {
|
|
334
337
|
entity: "instructionfile",
|
|
335
338
|
resource: {
|
|
336
339
|
id: e.id,
|
|
@@ -339,10 +342,10 @@ function k({ agentId: c }) {
|
|
|
339
342
|
},
|
|
340
343
|
label: "Share"
|
|
341
344
|
}),
|
|
342
|
-
/* @__PURE__ */
|
|
345
|
+
/* @__PURE__ */ g("button", {
|
|
343
346
|
type: "button",
|
|
344
|
-
className:
|
|
345
|
-
onClick: () =>
|
|
347
|
+
className: C,
|
|
348
|
+
onClick: () => G(e.id),
|
|
346
349
|
children: "Delete"
|
|
347
350
|
})
|
|
348
351
|
] })
|
|
@@ -354,6 +357,6 @@ function k({ agentId: c }) {
|
|
|
354
357
|
});
|
|
355
358
|
}
|
|
356
359
|
//#endregion
|
|
357
|
-
export {
|
|
360
|
+
export { A as InstructionFilesManager };
|
|
358
361
|
|
|
359
362
|
//# sourceMappingURL=InstructionFilesManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstructionFilesManager.js","names":[],"sources":["../../../src/components/ai/InstructionFilesManager.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n useListAgentInstructionFilesQuery,\n useCreateAgentInstructionFileMutation,\n useUpdateAgentInstructionFileMutation,\n useDeleteAgentInstructionFileMutation,\n} from '@/generated/wspace-operations';\nimport {\n InstructionFilename,\n InstructionScope,\n VibeVisibility,\n VibeEntityType,\n type CreateAgentInstructionFileInput,\n type UpdateAgentInstructionFileInput,\n} from '@/generated/wspace-types';\nimport {\n LinkToVibePanel,\n LINK_TO_VIBE_DEFAULT,\n type LinkToVibeValue,\n type LinkToVibeVisibility,\n} from '@/components/shared/LinkToVibePanel';\nimport { EntityVibeLinkControl } from '@/components/shared/EntityVibeLinkControl';\nimport { EntityShareButton } from '@/components/sharing';\n\n/**\n * Shape of a single instruction file as returned by ListAgentInstructionFiles.\n * Mirrors the InstructionFileFields fragment in wspace-operations.\n */\ninterface InstructionFile {\n id: string;\n workspaceId: string;\n filename: InstructionFilename;\n customName?: string | null;\n effectiveFilename: string;\n content: string;\n scope: InstructionScope;\n agentId?: string | null;\n tags: string[];\n vibeId?: string | null;\n visibility: VibeVisibility;\n createdBy: string;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface InstructionFilesManagerProps {\n /** Default AGENT-scope target for newly-created files. */\n agentId?: string | null;\n}\n\nconst FILENAME_OPTIONS: ReadonlyArray<{ value: InstructionFilename; label: string }> = [\n { value: InstructionFilename.AgentsMd, label: 'AGENTS.md' },\n { value: InstructionFilename.ClaudeMd, label: 'CLAUDE.md' },\n { value: InstructionFilename.GeminiMd, label: 'GEMINI.md' },\n { value: InstructionFilename.Custom, label: 'Custom' },\n];\n\nconst SCOPE_OPTIONS: ReadonlyArray<{ value: InstructionScope; label: string }> = [\n { value: InstructionScope.Agent, label: 'Agent' },\n { value: InstructionScope.Vibe, label: 'Vibe' },\n];\n\nconst INPUT_CLASS =\n 'w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary';\n\nconst PRIMARY_BTN_CLASS =\n 'inline-flex items-center rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50';\n\nconst SECONDARY_BTN_CLASS =\n 'inline-flex items-center rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken';\n\nconst DANGER_BTN_CLASS =\n 'inline-flex items-center rounded-md bg-action-danger-bg px-3 py-2 text-sm font-medium text-action-danger-text disabled:opacity-50';\n\nconst BADGE_CLASS =\n 'inline-flex items-center rounded bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary';\n\n/** Internal state for the create/edit form. */\ninterface FormState {\n filename: InstructionFilename;\n customName: string;\n scope: InstructionScope;\n content: string;\n link: LinkToVibeValue;\n}\n\nfunction emptyFormState(): FormState {\n return {\n filename: InstructionFilename.AgentsMd,\n customName: '',\n scope: InstructionScope.Agent,\n content: '',\n link: LINK_TO_VIBE_DEFAULT,\n };\n}\n\n/** Map the file's stored visibility enum onto the LinkToVibePanel string union. */\nfunction toLinkVisibility(visibility: VibeVisibility): LinkToVibeVisibility {\n return visibility === VibeVisibility.SharedWithVibe ? 'SHARED_WITH_VIBE' : 'PRIVATE';\n}\n\n/** Map the LinkToVibePanel string union back onto the generated enum. */\nfunction toVibeVisibility(visibility: LinkToVibeVisibility): VibeVisibility {\n return visibility === 'SHARED_WITH_VIBE' ? VibeVisibility.SharedWithVibe : VibeVisibility.Private;\n}\n\nfunction formStateFromFile(file: InstructionFile): FormState {\n return {\n filename: file.filename,\n customName: file.customName ?? '',\n scope: file.scope,\n content: file.content,\n link: {\n vibeId: file.vibeId ?? null,\n visibility: toLinkVisibility(file.visibility),\n },\n };\n}\n\nfunction formatTimestamp(value: string): string {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return value;\n }\n return parsed.toLocaleString();\n}\n\nexport function InstructionFilesManager({\n agentId,\n}: InstructionFilesManagerProps): React.ReactElement {\n const { data, loading, error } = useListAgentInstructionFilesQuery({\n variables: {\n filter: agentId ? { agentId } : undefined,\n pagination: { limit: 100, offset: 0 },\n },\n fetchPolicy: 'cache-and-network',\n });\n\n const [createFile, { loading: creating }] = useCreateAgentInstructionFileMutation({\n refetchQueries: ['ListAgentInstructionFiles'],\n });\n const [updateFile, { loading: updating }] = useUpdateAgentInstructionFileMutation({\n refetchQueries: ['ListAgentInstructionFiles'],\n });\n const [deleteFile, { loading: deleting }] = useDeleteAgentInstructionFileMutation({\n refetchQueries: ['ListAgentInstructionFiles'],\n });\n\n const [formOpen, setFormOpen] = useState(false);\n const [editingId, setEditingId] = useState<string | null>(null);\n const [form, setForm] = useState<FormState>(emptyFormState);\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n\n const items = useMemo<InstructionFile[]>(\n () => data?.agentInstructionFiles?.items ?? [],\n [data?.agentInstructionFiles?.items]\n );\n\n const submitting = creating || updating;\n\n const openCreateForm = (): void => {\n setEditingId(null);\n setForm(emptyFormState());\n setFormError(null);\n setFormOpen(true);\n };\n\n const openEditForm = (file: InstructionFile): void => {\n setEditingId(file.id);\n setForm(formStateFromFile(file));\n setFormError(null);\n setFormOpen(true);\n };\n\n const closeForm = (): void => {\n setFormOpen(false);\n setEditingId(null);\n setForm(emptyFormState());\n setFormError(null);\n };\n\n const handleSubmit = async (): Promise<void> => {\n setFormError(null);\n\n if (form.filename === InstructionFilename.Custom && form.customName.trim() === '') {\n setFormError('Please provide a name for the custom instruction file.');\n return;\n }\n if (form.content.trim() === '') {\n setFormError('Instruction file content cannot be empty.');\n return;\n }\n\n const customName = form.filename === InstructionFilename.Custom ? form.customName.trim() : null;\n\n try {\n if (editingId) {\n // On edit only content / filename / customName / tags are updatable.\n const input: UpdateAgentInstructionFileInput = {\n content: form.content,\n filename: form.filename,\n customName,\n };\n await updateFile({ variables: { id: editingId, input } });\n } else {\n if (form.scope === InstructionScope.Vibe && !form.link.vibeId) {\n setFormError('Pick a vibe to link before saving a vibe-scoped file.');\n return;\n }\n\n const input: CreateAgentInstructionFileInput = {\n filename: form.filename,\n customName,\n content: form.content,\n scope: form.scope,\n };\n\n if (form.scope === InstructionScope.Vibe && form.link.vibeId) {\n input.vibeId = form.link.vibeId;\n input.visibility = toVibeVisibility(form.link.visibility);\n } else {\n input.agentId = agentId ?? null;\n }\n\n await createFile({ variables: { input } });\n }\n closeForm();\n } catch (submitErr) {\n setFormError(\n submitErr instanceof Error ? submitErr.message : 'Failed to save the instruction file.'\n );\n }\n };\n\n const handleDelete = async (id: string): Promise<void> => {\n try {\n await deleteFile({ variables: { id } });\n } finally {\n setConfirmDeleteId(null);\n }\n };\n\n return (\n <section\n data-testid=\"instruction-files-manager\"\n className=\"space-y-4 rounded-lg border border-border-default bg-bg-surface p-4\"\n >\n <header className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Instruction files</h2>\n <p className=\"max-w-2xl text-sm text-text-secondary\">\n AGENTS.md / CLAUDE.md / GEMINI.md maintained centrally and pushed to your agent on chat\n open.\n </p>\n </div>\n <button\n type=\"button\"\n data-testid=\"instruction-file-new\"\n className={PRIMARY_BTN_CLASS}\n onClick={formOpen && !editingId ? closeForm : openCreateForm}\n >\n {formOpen && !editingId ? 'Close' : 'New file'}\n </button>\n </header>\n\n {formOpen && (\n <div className=\"space-y-4 rounded-md border border-border-default bg-bg-elevated p-4\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {editingId ? 'Edit instruction file' : 'New instruction file'}\n </h3>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Filename</span>\n <select\n className={INPUT_CLASS}\n value={form.filename}\n onChange={(e) =>\n setForm((prev) => ({\n ...prev,\n filename: e.target.value as InstructionFilename,\n }))\n }\n >\n {FILENAME_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Scope</span>\n <select\n className={INPUT_CLASS}\n value={form.scope}\n disabled={editingId !== null}\n onChange={(e) =>\n setForm((prev) => ({\n ...prev,\n scope: e.target.value as InstructionScope,\n }))\n }\n >\n {SCOPE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n </div>\n\n {form.filename === InstructionFilename.Custom && (\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Custom name</span>\n <input\n type=\"text\"\n className={INPUT_CLASS}\n placeholder=\"e.g. CONTRIBUTING.md\"\n value={form.customName}\n onChange={(e) => setForm((prev) => ({ ...prev, customName: e.target.value }))}\n />\n </label>\n )}\n\n {!editingId && form.scope === InstructionScope.Vibe && (\n <LinkToVibePanel\n value={form.link}\n onChange={(link) => setForm((prev) => ({ ...prev, link }))}\n disabled={submitting}\n />\n )}\n\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Content</span>\n <textarea\n className={`${INPUT_CLASS} min-h-56 font-mono`}\n placeholder=\"# Project instructions…\"\n value={form.content}\n onChange={(e) => setForm((prev) => ({ ...prev, content: e.target.value }))}\n />\n </label>\n\n {formError && (\n <p className=\"text-sm text-action-danger-text\" role=\"alert\">\n {formError}\n </p>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-testid=\"instruction-file-save\"\n className={PRIMARY_BTN_CLASS}\n disabled={submitting}\n onClick={() => {\n void handleSubmit();\n }}\n >\n {submitting ? 'Saving…' : 'Save'}\n </button>\n <button\n type=\"button\"\n className={SECONDARY_BTN_CLASS}\n disabled={submitting}\n onClick={closeForm}\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {error ? (\n <p className=\"rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-action-danger-text\">\n Could not load instruction files: {error.message}\n </p>\n ) : loading && items.length === 0 ? (\n <p className=\"rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary\">\n Loading instruction files…\n </p>\n ) : items.length === 0 ? (\n <p className=\"rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary\">\n No instruction files yet. Create one to share it with your agent.\n </p>\n ) : (\n <ul className=\"space-y-2\">\n {items.map((file) => {\n const isConfirming = confirmDeleteId === file.id;\n const isShared = file.visibility === VibeVisibility.SharedWithVibe;\n const scopeLabel = file.scope === InstructionScope.Vibe ? 'Vibe' : 'Agent';\n return (\n <li\n key={file.id}\n data-testid=\"instruction-file-row\"\n className=\"flex flex-wrap items-center justify-between gap-3 rounded-md border border-border-default bg-bg-elevated p-3\"\n >\n <div className=\"min-w-0 space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-mono text-sm font-bold text-text-primary\">\n {file.effectiveFilename}\n </span>\n <span className={BADGE_CLASS}>{scopeLabel}</span>\n <span className={BADGE_CLASS}>{isShared ? 'Shared' : 'Private'}</span>\n </div>\n <p className=\"text-xs text-text-tertiary\">\n Updated {formatTimestamp(file.updatedAt)}\n </p>\n </div>\n\n <div className=\"flex items-center gap-2\">\n {isConfirming ? (\n <>\n <span className=\"text-xs text-text-secondary\">Delete this file?</span>\n <button\n type=\"button\"\n className={DANGER_BTN_CLASS}\n disabled={deleting}\n onClick={() => {\n void handleDelete(file.id);\n }}\n >\n {deleting ? 'Deleting…' : 'Confirm'}\n </button>\n <button\n type=\"button\"\n className={SECONDARY_BTN_CLASS}\n disabled={deleting}\n onClick={() => setConfirmDeleteId(null)}\n >\n Cancel\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n className={SECONDARY_BTN_CLASS}\n onClick={() => openEditForm(file)}\n >\n Edit\n </button>\n <EntityVibeLinkControl\n entityType={VibeEntityType.InstructionFile}\n entityId={file.id}\n currentVibeId={file.vibeId ?? null}\n currentVisibility={file.visibility}\n refetchQueries={['ListAgentInstructionFiles']}\n />\n <EntityShareButton\n entity=\"instructionfile\"\n resource={{\n id: file.id,\n name: file.effectiveFilename,\n vibeId: file.vibeId ?? null,\n }}\n label=\"Share\"\n />\n <button\n type=\"button\"\n className={DANGER_BTN_CLASS}\n onClick={() => setConfirmDeleteId(file.id)}\n >\n Delete\n </button>\n </>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InstructionFilesManager.js","names":[],"sources":["../../../src/components/ai/InstructionFilesManager.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n useListAgentInstructionFilesQuery,\n useCreateAgentInstructionFileMutation,\n useUpdateAgentInstructionFileMutation,\n useDeleteAgentInstructionFileMutation,\n} from '@/generated/wspace-operations';\nimport {\n InstructionFilename,\n InstructionScope,\n VibeVisibility,\n VibeEntityType,\n type CreateAgentInstructionFileInput,\n type UpdateAgentInstructionFileInput,\n} from '@/generated/wspace-types';\nimport {\n LinkToVibePanel,\n LINK_TO_VIBE_DEFAULT,\n type LinkToVibeValue,\n type LinkToVibeVisibility,\n} from '@/components/shared/LinkToVibePanel';\nimport { EntityVibeLinkControl } from '@/components/shared/EntityVibeLinkControl';\nimport { EntityShareButton } from '@/components/sharing';\nimport { CommandEditor } from '@/components/common/CommandEditor';\n\n/**\n * Shape of a single instruction file as returned by ListAgentInstructionFiles.\n * Mirrors the InstructionFileFields fragment in wspace-operations.\n */\ninterface InstructionFile {\n id: string;\n workspaceId: string;\n filename: InstructionFilename;\n customName?: string | null;\n effectiveFilename: string;\n content: string;\n scope: InstructionScope;\n agentId?: string | null;\n tags: string[];\n vibeId?: string | null;\n visibility: VibeVisibility;\n createdBy: string;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface InstructionFilesManagerProps {\n /** Default AGENT-scope target for newly-created files. */\n agentId?: string | null;\n}\n\nconst FILENAME_OPTIONS: ReadonlyArray<{ value: InstructionFilename; label: string }> = [\n { value: InstructionFilename.AgentsMd, label: 'AGENTS.md' },\n { value: InstructionFilename.ClaudeMd, label: 'CLAUDE.md' },\n { value: InstructionFilename.GeminiMd, label: 'GEMINI.md' },\n { value: InstructionFilename.Custom, label: 'Custom' },\n];\n\nconst SCOPE_OPTIONS: ReadonlyArray<{ value: InstructionScope; label: string }> = [\n { value: InstructionScope.Agent, label: 'Agent' },\n { value: InstructionScope.Vibe, label: 'Vibe' },\n];\n\nconst INPUT_CLASS =\n 'w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary';\n\nconst PRIMARY_BTN_CLASS =\n 'inline-flex items-center rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50';\n\nconst SECONDARY_BTN_CLASS =\n 'inline-flex items-center rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken';\n\nconst DANGER_BTN_CLASS =\n 'inline-flex items-center rounded-md bg-action-danger-bg px-3 py-2 text-sm font-medium text-action-danger-text disabled:opacity-50';\n\nconst BADGE_CLASS =\n 'inline-flex items-center rounded bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary';\n\n/** Internal state for the create/edit form. */\ninterface FormState {\n filename: InstructionFilename;\n customName: string;\n scope: InstructionScope;\n content: string;\n link: LinkToVibeValue;\n}\n\nfunction emptyFormState(): FormState {\n return {\n filename: InstructionFilename.AgentsMd,\n customName: '',\n scope: InstructionScope.Agent,\n content: '',\n link: LINK_TO_VIBE_DEFAULT,\n };\n}\n\n/** Map the file's stored visibility enum onto the LinkToVibePanel string union. */\nfunction toLinkVisibility(visibility: VibeVisibility): LinkToVibeVisibility {\n return visibility === VibeVisibility.SharedWithVibe ? 'SHARED_WITH_VIBE' : 'PRIVATE';\n}\n\n/** Map the LinkToVibePanel string union back onto the generated enum. */\nfunction toVibeVisibility(visibility: LinkToVibeVisibility): VibeVisibility {\n return visibility === 'SHARED_WITH_VIBE' ? VibeVisibility.SharedWithVibe : VibeVisibility.Private;\n}\n\nfunction formStateFromFile(file: InstructionFile): FormState {\n return {\n filename: file.filename,\n customName: file.customName ?? '',\n scope: file.scope,\n content: file.content,\n link: {\n vibeId: file.vibeId ?? null,\n visibility: toLinkVisibility(file.visibility),\n },\n };\n}\n\nfunction formatTimestamp(value: string): string {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return value;\n }\n return parsed.toLocaleString();\n}\n\nexport function InstructionFilesManager({\n agentId,\n}: InstructionFilesManagerProps): React.ReactElement {\n const { data, loading, error } = useListAgentInstructionFilesQuery({\n variables: {\n filter: agentId ? { agentId } : undefined,\n pagination: { limit: 100, offset: 0 },\n },\n fetchPolicy: 'cache-and-network',\n });\n\n const [createFile, { loading: creating }] = useCreateAgentInstructionFileMutation({\n refetchQueries: ['ListAgentInstructionFiles'],\n });\n const [updateFile, { loading: updating }] = useUpdateAgentInstructionFileMutation({\n refetchQueries: ['ListAgentInstructionFiles'],\n });\n const [deleteFile, { loading: deleting }] = useDeleteAgentInstructionFileMutation({\n refetchQueries: ['ListAgentInstructionFiles'],\n });\n\n const [formOpen, setFormOpen] = useState(false);\n const [editingId, setEditingId] = useState<string | null>(null);\n const [form, setForm] = useState<FormState>(emptyFormState);\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n\n const items = useMemo<InstructionFile[]>(\n () => data?.agentInstructionFiles?.items ?? [],\n [data?.agentInstructionFiles?.items]\n );\n\n const submitting = creating || updating;\n\n const openCreateForm = (): void => {\n setEditingId(null);\n setForm(emptyFormState());\n setFormError(null);\n setFormOpen(true);\n };\n\n const openEditForm = (file: InstructionFile): void => {\n setEditingId(file.id);\n setForm(formStateFromFile(file));\n setFormError(null);\n setFormOpen(true);\n };\n\n const closeForm = (): void => {\n setFormOpen(false);\n setEditingId(null);\n setForm(emptyFormState());\n setFormError(null);\n };\n\n const handleSubmit = async (): Promise<void> => {\n setFormError(null);\n\n if (form.filename === InstructionFilename.Custom && form.customName.trim() === '') {\n setFormError('Please provide a name for the custom instruction file.');\n return;\n }\n if (form.content.trim() === '') {\n setFormError('Instruction file content cannot be empty.');\n return;\n }\n\n const customName = form.filename === InstructionFilename.Custom ? form.customName.trim() : null;\n\n try {\n if (editingId) {\n // On edit only content / filename / customName / tags are updatable.\n const input: UpdateAgentInstructionFileInput = {\n content: form.content,\n filename: form.filename,\n customName,\n };\n await updateFile({ variables: { id: editingId, input } });\n } else {\n if (form.scope === InstructionScope.Vibe && !form.link.vibeId) {\n setFormError('Pick a vibe to link before saving a vibe-scoped file.');\n return;\n }\n\n const input: CreateAgentInstructionFileInput = {\n filename: form.filename,\n customName,\n content: form.content,\n scope: form.scope,\n };\n\n if (form.scope === InstructionScope.Vibe && form.link.vibeId) {\n input.vibeId = form.link.vibeId;\n input.visibility = toVibeVisibility(form.link.visibility);\n } else {\n input.agentId = agentId ?? null;\n }\n\n await createFile({ variables: { input } });\n }\n closeForm();\n } catch (submitErr) {\n setFormError(\n submitErr instanceof Error ? submitErr.message : 'Failed to save the instruction file.'\n );\n }\n };\n\n const handleDelete = async (id: string): Promise<void> => {\n try {\n await deleteFile({ variables: { id } });\n } finally {\n setConfirmDeleteId(null);\n }\n };\n\n return (\n <section\n data-testid=\"instruction-files-manager\"\n className=\"space-y-4 rounded-lg border border-border-default bg-bg-surface p-4\"\n >\n <header className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Instruction files</h2>\n <p className=\"max-w-2xl text-sm text-text-secondary\">\n AGENTS.md / CLAUDE.md / GEMINI.md maintained centrally and pushed to your agent on chat\n open.\n </p>\n </div>\n <button\n type=\"button\"\n data-testid=\"instruction-file-new\"\n className={PRIMARY_BTN_CLASS}\n onClick={formOpen && !editingId ? closeForm : openCreateForm}\n >\n {formOpen && !editingId ? 'Close' : 'New file'}\n </button>\n </header>\n\n {formOpen && (\n <div className=\"space-y-4 rounded-md border border-border-default bg-bg-elevated p-4\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {editingId ? 'Edit instruction file' : 'New instruction file'}\n </h3>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Filename</span>\n <select\n className={INPUT_CLASS}\n value={form.filename}\n onChange={(e) =>\n setForm((prev) => ({\n ...prev,\n filename: e.target.value as InstructionFilename,\n }))\n }\n >\n {FILENAME_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Scope</span>\n <select\n className={INPUT_CLASS}\n value={form.scope}\n disabled={editingId !== null}\n onChange={(e) =>\n setForm((prev) => ({\n ...prev,\n scope: e.target.value as InstructionScope,\n }))\n }\n >\n {SCOPE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n </div>\n\n {form.filename === InstructionFilename.Custom && (\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Custom name</span>\n <input\n type=\"text\"\n className={INPUT_CLASS}\n placeholder=\"e.g. CONTRIBUTING.md\"\n value={form.customName}\n onChange={(e) => setForm((prev) => ({ ...prev, customName: e.target.value }))}\n />\n </label>\n )}\n\n {!editingId && form.scope === InstructionScope.Vibe && (\n <LinkToVibePanel\n value={form.link}\n onChange={(link) => setForm((prev) => ({ ...prev, link }))}\n disabled={submitting}\n />\n )}\n\n <label className=\"space-y-1.5\">\n <span className=\"block text-sm font-medium text-text-secondary\">Content</span>\n <CommandEditor\n language=\"markdown\"\n rows={12}\n style={{ minHeight: '14rem' }}\n placeholder=\"# Project instructions…\"\n value={form.content}\n onChange={(e) => setForm((prev) => ({ ...prev, content: e.target.value }))}\n />\n </label>\n\n {formError && (\n <p className=\"text-sm text-action-danger-text\" role=\"alert\">\n {formError}\n </p>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-testid=\"instruction-file-save\"\n className={PRIMARY_BTN_CLASS}\n disabled={submitting}\n onClick={() => {\n void handleSubmit();\n }}\n >\n {submitting ? 'Saving…' : 'Save'}\n </button>\n <button\n type=\"button\"\n className={SECONDARY_BTN_CLASS}\n disabled={submitting}\n onClick={closeForm}\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {error ? (\n <p className=\"rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-action-danger-text\">\n Could not load instruction files: {error.message}\n </p>\n ) : loading && items.length === 0 ? (\n <p className=\"rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary\">\n Loading instruction files…\n </p>\n ) : items.length === 0 ? (\n <p className=\"rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary\">\n No instruction files yet. Create one to share it with your agent.\n </p>\n ) : (\n <ul className=\"space-y-2\">\n {items.map((file) => {\n const isConfirming = confirmDeleteId === file.id;\n const isShared = file.visibility === VibeVisibility.SharedWithVibe;\n const scopeLabel = file.scope === InstructionScope.Vibe ? 'Vibe' : 'Agent';\n return (\n <li\n key={file.id}\n data-testid=\"instruction-file-row\"\n className=\"flex flex-wrap items-center justify-between gap-3 rounded-md border border-border-default bg-bg-elevated p-3\"\n >\n <div className=\"min-w-0 space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-mono text-sm font-bold text-text-primary\">\n {file.effectiveFilename}\n </span>\n <span className={BADGE_CLASS}>{scopeLabel}</span>\n <span className={BADGE_CLASS}>{isShared ? 'Shared' : 'Private'}</span>\n </div>\n <p className=\"text-xs text-text-tertiary\">\n Updated {formatTimestamp(file.updatedAt)}\n </p>\n </div>\n\n <div className=\"flex items-center gap-2\">\n {isConfirming ? (\n <>\n <span className=\"text-xs text-text-secondary\">Delete this file?</span>\n <button\n type=\"button\"\n className={DANGER_BTN_CLASS}\n disabled={deleting}\n onClick={() => {\n void handleDelete(file.id);\n }}\n >\n {deleting ? 'Deleting…' : 'Confirm'}\n </button>\n <button\n type=\"button\"\n className={SECONDARY_BTN_CLASS}\n disabled={deleting}\n onClick={() => setConfirmDeleteId(null)}\n >\n Cancel\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n className={SECONDARY_BTN_CLASS}\n onClick={() => openEditForm(file)}\n >\n Edit\n </button>\n <EntityVibeLinkControl\n entityType={VibeEntityType.InstructionFile}\n entityId={file.id}\n currentVibeId={file.vibeId ?? null}\n currentVisibility={file.visibility}\n refetchQueries={['ListAgentInstructionFiles']}\n />\n <EntityShareButton\n entity=\"instructionfile\"\n resource={{\n id: file.id,\n name: file.effectiveFilename,\n vibeId: file.vibeId ?? null,\n }}\n label=\"Share\"\n />\n <button\n type=\"button\"\n className={DANGER_BTN_CLASS}\n onClick={() => setConfirmDeleteId(file.id)}\n >\n Delete\n </button>\n </>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
|