@burdenoff/microfe-vibecontrols 2026.601.21 → 2026.601.22
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/ActionCard.js +77 -66
- package/dist/components/actions/ActionCard.js.map +1 -1
- package/dist/components/ai/AIContextsTab.js +186 -173
- package/dist/components/ai/AIContextsTab.js.map +1 -1
- package/dist/components/ai/AITemplatesTab.js +135 -125
- package/dist/components/ai/AITemplatesTab.js.map +1 -1
- package/dist/components/ai/InstructionFilesManager.js +151 -137
- package/dist/components/ai/InstructionFilesManager.js.map +1 -1
- package/dist/components/notes/NotesTabPanel.js +8 -8
- package/dist/components/sharing/EntityShareButton.js +58 -0
- package/dist/components/sharing/EntityShareButton.js.map +1 -0
- package/dist/components/sharing/entityShareOps.js +277 -0
- package/dist/components/sharing/entityShareOps.js.map +1 -0
- package/dist/components/sharing/index.js +3 -0
- package/dist/components/sharing/shareRegistry.js +25 -0
- package/dist/components/sharing/shareRegistry.js.map +1 -1
- package/dist/components/sharing/useEntityShareController.js +88 -0
- package/dist/components/sharing/useEntityShareController.js.map +1 -0
- package/dist/constants/permissions.js +5 -0
- package/dist/constants/permissions.js.map +1 -1
- package/dist/pages/ActionsPage.js +162 -162
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +1 -1
- package/dist/pages/VibeDetailsPage.js +484 -484
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/tunnels/TunnelDetailsPage.js +91 -77
- package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useCreateAgentInstructionFileMutation as e, useDeleteAgentInstructionFileMutation as t, useListAgentInstructionFilesQuery as n, useUpdateAgentInstructionFileMutation as r } from "../../generated/wspace-operations.js";
|
|
2
2
|
import { InstructionFilename as i, InstructionScope as a, VibeVisibility as o } from "../../generated/wspace-types.js";
|
|
3
3
|
import { LINK_TO_VIBE_DEFAULT as s, LinkToVibePanel as c } from "../shared/LinkToVibePanel.js";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { EntityShareButton as l } from "../sharing/EntityShareButton.js";
|
|
5
|
+
import "../sharing/index.js";
|
|
6
|
+
import { useMemo as u, useState as d } from "react";
|
|
7
|
+
import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
6
8
|
//#region src/components/ai/InstructionFilesManager.tsx
|
|
7
|
-
var
|
|
9
|
+
var h = [
|
|
8
10
|
{
|
|
9
11
|
value: i.AgentsMd,
|
|
10
12
|
label: "AGENTS.md"
|
|
@@ -21,14 +23,14 @@ var m = [
|
|
|
21
23
|
value: i.Custom,
|
|
22
24
|
label: "Custom"
|
|
23
25
|
}
|
|
24
|
-
],
|
|
26
|
+
], g = [{
|
|
25
27
|
value: a.Agent,
|
|
26
28
|
label: "Agent"
|
|
27
29
|
}, {
|
|
28
30
|
value: a.Vibe,
|
|
29
31
|
label: "Vibe"
|
|
30
|
-
}],
|
|
31
|
-
function
|
|
32
|
+
}], _ = "w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary", v = "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", y = "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", b = "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", x = "inline-flex items-center rounded bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary";
|
|
33
|
+
function S() {
|
|
32
34
|
return {
|
|
33
35
|
filename: i.AgentsMd,
|
|
34
36
|
customName: "",
|
|
@@ -37,13 +39,13 @@ function x() {
|
|
|
37
39
|
link: s
|
|
38
40
|
};
|
|
39
41
|
}
|
|
40
|
-
function
|
|
42
|
+
function C(e) {
|
|
41
43
|
return e === o.SharedWithVibe ? "SHARED_WITH_VIBE" : "PRIVATE";
|
|
42
44
|
}
|
|
43
|
-
function
|
|
45
|
+
function w(e) {
|
|
44
46
|
return e === "SHARED_WITH_VIBE" ? o.SharedWithVibe : o.Private;
|
|
45
47
|
}
|
|
46
|
-
function
|
|
48
|
+
function T(e) {
|
|
47
49
|
return {
|
|
48
50
|
filename: e.filename,
|
|
49
51
|
customName: e.customName ?? "",
|
|
@@ -51,16 +53,16 @@ function w(e) {
|
|
|
51
53
|
content: e.content,
|
|
52
54
|
link: {
|
|
53
55
|
vibeId: e.vibeId ?? null,
|
|
54
|
-
visibility:
|
|
56
|
+
visibility: C(e.visibility)
|
|
55
57
|
}
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
|
-
function
|
|
60
|
+
function E(e) {
|
|
59
61
|
let t = new Date(e);
|
|
60
62
|
return Number.isNaN(t.getTime()) ? e : t.toLocaleString();
|
|
61
63
|
}
|
|
62
|
-
function
|
|
63
|
-
let { data:
|
|
64
|
+
function D({ agentId: s }) {
|
|
65
|
+
let { data: C, loading: D, error: O } = n({
|
|
64
66
|
variables: {
|
|
65
67
|
filter: s ? { agentId: s } : void 0,
|
|
66
68
|
pagination: {
|
|
@@ -69,261 +71,273 @@ function E({ agentId: s }) {
|
|
|
69
71
|
}
|
|
70
72
|
},
|
|
71
73
|
fetchPolicy: "cache-and-network"
|
|
72
|
-
}), [
|
|
73
|
-
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
},
|
|
79
|
-
if (
|
|
80
|
-
|
|
74
|
+
}), [k, { loading: A }] = e({ refetchQueries: ["ListAgentInstructionFiles"] }), [j, { loading: M }] = r({ refetchQueries: ["ListAgentInstructionFiles"] }), [N, { loading: P }] = t({ refetchQueries: ["ListAgentInstructionFiles"] }), [F, I] = d(!1), [L, R] = d(null), [z, B] = d(S), [V, H] = d(null), [U, W] = d(null), G = u(() => C?.agentInstructionFiles?.items ?? [], [C?.agentInstructionFiles?.items]), K = A || M, q = () => {
|
|
75
|
+
R(null), B(S()), W(null), I(!0);
|
|
76
|
+
}, J = (e) => {
|
|
77
|
+
R(e.id), B(T(e)), W(null), I(!0);
|
|
78
|
+
}, Y = () => {
|
|
79
|
+
I(!1), R(null), B(S()), W(null);
|
|
80
|
+
}, X = async () => {
|
|
81
|
+
if (W(null), z.filename === i.Custom && z.customName.trim() === "") {
|
|
82
|
+
W("Please provide a name for the custom instruction file.");
|
|
81
83
|
return;
|
|
82
84
|
}
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
+
if (z.content.trim() === "") {
|
|
86
|
+
W("Instruction file content cannot be empty.");
|
|
85
87
|
return;
|
|
86
88
|
}
|
|
87
|
-
let e =
|
|
89
|
+
let e = z.filename === i.Custom ? z.customName.trim() : null;
|
|
88
90
|
try {
|
|
89
|
-
if (
|
|
90
|
-
id:
|
|
91
|
+
if (L) await j({ variables: {
|
|
92
|
+
id: L,
|
|
91
93
|
input: {
|
|
92
|
-
content:
|
|
93
|
-
filename:
|
|
94
|
+
content: z.content,
|
|
95
|
+
filename: z.filename,
|
|
94
96
|
customName: e
|
|
95
97
|
}
|
|
96
98
|
} });
|
|
97
99
|
else {
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
+
if (z.scope === a.Vibe && !z.link.vibeId) {
|
|
101
|
+
W("Pick a vibe to link before saving a vibe-scoped file.");
|
|
100
102
|
return;
|
|
101
103
|
}
|
|
102
104
|
let t = {
|
|
103
|
-
filename:
|
|
105
|
+
filename: z.filename,
|
|
104
106
|
customName: e,
|
|
105
|
-
content:
|
|
106
|
-
scope:
|
|
107
|
+
content: z.content,
|
|
108
|
+
scope: z.scope
|
|
107
109
|
};
|
|
108
|
-
|
|
110
|
+
z.scope === a.Vibe && z.link.vibeId ? (t.vibeId = z.link.vibeId, t.visibility = w(z.link.visibility)) : t.agentId = s ?? null, await k({ variables: { input: t } });
|
|
109
111
|
}
|
|
110
|
-
|
|
112
|
+
Y();
|
|
111
113
|
} catch (e) {
|
|
112
|
-
|
|
114
|
+
W(e instanceof Error ? e.message : "Failed to save the instruction file.");
|
|
113
115
|
}
|
|
114
|
-
},
|
|
116
|
+
}, Z = async (e) => {
|
|
115
117
|
try {
|
|
116
|
-
await
|
|
118
|
+
await N({ variables: { id: e } });
|
|
117
119
|
} finally {
|
|
118
|
-
|
|
120
|
+
H(null);
|
|
119
121
|
}
|
|
120
122
|
};
|
|
121
|
-
return /* @__PURE__ */
|
|
123
|
+
return /* @__PURE__ */ m("section", {
|
|
122
124
|
"data-testid": "instruction-files-manager",
|
|
123
125
|
className: "space-y-4 rounded-lg border border-border-default bg-bg-surface p-4",
|
|
124
126
|
children: [
|
|
125
|
-
/* @__PURE__ */
|
|
127
|
+
/* @__PURE__ */ m("header", {
|
|
126
128
|
className: "flex flex-wrap items-start justify-between gap-3",
|
|
127
|
-
children: [/* @__PURE__ */
|
|
129
|
+
children: [/* @__PURE__ */ m("div", {
|
|
128
130
|
className: "space-y-1",
|
|
129
|
-
children: [/* @__PURE__ */
|
|
131
|
+
children: [/* @__PURE__ */ p("h2", {
|
|
130
132
|
className: "text-lg font-semibold text-text-primary",
|
|
131
133
|
children: "Instruction files"
|
|
132
|
-
}), /* @__PURE__ */
|
|
134
|
+
}), /* @__PURE__ */ p("p", {
|
|
133
135
|
className: "max-w-2xl text-sm text-text-secondary",
|
|
134
136
|
children: "AGENTS.md / CLAUDE.md / GEMINI.md maintained centrally and pushed to your agent on chat open."
|
|
135
137
|
})]
|
|
136
|
-
}), /* @__PURE__ */
|
|
138
|
+
}), /* @__PURE__ */ p("button", {
|
|
137
139
|
type: "button",
|
|
138
140
|
"data-testid": "instruction-file-new",
|
|
139
|
-
className:
|
|
140
|
-
onClick:
|
|
141
|
-
children:
|
|
141
|
+
className: v,
|
|
142
|
+
onClick: F && !L ? Y : q,
|
|
143
|
+
children: F && !L ? "Close" : "New file"
|
|
142
144
|
})]
|
|
143
145
|
}),
|
|
144
|
-
|
|
146
|
+
F && /* @__PURE__ */ m("div", {
|
|
145
147
|
className: "space-y-4 rounded-md border border-border-default bg-bg-elevated p-4",
|
|
146
148
|
children: [
|
|
147
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ p("h3", {
|
|
148
150
|
className: "text-sm font-medium text-text-primary",
|
|
149
|
-
children:
|
|
151
|
+
children: L ? "Edit instruction file" : "New instruction file"
|
|
150
152
|
}),
|
|
151
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ m("div", {
|
|
152
154
|
className: "grid gap-4 sm:grid-cols-2",
|
|
153
|
-
children: [/* @__PURE__ */
|
|
155
|
+
children: [/* @__PURE__ */ m("label", {
|
|
154
156
|
className: "space-y-1.5",
|
|
155
|
-
children: [/* @__PURE__ */
|
|
157
|
+
children: [/* @__PURE__ */ p("span", {
|
|
156
158
|
className: "block text-sm font-medium text-text-secondary",
|
|
157
159
|
children: "Filename"
|
|
158
|
-
}), /* @__PURE__ */
|
|
159
|
-
className:
|
|
160
|
-
value:
|
|
161
|
-
onChange: (e) =>
|
|
160
|
+
}), /* @__PURE__ */ p("select", {
|
|
161
|
+
className: _,
|
|
162
|
+
value: z.filename,
|
|
163
|
+
onChange: (e) => B((t) => ({
|
|
162
164
|
...t,
|
|
163
165
|
filename: e.target.value
|
|
164
166
|
})),
|
|
165
|
-
children:
|
|
167
|
+
children: h.map((e) => /* @__PURE__ */ p("option", {
|
|
166
168
|
value: e.value,
|
|
167
169
|
children: e.label
|
|
168
170
|
}, e.value))
|
|
169
171
|
})]
|
|
170
|
-
}), /* @__PURE__ */
|
|
172
|
+
}), /* @__PURE__ */ m("label", {
|
|
171
173
|
className: "space-y-1.5",
|
|
172
|
-
children: [/* @__PURE__ */
|
|
174
|
+
children: [/* @__PURE__ */ p("span", {
|
|
173
175
|
className: "block text-sm font-medium text-text-secondary",
|
|
174
176
|
children: "Scope"
|
|
175
|
-
}), /* @__PURE__ */
|
|
176
|
-
className:
|
|
177
|
-
value:
|
|
178
|
-
disabled:
|
|
179
|
-
onChange: (e) =>
|
|
177
|
+
}), /* @__PURE__ */ p("select", {
|
|
178
|
+
className: _,
|
|
179
|
+
value: z.scope,
|
|
180
|
+
disabled: L !== null,
|
|
181
|
+
onChange: (e) => B((t) => ({
|
|
180
182
|
...t,
|
|
181
183
|
scope: e.target.value
|
|
182
184
|
})),
|
|
183
|
-
children:
|
|
185
|
+
children: g.map((e) => /* @__PURE__ */ p("option", {
|
|
184
186
|
value: e.value,
|
|
185
187
|
children: e.label
|
|
186
188
|
}, e.value))
|
|
187
189
|
})]
|
|
188
190
|
})]
|
|
189
191
|
}),
|
|
190
|
-
|
|
192
|
+
z.filename === i.Custom && /* @__PURE__ */ m("label", {
|
|
191
193
|
className: "space-y-1.5",
|
|
192
|
-
children: [/* @__PURE__ */
|
|
194
|
+
children: [/* @__PURE__ */ p("span", {
|
|
193
195
|
className: "block text-sm font-medium text-text-secondary",
|
|
194
196
|
children: "Custom name"
|
|
195
|
-
}), /* @__PURE__ */
|
|
197
|
+
}), /* @__PURE__ */ p("input", {
|
|
196
198
|
type: "text",
|
|
197
|
-
className:
|
|
199
|
+
className: _,
|
|
198
200
|
placeholder: "e.g. CONTRIBUTING.md",
|
|
199
|
-
value:
|
|
200
|
-
onChange: (e) =>
|
|
201
|
+
value: z.customName,
|
|
202
|
+
onChange: (e) => B((t) => ({
|
|
201
203
|
...t,
|
|
202
204
|
customName: e.target.value
|
|
203
205
|
}))
|
|
204
206
|
})]
|
|
205
207
|
}),
|
|
206
|
-
!
|
|
207
|
-
value:
|
|
208
|
-
onChange: (e) =>
|
|
208
|
+
!L && z.scope === a.Vibe && /* @__PURE__ */ p(c, {
|
|
209
|
+
value: z.link,
|
|
210
|
+
onChange: (e) => B((t) => ({
|
|
209
211
|
...t,
|
|
210
212
|
link: e
|
|
211
213
|
})),
|
|
212
|
-
disabled:
|
|
214
|
+
disabled: K
|
|
213
215
|
}),
|
|
214
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ m("label", {
|
|
215
217
|
className: "space-y-1.5",
|
|
216
|
-
children: [/* @__PURE__ */
|
|
218
|
+
children: [/* @__PURE__ */ p("span", {
|
|
217
219
|
className: "block text-sm font-medium text-text-secondary",
|
|
218
220
|
children: "Content"
|
|
219
|
-
}), /* @__PURE__ */
|
|
220
|
-
className: `${
|
|
221
|
+
}), /* @__PURE__ */ p("textarea", {
|
|
222
|
+
className: `${_} min-h-56 font-mono`,
|
|
221
223
|
placeholder: "# Project instructions…",
|
|
222
|
-
value:
|
|
223
|
-
onChange: (e) =>
|
|
224
|
+
value: z.content,
|
|
225
|
+
onChange: (e) => B((t) => ({
|
|
224
226
|
...t,
|
|
225
227
|
content: e.target.value
|
|
226
228
|
}))
|
|
227
229
|
})]
|
|
228
230
|
}),
|
|
229
|
-
|
|
231
|
+
U && /* @__PURE__ */ p("p", {
|
|
230
232
|
className: "text-sm text-action-danger-text",
|
|
231
233
|
role: "alert",
|
|
232
|
-
children:
|
|
234
|
+
children: U
|
|
233
235
|
}),
|
|
234
|
-
/* @__PURE__ */
|
|
236
|
+
/* @__PURE__ */ m("div", {
|
|
235
237
|
className: "flex items-center gap-2",
|
|
236
|
-
children: [/* @__PURE__ */
|
|
238
|
+
children: [/* @__PURE__ */ p("button", {
|
|
237
239
|
type: "button",
|
|
238
240
|
"data-testid": "instruction-file-save",
|
|
239
|
-
className:
|
|
240
|
-
disabled:
|
|
241
|
+
className: v,
|
|
242
|
+
disabled: K,
|
|
241
243
|
onClick: () => {
|
|
242
|
-
|
|
244
|
+
X();
|
|
243
245
|
},
|
|
244
|
-
children:
|
|
245
|
-
}), /* @__PURE__ */
|
|
246
|
+
children: K ? "Saving…" : "Save"
|
|
247
|
+
}), /* @__PURE__ */ p("button", {
|
|
246
248
|
type: "button",
|
|
247
|
-
className:
|
|
248
|
-
disabled:
|
|
249
|
-
onClick:
|
|
249
|
+
className: y,
|
|
250
|
+
disabled: K,
|
|
251
|
+
onClick: Y,
|
|
250
252
|
children: "Cancel"
|
|
251
253
|
})]
|
|
252
254
|
})
|
|
253
255
|
]
|
|
254
256
|
}),
|
|
255
|
-
|
|
257
|
+
O ? /* @__PURE__ */ m("p", {
|
|
256
258
|
className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-action-danger-text",
|
|
257
|
-
children: ["Could not load instruction files: ",
|
|
258
|
-
}) :
|
|
259
|
+
children: ["Could not load instruction files: ", O.message]
|
|
260
|
+
}) : D && G.length === 0 ? /* @__PURE__ */ p("p", {
|
|
259
261
|
className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary",
|
|
260
262
|
children: "Loading instruction files…"
|
|
261
|
-
}) :
|
|
263
|
+
}) : G.length === 0 ? /* @__PURE__ */ p("p", {
|
|
262
264
|
className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary",
|
|
263
265
|
children: "No instruction files yet. Create one to share it with your agent."
|
|
264
|
-
}) : /* @__PURE__ */
|
|
266
|
+
}) : /* @__PURE__ */ p("ul", {
|
|
265
267
|
className: "space-y-2",
|
|
266
|
-
children:
|
|
267
|
-
let t =
|
|
268
|
-
return /* @__PURE__ */
|
|
268
|
+
children: G.map((e) => {
|
|
269
|
+
let t = V === e.id, n = e.visibility === o.SharedWithVibe, r = e.scope === a.Vibe ? "Vibe" : "Agent";
|
|
270
|
+
return /* @__PURE__ */ m("li", {
|
|
269
271
|
"data-testid": "instruction-file-row",
|
|
270
272
|
className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-border-default bg-bg-elevated p-3",
|
|
271
|
-
children: [/* @__PURE__ */
|
|
273
|
+
children: [/* @__PURE__ */ m("div", {
|
|
272
274
|
className: "min-w-0 space-y-1",
|
|
273
|
-
children: [/* @__PURE__ */
|
|
275
|
+
children: [/* @__PURE__ */ m("div", {
|
|
274
276
|
className: "flex flex-wrap items-center gap-2",
|
|
275
277
|
children: [
|
|
276
|
-
/* @__PURE__ */
|
|
278
|
+
/* @__PURE__ */ p("span", {
|
|
277
279
|
className: "font-mono text-sm font-bold text-text-primary",
|
|
278
280
|
children: e.effectiveFilename
|
|
279
281
|
}),
|
|
280
|
-
/* @__PURE__ */
|
|
281
|
-
className:
|
|
282
|
+
/* @__PURE__ */ p("span", {
|
|
283
|
+
className: x,
|
|
282
284
|
children: r
|
|
283
285
|
}),
|
|
284
|
-
/* @__PURE__ */
|
|
285
|
-
className:
|
|
286
|
+
/* @__PURE__ */ p("span", {
|
|
287
|
+
className: x,
|
|
286
288
|
children: n ? "Shared" : "Private"
|
|
287
289
|
})
|
|
288
290
|
]
|
|
289
|
-
}), /* @__PURE__ */
|
|
291
|
+
}), /* @__PURE__ */ m("p", {
|
|
290
292
|
className: "text-xs text-text-tertiary",
|
|
291
|
-
children: ["Updated ",
|
|
293
|
+
children: ["Updated ", E(e.updatedAt)]
|
|
292
294
|
})]
|
|
293
|
-
}), /* @__PURE__ */
|
|
295
|
+
}), /* @__PURE__ */ p("div", {
|
|
294
296
|
className: "flex items-center gap-2",
|
|
295
|
-
children: t ? /* @__PURE__ */
|
|
296
|
-
/* @__PURE__ */
|
|
297
|
+
children: t ? /* @__PURE__ */ m(f, { children: [
|
|
298
|
+
/* @__PURE__ */ p("span", {
|
|
297
299
|
className: "text-xs text-text-secondary",
|
|
298
300
|
children: "Delete this file?"
|
|
299
301
|
}),
|
|
300
|
-
/* @__PURE__ */
|
|
302
|
+
/* @__PURE__ */ p("button", {
|
|
301
303
|
type: "button",
|
|
302
|
-
className:
|
|
303
|
-
disabled:
|
|
304
|
+
className: b,
|
|
305
|
+
disabled: P,
|
|
304
306
|
onClick: () => {
|
|
305
|
-
|
|
307
|
+
Z(e.id);
|
|
306
308
|
},
|
|
307
|
-
children:
|
|
309
|
+
children: P ? "Deleting…" : "Confirm"
|
|
308
310
|
}),
|
|
309
|
-
/* @__PURE__ */
|
|
311
|
+
/* @__PURE__ */ p("button", {
|
|
310
312
|
type: "button",
|
|
311
|
-
className:
|
|
312
|
-
disabled:
|
|
313
|
-
onClick: () =>
|
|
313
|
+
className: y,
|
|
314
|
+
disabled: P,
|
|
315
|
+
onClick: () => H(null),
|
|
314
316
|
children: "Cancel"
|
|
315
317
|
})
|
|
316
|
-
] }) : /* @__PURE__ */
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
318
|
+
] }) : /* @__PURE__ */ m(f, { children: [
|
|
319
|
+
/* @__PURE__ */ p("button", {
|
|
320
|
+
type: "button",
|
|
321
|
+
className: y,
|
|
322
|
+
onClick: () => J(e),
|
|
323
|
+
children: "Edit"
|
|
324
|
+
}),
|
|
325
|
+
/* @__PURE__ */ p(l, {
|
|
326
|
+
entity: "instructionfile",
|
|
327
|
+
resource: {
|
|
328
|
+
id: e.id,
|
|
329
|
+
name: e.effectiveFilename,
|
|
330
|
+
vibeId: e.vibeId ?? null
|
|
331
|
+
},
|
|
332
|
+
label: "Share"
|
|
333
|
+
}),
|
|
334
|
+
/* @__PURE__ */ p("button", {
|
|
335
|
+
type: "button",
|
|
336
|
+
className: b,
|
|
337
|
+
onClick: () => H(e.id),
|
|
338
|
+
children: "Delete"
|
|
339
|
+
})
|
|
340
|
+
] })
|
|
327
341
|
})]
|
|
328
342
|
}, e.id);
|
|
329
343
|
})
|
|
@@ -332,6 +346,6 @@ function E({ agentId: s }) {
|
|
|
332
346
|
});
|
|
333
347
|
}
|
|
334
348
|
//#endregion
|
|
335
|
-
export {
|
|
349
|
+
export { D as InstructionFilesManager };
|
|
336
350
|
|
|
337
351
|
//# 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 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';\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 <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 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 { 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 <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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"}
|
|
@@ -9,12 +9,12 @@ import { SearchInput as ue } from "../shared/SearchInput.js";
|
|
|
9
9
|
import { FilterDropdown as s } from "../shared/FilterDropdown.js";
|
|
10
10
|
import "../shared/index.js";
|
|
11
11
|
import { VIBE_PERMISSIONS as c } from "../../constants/permissions.js";
|
|
12
|
-
import { NoteCard as de } from "./NoteCard.js";
|
|
13
|
-
import { NoteList as fe } from "./NoteList.js";
|
|
14
|
-
import { NoteEditor as pe } from "./NoteEditor.js";
|
|
15
12
|
import { SHARE_REGISTRY as l } from "../sharing/shareRegistry.js";
|
|
16
|
-
import { NoteShareDialog as
|
|
13
|
+
import { NoteShareDialog as de } from "../sharing/NoteShareDialog.js";
|
|
17
14
|
import "../sharing/index.js";
|
|
15
|
+
import { NoteCard as fe } from "./NoteCard.js";
|
|
16
|
+
import { NoteList as pe } from "./NoteList.js";
|
|
17
|
+
import { NoteEditor as me } from "./NoteEditor.js";
|
|
18
18
|
import { useMemo as u, useState as d } from "react";
|
|
19
19
|
import { useI18n as he } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
20
20
|
import { FileText as ge, Globe as _e, Grid as ve, List as ye, Lock as be, Pin as xe, Plus as f, RefreshCw as Se } from "lucide-react";
|
|
@@ -394,7 +394,7 @@ function h({ context: h, vibeId: g, agentVibes: _ = [] }) {
|
|
|
394
394
|
children: K.length > 0 ? A === "grid" ? /* @__PURE__ */ p(je, {
|
|
395
395
|
stagger: .04,
|
|
396
396
|
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
397
|
-
children: K.map((e) => /* @__PURE__ */ p(Ae, { children: /* @__PURE__ */ p(
|
|
397
|
+
children: K.map((e) => /* @__PURE__ */ p(Ae, { children: /* @__PURE__ */ p(fe, {
|
|
398
398
|
note: e,
|
|
399
399
|
onOpen: q,
|
|
400
400
|
onEdit: q,
|
|
@@ -404,7 +404,7 @@ function h({ context: h, vibeId: g, agentVibes: _ = [] }) {
|
|
|
404
404
|
onShare: tt,
|
|
405
405
|
onShareAccess: Z
|
|
406
406
|
}) }, e.id))
|
|
407
|
-
}, "grid") : /* @__PURE__ */ p(
|
|
407
|
+
}, "grid") : /* @__PURE__ */ p(pe, {
|
|
408
408
|
notes: K,
|
|
409
409
|
onOpen: q,
|
|
410
410
|
onEdit: q,
|
|
@@ -425,7 +425,7 @@ function h({ context: h, vibeId: g, agentVibes: _ = [] }) {
|
|
|
425
425
|
}) : void 0
|
|
426
426
|
})
|
|
427
427
|
}),
|
|
428
|
-
Ue && /* @__PURE__ */ p(
|
|
428
|
+
Ue && /* @__PURE__ */ p(me, {
|
|
429
429
|
note: We || void 0,
|
|
430
430
|
vibeOptions: nt,
|
|
431
431
|
defaultVibeId: h === "vibe" ? g : void 0,
|
|
@@ -442,7 +442,7 @@ function h({ context: h, vibeId: g, agentVibes: _ = [] }) {
|
|
|
442
442
|
title: "Note Quota Reached",
|
|
443
443
|
message: "You've used all available note quota on your current plan. Upgrade your plan to create or update more notes."
|
|
444
444
|
}),
|
|
445
|
-
S && /* @__PURE__ */ p(
|
|
445
|
+
S && /* @__PURE__ */ p(de, {
|
|
446
446
|
note: {
|
|
447
447
|
id: S.id,
|
|
448
448
|
title: S.title,
|