@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.
@@ -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 { useMemo as f, useState as p } from "react";
8
- import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
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
- ], v = [{
28
+ ], y = [{
28
29
  value: a.Agent,
29
30
  label: "Agent"
30
31
  }, {
31
32
  value: a.Vibe,
32
33
  label: "Vibe"
33
- }], y = "w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary", b = "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", x = "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", S = "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", C = "inline-flex items-center rounded bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary";
34
- function w() {
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 T(e) {
44
+ function E(e) {
44
45
  return e === s.SharedWithVibe ? "SHARED_WITH_VIBE" : "PRIVATE";
45
46
  }
46
- function E(e) {
47
+ function D(e) {
47
48
  return e === "SHARED_WITH_VIBE" ? s.SharedWithVibe : s.Private;
48
49
  }
49
- function D(e) {
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: T(e.visibility)
58
+ visibility: E(e.visibility)
58
59
  }
59
60
  };
60
61
  }
61
- function O(e) {
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 k({ agentId: c }) {
66
- let { data: T, loading: k, error: A } = n({
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
- }), [j, { loading: M }] = e({ refetchQueries: ["ListAgentInstructionFiles"] }), [N, { loading: P }] = r({ refetchQueries: ["ListAgentInstructionFiles"] }), [F, { loading: I }] = t({ refetchQueries: ["ListAgentInstructionFiles"] }), [L, R] = p(!1), [z, B] = p(null), [V, H] = p(w), [U, W] = p(null), [G, K] = p(null), q = f(() => T?.agentInstructionFiles?.items ?? [], [T?.agentInstructionFiles?.items]), J = M || P, Y = () => {
76
- B(null), H(w()), K(null), R(!0);
77
- }, X = (e) => {
78
- B(e.id), H(D(e)), K(null), R(!0);
79
- }, Z = () => {
80
- R(!1), B(null), H(w()), K(null);
81
- }, Q = async () => {
82
- if (K(null), V.filename === i.Custom && V.customName.trim() === "") {
83
- K("Please provide a name for the custom instruction file.");
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 (V.content.trim() === "") {
87
- K("Instruction file content cannot be empty.");
87
+ if (H.content.trim() === "") {
88
+ q("Instruction file content cannot be empty.");
88
89
  return;
89
90
  }
90
- let e = V.filename === i.Custom ? V.customName.trim() : null;
91
+ let e = H.filename === i.Custom ? H.customName.trim() : null;
91
92
  try {
92
- if (z) await N({ variables: {
93
- id: z,
93
+ if (B) await P({ variables: {
94
+ id: B,
94
95
  input: {
95
- content: V.content,
96
- filename: V.filename,
96
+ content: H.content,
97
+ filename: H.filename,
97
98
  customName: e
98
99
  }
99
100
  } });
100
101
  else {
101
- if (V.scope === a.Vibe && !V.link.vibeId) {
102
- K("Pick a vibe to link before saving a vibe-scoped file.");
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: V.filename,
107
+ filename: H.filename,
107
108
  customName: e,
108
- content: V.content,
109
- scope: V.scope
109
+ content: H.content,
110
+ scope: H.scope
110
111
  };
111
- V.scope === a.Vibe && V.link.vibeId ? (t.vibeId = V.link.vibeId, t.visibility = E(V.link.visibility)) : t.agentId = c ?? null, await j({ variables: { input: t } });
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
- Z();
114
+ Q();
114
115
  } catch (e) {
115
- K(e instanceof Error ? e.message : "Failed to save the instruction file.");
116
+ q(e instanceof Error ? e.message : "Failed to save the instruction file.");
116
117
  }
117
- }, $ = async (e) => {
118
+ }, ee = async (e) => {
118
119
  try {
119
- await F({ variables: { id: e } });
120
+ await I({ variables: { id: e } });
120
121
  } finally {
121
- W(null);
122
+ G(null);
122
123
  }
123
124
  };
124
- return /* @__PURE__ */ g("section", {
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__ */ g("header", {
129
+ /* @__PURE__ */ _("header", {
129
130
  className: "flex flex-wrap items-start justify-between gap-3",
130
- children: [/* @__PURE__ */ g("div", {
131
+ children: [/* @__PURE__ */ _("div", {
131
132
  className: "space-y-1",
132
- children: [/* @__PURE__ */ h("h2", {
133
+ children: [/* @__PURE__ */ g("h2", {
133
134
  className: "text-lg font-semibold text-text-primary",
134
135
  children: "Instruction files"
135
- }), /* @__PURE__ */ h("p", {
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__ */ h("button", {
140
+ }), /* @__PURE__ */ g("button", {
140
141
  type: "button",
141
142
  "data-testid": "instruction-file-new",
142
- className: b,
143
- onClick: L && !z ? Z : Y,
144
- children: L && !z ? "Close" : "New file"
143
+ className: x,
144
+ onClick: R && !B ? Q : X,
145
+ children: R && !B ? "Close" : "New file"
145
146
  })]
146
147
  }),
147
- L && /* @__PURE__ */ g("div", {
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__ */ h("h3", {
151
+ /* @__PURE__ */ g("h3", {
151
152
  className: "text-sm font-medium text-text-primary",
152
- children: z ? "Edit instruction file" : "New instruction file"
153
+ children: B ? "Edit instruction file" : "New instruction file"
153
154
  }),
154
- /* @__PURE__ */ g("div", {
155
+ /* @__PURE__ */ _("div", {
155
156
  className: "grid gap-4 sm:grid-cols-2",
156
- children: [/* @__PURE__ */ g("label", {
157
+ children: [/* @__PURE__ */ _("label", {
157
158
  className: "space-y-1.5",
158
- children: [/* @__PURE__ */ h("span", {
159
+ children: [/* @__PURE__ */ g("span", {
159
160
  className: "block text-sm font-medium text-text-secondary",
160
161
  children: "Filename"
161
- }), /* @__PURE__ */ h("select", {
162
- className: y,
163
- value: V.filename,
164
- onChange: (e) => H((t) => ({
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: _.map((e) => /* @__PURE__ */ h("option", {
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__ */ g("label", {
174
+ }), /* @__PURE__ */ _("label", {
174
175
  className: "space-y-1.5",
175
- children: [/* @__PURE__ */ h("span", {
176
+ children: [/* @__PURE__ */ g("span", {
176
177
  className: "block text-sm font-medium text-text-secondary",
177
178
  children: "Scope"
178
- }), /* @__PURE__ */ h("select", {
179
- className: y,
180
- value: V.scope,
181
- disabled: z !== null,
182
- onChange: (e) => H((t) => ({
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: v.map((e) => /* @__PURE__ */ h("option", {
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
- V.filename === i.Custom && /* @__PURE__ */ g("label", {
194
+ H.filename === i.Custom && /* @__PURE__ */ _("label", {
194
195
  className: "space-y-1.5",
195
- children: [/* @__PURE__ */ h("span", {
196
+ children: [/* @__PURE__ */ g("span", {
196
197
  className: "block text-sm font-medium text-text-secondary",
197
198
  children: "Custom name"
198
- }), /* @__PURE__ */ h("input", {
199
+ }), /* @__PURE__ */ g("input", {
199
200
  type: "text",
200
- className: y,
201
+ className: b,
201
202
  placeholder: "e.g. CONTRIBUTING.md",
202
- value: V.customName,
203
- onChange: (e) => H((t) => ({
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
- !z && V.scope === a.Vibe && /* @__PURE__ */ h(l, {
210
- value: V.link,
211
- onChange: (e) => H((t) => ({
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: J
216
+ disabled: Y
216
217
  }),
217
- /* @__PURE__ */ g("label", {
218
+ /* @__PURE__ */ _("label", {
218
219
  className: "space-y-1.5",
219
- children: [/* @__PURE__ */ h("span", {
220
+ children: [/* @__PURE__ */ g("span", {
220
221
  className: "block text-sm font-medium text-text-secondary",
221
222
  children: "Content"
222
- }), /* @__PURE__ */ h("textarea", {
223
- className: `${y} min-h-56 font-mono`,
223
+ }), /* @__PURE__ */ g(f, {
224
+ language: "markdown",
225
+ rows: 12,
226
+ style: { minHeight: "14rem" },
224
227
  placeholder: "# Project instructions…",
225
- value: V.content,
226
- onChange: (e) => H((t) => ({
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
- G && /* @__PURE__ */ h("p", {
235
+ K && /* @__PURE__ */ g("p", {
233
236
  className: "text-sm text-action-danger-text",
234
237
  role: "alert",
235
- children: G
238
+ children: K
236
239
  }),
237
- /* @__PURE__ */ g("div", {
240
+ /* @__PURE__ */ _("div", {
238
241
  className: "flex items-center gap-2",
239
- children: [/* @__PURE__ */ h("button", {
242
+ children: [/* @__PURE__ */ g("button", {
240
243
  type: "button",
241
244
  "data-testid": "instruction-file-save",
242
- className: b,
243
- disabled: J,
245
+ className: x,
246
+ disabled: Y,
244
247
  onClick: () => {
245
- Q();
248
+ $();
246
249
  },
247
- children: J ? "Saving…" : "Save"
248
- }), /* @__PURE__ */ h("button", {
250
+ children: Y ? "Saving…" : "Save"
251
+ }), /* @__PURE__ */ g("button", {
249
252
  type: "button",
250
- className: x,
251
- disabled: J,
252
- onClick: Z,
253
+ className: S,
254
+ disabled: Y,
255
+ onClick: Q,
253
256
  children: "Cancel"
254
257
  })]
255
258
  })
256
259
  ]
257
260
  }),
258
- A ? /* @__PURE__ */ g("p", {
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: ", A.message]
261
- }) : k && q.length === 0 ? /* @__PURE__ */ h("p", {
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
- }) : q.length === 0 ? /* @__PURE__ */ h("p", {
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__ */ h("ul", {
270
+ }) : /* @__PURE__ */ g("ul", {
268
271
  className: "space-y-2",
269
- children: q.map((e) => {
270
- let t = U === e.id, n = e.visibility === s.SharedWithVibe, r = e.scope === a.Vibe ? "Vibe" : "Agent";
271
- return /* @__PURE__ */ g("li", {
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__ */ g("div", {
277
+ children: [/* @__PURE__ */ _("div", {
275
278
  className: "min-w-0 space-y-1",
276
- children: [/* @__PURE__ */ g("div", {
279
+ children: [/* @__PURE__ */ _("div", {
277
280
  className: "flex flex-wrap items-center gap-2",
278
281
  children: [
279
- /* @__PURE__ */ h("span", {
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__ */ h("span", {
284
- className: C,
286
+ /* @__PURE__ */ g("span", {
287
+ className: w,
285
288
  children: r
286
289
  }),
287
- /* @__PURE__ */ h("span", {
288
- className: C,
290
+ /* @__PURE__ */ g("span", {
291
+ className: w,
289
292
  children: n ? "Shared" : "Private"
290
293
  })
291
294
  ]
292
- }), /* @__PURE__ */ g("p", {
295
+ }), /* @__PURE__ */ _("p", {
293
296
  className: "text-xs text-text-tertiary",
294
- children: ["Updated ", O(e.updatedAt)]
297
+ children: ["Updated ", k(e.updatedAt)]
295
298
  })]
296
- }), /* @__PURE__ */ h("div", {
299
+ }), /* @__PURE__ */ g("div", {
297
300
  className: "flex items-center gap-2",
298
- children: t ? /* @__PURE__ */ g(m, { children: [
299
- /* @__PURE__ */ h("span", {
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__ */ h("button", {
306
+ /* @__PURE__ */ g("button", {
304
307
  type: "button",
305
- className: S,
306
- disabled: I,
308
+ className: C,
309
+ disabled: L,
307
310
  onClick: () => {
308
- $(e.id);
311
+ ee(e.id);
309
312
  },
310
- children: I ? "Deleting…" : "Confirm"
313
+ children: L ? "Deleting…" : "Confirm"
311
314
  }),
312
- /* @__PURE__ */ h("button", {
315
+ /* @__PURE__ */ g("button", {
313
316
  type: "button",
314
- className: x,
315
- disabled: I,
316
- onClick: () => W(null),
317
+ className: S,
318
+ disabled: L,
319
+ onClick: () => G(null),
317
320
  children: "Cancel"
318
321
  })
319
- ] }) : /* @__PURE__ */ g(m, { children: [
320
- /* @__PURE__ */ h("button", {
322
+ ] }) : /* @__PURE__ */ _(h, { children: [
323
+ /* @__PURE__ */ g("button", {
321
324
  type: "button",
322
- className: x,
323
- onClick: () => X(e),
325
+ className: S,
326
+ onClick: () => Z(e),
324
327
  children: "Edit"
325
328
  }),
326
- /* @__PURE__ */ h(u, {
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__ */ h(d, {
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__ */ h("button", {
345
+ /* @__PURE__ */ g("button", {
343
346
  type: "button",
344
- className: S,
345
- onClick: () => W(e.id),
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 { k as InstructionFilesManager };
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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"}