@burdenoff/microfe-vibecontrols 2026.602.2 → 2026.602.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/components/actions/ActionCard.js +87 -74
  2. package/dist/components/actions/ActionCard.js.map +1 -1
  3. package/dist/components/ai/InstructionFilesManager.js +149 -141
  4. package/dist/components/ai/InstructionFilesManager.js.map +1 -1
  5. package/dist/components/sessions/SessionShareDialog.js +24 -462
  6. package/dist/components/sessions/SessionShareDialog.js.map +1 -1
  7. package/dist/components/shared/EntityVibeLinkControl.js +204 -0
  8. package/dist/components/shared/EntityVibeLinkControl.js.map +1 -0
  9. package/dist/components/shared/index.js +1 -0
  10. package/dist/components/sharing/entityShareOps.js +106 -0
  11. package/dist/components/sharing/entityShareOps.js.map +1 -1
  12. package/dist/components/sharing/shareRegistry.js +3 -3
  13. package/dist/components/sharing/shareRegistry.js.map +1 -1
  14. package/dist/components/tunnels/TunnelCard.js +51 -43
  15. package/dist/components/tunnels/TunnelCard.js.map +1 -1
  16. package/dist/components/vibe/VibeLinkedEntitiesPanel.js +117 -89
  17. package/dist/components/vibe/VibeLinkedEntitiesPanel.js.map +1 -1
  18. package/dist/components/vibedeck/VibeDeckShareDialog.js +19 -335
  19. package/dist/components/vibedeck/VibeDeckShareDialog.js.map +1 -1
  20. package/dist/constants/permissions.js +1 -0
  21. package/dist/constants/permissions.js.map +1 -1
  22. package/dist/generated/wspace-operations.js +1618 -1593
  23. package/dist/generated/wspace-operations.js.map +1 -1
  24. package/dist/generated/wspace-types.js +10 -10
  25. package/dist/generated/wspace-types.js.map +1 -1
  26. package/dist/index.js +10 -10
  27. package/dist/pages/SessionsPage.js +1011 -1007
  28. package/dist/pages/SessionsPage.js.map +1 -1
  29. package/dist/pages/VibeDeckPage.js +218 -210
  30. package/dist/pages/VibeDeckPage.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/utils/shareUrl.js +0 -41
  33. package/dist/utils/shareUrl.js.map +0 -1
@@ -1,12 +1,13 @@
1
1
  import { useCreateAgentInstructionFileMutation as e, useDeleteAgentInstructionFileMutation as t, useListAgentInstructionFilesQuery as n, useUpdateAgentInstructionFileMutation as r } from "../../generated/wspace-operations.js";
2
- import { InstructionFilename as i, InstructionScope as a, VibeVisibility as o } from "../../generated/wspace-types.js";
3
- import { LINK_TO_VIBE_DEFAULT as s, LinkToVibePanel as c } from "../shared/LinkToVibePanel.js";
4
- import { EntityShareButton as l } from "../sharing/EntityShareButton.js";
2
+ import { InstructionFilename as i, InstructionScope as a, VibeEntityType as o, VibeVisibility as s } from "../../generated/wspace-types.js";
3
+ import { LINK_TO_VIBE_DEFAULT as c, LinkToVibePanel as l } from "../shared/LinkToVibePanel.js";
4
+ import { EntityVibeLinkControl as u } from "../shared/EntityVibeLinkControl.js";
5
+ import { EntityShareButton as d } from "../sharing/EntityShareButton.js";
5
6
  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";
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";
8
9
  //#region src/components/ai/InstructionFilesManager.tsx
9
- var h = [
10
+ var _ = [
10
11
  {
11
12
  value: i.AgentsMd,
12
13
  label: "AGENTS.md"
@@ -23,29 +24,29 @@ var h = [
23
24
  value: i.Custom,
24
25
  label: "Custom"
25
26
  }
26
- ], g = [{
27
+ ], v = [{
27
28
  value: a.Agent,
28
29
  label: "Agent"
29
30
  }, {
30
31
  value: a.Vibe,
31
32
  label: "Vibe"
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() {
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
35
  return {
35
36
  filename: i.AgentsMd,
36
37
  customName: "",
37
38
  scope: a.Agent,
38
39
  content: "",
39
- link: s
40
+ link: c
40
41
  };
41
42
  }
42
- function C(e) {
43
- return e === o.SharedWithVibe ? "SHARED_WITH_VIBE" : "PRIVATE";
43
+ function T(e) {
44
+ return e === s.SharedWithVibe ? "SHARED_WITH_VIBE" : "PRIVATE";
44
45
  }
45
- function w(e) {
46
- return e === "SHARED_WITH_VIBE" ? o.SharedWithVibe : o.Private;
46
+ function E(e) {
47
+ return e === "SHARED_WITH_VIBE" ? s.SharedWithVibe : s.Private;
47
48
  }
48
- function T(e) {
49
+ function D(e) {
49
50
  return {
50
51
  filename: e.filename,
51
52
  customName: e.customName ?? "",
@@ -53,276 +54,283 @@ function T(e) {
53
54
  content: e.content,
54
55
  link: {
55
56
  vibeId: e.vibeId ?? null,
56
- visibility: C(e.visibility)
57
+ visibility: T(e.visibility)
57
58
  }
58
59
  };
59
60
  }
60
- function E(e) {
61
+ function O(e) {
61
62
  let t = new Date(e);
62
63
  return Number.isNaN(t.getTime()) ? e : t.toLocaleString();
63
64
  }
64
- function D({ agentId: s }) {
65
- let { data: C, loading: D, error: O } = n({
65
+ function k({ agentId: c }) {
66
+ let { data: T, loading: k, error: A } = n({
66
67
  variables: {
67
- filter: s ? { agentId: s } : void 0,
68
+ filter: c ? { agentId: c } : void 0,
68
69
  pagination: {
69
70
  limit: 100,
70
71
  offset: 0
71
72
  }
72
73
  },
73
74
  fetchPolicy: "cache-and-network"
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.");
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.");
83
84
  return;
84
85
  }
85
- if (z.content.trim() === "") {
86
- W("Instruction file content cannot be empty.");
86
+ if (V.content.trim() === "") {
87
+ K("Instruction file content cannot be empty.");
87
88
  return;
88
89
  }
89
- let e = z.filename === i.Custom ? z.customName.trim() : null;
90
+ let e = V.filename === i.Custom ? V.customName.trim() : null;
90
91
  try {
91
- if (L) await j({ variables: {
92
- id: L,
92
+ if (z) await N({ variables: {
93
+ id: z,
93
94
  input: {
94
- content: z.content,
95
- filename: z.filename,
95
+ content: V.content,
96
+ filename: V.filename,
96
97
  customName: e
97
98
  }
98
99
  } });
99
100
  else {
100
- if (z.scope === a.Vibe && !z.link.vibeId) {
101
- W("Pick a vibe to link before saving a vibe-scoped file.");
101
+ if (V.scope === a.Vibe && !V.link.vibeId) {
102
+ K("Pick a vibe to link before saving a vibe-scoped file.");
102
103
  return;
103
104
  }
104
105
  let t = {
105
- filename: z.filename,
106
+ filename: V.filename,
106
107
  customName: e,
107
- content: z.content,
108
- scope: z.scope
108
+ content: V.content,
109
+ scope: V.scope
109
110
  };
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 } });
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 } });
111
112
  }
112
- Y();
113
+ Z();
113
114
  } catch (e) {
114
- W(e instanceof Error ? e.message : "Failed to save the instruction file.");
115
+ K(e instanceof Error ? e.message : "Failed to save the instruction file.");
115
116
  }
116
- }, Z = async (e) => {
117
+ }, $ = async (e) => {
117
118
  try {
118
- await N({ variables: { id: e } });
119
+ await F({ variables: { id: e } });
119
120
  } finally {
120
- H(null);
121
+ W(null);
121
122
  }
122
123
  };
123
- return /* @__PURE__ */ m("section", {
124
+ return /* @__PURE__ */ g("section", {
124
125
  "data-testid": "instruction-files-manager",
125
126
  className: "space-y-4 rounded-lg border border-border-default bg-bg-surface p-4",
126
127
  children: [
127
- /* @__PURE__ */ m("header", {
128
+ /* @__PURE__ */ g("header", {
128
129
  className: "flex flex-wrap items-start justify-between gap-3",
129
- children: [/* @__PURE__ */ m("div", {
130
+ children: [/* @__PURE__ */ g("div", {
130
131
  className: "space-y-1",
131
- children: [/* @__PURE__ */ p("h2", {
132
+ children: [/* @__PURE__ */ h("h2", {
132
133
  className: "text-lg font-semibold text-text-primary",
133
134
  children: "Instruction files"
134
- }), /* @__PURE__ */ p("p", {
135
+ }), /* @__PURE__ */ h("p", {
135
136
  className: "max-w-2xl text-sm text-text-secondary",
136
137
  children: "AGENTS.md / CLAUDE.md / GEMINI.md maintained centrally and pushed to your agent on chat open."
137
138
  })]
138
- }), /* @__PURE__ */ p("button", {
139
+ }), /* @__PURE__ */ h("button", {
139
140
  type: "button",
140
141
  "data-testid": "instruction-file-new",
141
- className: v,
142
- onClick: F && !L ? Y : q,
143
- children: F && !L ? "Close" : "New file"
142
+ className: b,
143
+ onClick: L && !z ? Z : Y,
144
+ children: L && !z ? "Close" : "New file"
144
145
  })]
145
146
  }),
146
- F && /* @__PURE__ */ m("div", {
147
+ L && /* @__PURE__ */ g("div", {
147
148
  className: "space-y-4 rounded-md border border-border-default bg-bg-elevated p-4",
148
149
  children: [
149
- /* @__PURE__ */ p("h3", {
150
+ /* @__PURE__ */ h("h3", {
150
151
  className: "text-sm font-medium text-text-primary",
151
- children: L ? "Edit instruction file" : "New instruction file"
152
+ children: z ? "Edit instruction file" : "New instruction file"
152
153
  }),
153
- /* @__PURE__ */ m("div", {
154
+ /* @__PURE__ */ g("div", {
154
155
  className: "grid gap-4 sm:grid-cols-2",
155
- children: [/* @__PURE__ */ m("label", {
156
+ children: [/* @__PURE__ */ g("label", {
156
157
  className: "space-y-1.5",
157
- children: [/* @__PURE__ */ p("span", {
158
+ children: [/* @__PURE__ */ h("span", {
158
159
  className: "block text-sm font-medium text-text-secondary",
159
160
  children: "Filename"
160
- }), /* @__PURE__ */ p("select", {
161
- className: _,
162
- value: z.filename,
163
- onChange: (e) => B((t) => ({
161
+ }), /* @__PURE__ */ h("select", {
162
+ className: y,
163
+ value: V.filename,
164
+ onChange: (e) => H((t) => ({
164
165
  ...t,
165
166
  filename: e.target.value
166
167
  })),
167
- children: h.map((e) => /* @__PURE__ */ p("option", {
168
+ children: _.map((e) => /* @__PURE__ */ h("option", {
168
169
  value: e.value,
169
170
  children: e.label
170
171
  }, e.value))
171
172
  })]
172
- }), /* @__PURE__ */ m("label", {
173
+ }), /* @__PURE__ */ g("label", {
173
174
  className: "space-y-1.5",
174
- children: [/* @__PURE__ */ p("span", {
175
+ children: [/* @__PURE__ */ h("span", {
175
176
  className: "block text-sm font-medium text-text-secondary",
176
177
  children: "Scope"
177
- }), /* @__PURE__ */ p("select", {
178
- className: _,
179
- value: z.scope,
180
- disabled: L !== null,
181
- onChange: (e) => B((t) => ({
178
+ }), /* @__PURE__ */ h("select", {
179
+ className: y,
180
+ value: V.scope,
181
+ disabled: z !== null,
182
+ onChange: (e) => H((t) => ({
182
183
  ...t,
183
184
  scope: e.target.value
184
185
  })),
185
- children: g.map((e) => /* @__PURE__ */ p("option", {
186
+ children: v.map((e) => /* @__PURE__ */ h("option", {
186
187
  value: e.value,
187
188
  children: e.label
188
189
  }, e.value))
189
190
  })]
190
191
  })]
191
192
  }),
192
- z.filename === i.Custom && /* @__PURE__ */ m("label", {
193
+ V.filename === i.Custom && /* @__PURE__ */ g("label", {
193
194
  className: "space-y-1.5",
194
- children: [/* @__PURE__ */ p("span", {
195
+ children: [/* @__PURE__ */ h("span", {
195
196
  className: "block text-sm font-medium text-text-secondary",
196
197
  children: "Custom name"
197
- }), /* @__PURE__ */ p("input", {
198
+ }), /* @__PURE__ */ h("input", {
198
199
  type: "text",
199
- className: _,
200
+ className: y,
200
201
  placeholder: "e.g. CONTRIBUTING.md",
201
- value: z.customName,
202
- onChange: (e) => B((t) => ({
202
+ value: V.customName,
203
+ onChange: (e) => H((t) => ({
203
204
  ...t,
204
205
  customName: e.target.value
205
206
  }))
206
207
  })]
207
208
  }),
208
- !L && z.scope === a.Vibe && /* @__PURE__ */ p(c, {
209
- value: z.link,
210
- onChange: (e) => B((t) => ({
209
+ !z && V.scope === a.Vibe && /* @__PURE__ */ h(l, {
210
+ value: V.link,
211
+ onChange: (e) => H((t) => ({
211
212
  ...t,
212
213
  link: e
213
214
  })),
214
- disabled: K
215
+ disabled: J
215
216
  }),
216
- /* @__PURE__ */ m("label", {
217
+ /* @__PURE__ */ g("label", {
217
218
  className: "space-y-1.5",
218
- children: [/* @__PURE__ */ p("span", {
219
+ children: [/* @__PURE__ */ h("span", {
219
220
  className: "block text-sm font-medium text-text-secondary",
220
221
  children: "Content"
221
- }), /* @__PURE__ */ p("textarea", {
222
- className: `${_} min-h-56 font-mono`,
222
+ }), /* @__PURE__ */ h("textarea", {
223
+ className: `${y} min-h-56 font-mono`,
223
224
  placeholder: "# Project instructions…",
224
- value: z.content,
225
- onChange: (e) => B((t) => ({
225
+ value: V.content,
226
+ onChange: (e) => H((t) => ({
226
227
  ...t,
227
228
  content: e.target.value
228
229
  }))
229
230
  })]
230
231
  }),
231
- U && /* @__PURE__ */ p("p", {
232
+ G && /* @__PURE__ */ h("p", {
232
233
  className: "text-sm text-action-danger-text",
233
234
  role: "alert",
234
- children: U
235
+ children: G
235
236
  }),
236
- /* @__PURE__ */ m("div", {
237
+ /* @__PURE__ */ g("div", {
237
238
  className: "flex items-center gap-2",
238
- children: [/* @__PURE__ */ p("button", {
239
+ children: [/* @__PURE__ */ h("button", {
239
240
  type: "button",
240
241
  "data-testid": "instruction-file-save",
241
- className: v,
242
- disabled: K,
242
+ className: b,
243
+ disabled: J,
243
244
  onClick: () => {
244
- X();
245
+ Q();
245
246
  },
246
- children: K ? "Saving…" : "Save"
247
- }), /* @__PURE__ */ p("button", {
247
+ children: J ? "Saving…" : "Save"
248
+ }), /* @__PURE__ */ h("button", {
248
249
  type: "button",
249
- className: y,
250
- disabled: K,
251
- onClick: Y,
250
+ className: x,
251
+ disabled: J,
252
+ onClick: Z,
252
253
  children: "Cancel"
253
254
  })]
254
255
  })
255
256
  ]
256
257
  }),
257
- O ? /* @__PURE__ */ m("p", {
258
+ A ? /* @__PURE__ */ g("p", {
258
259
  className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-action-danger-text",
259
- children: ["Could not load instruction files: ", O.message]
260
- }) : D && G.length === 0 ? /* @__PURE__ */ p("p", {
260
+ children: ["Could not load instruction files: ", A.message]
261
+ }) : k && q.length === 0 ? /* @__PURE__ */ h("p", {
261
262
  className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary",
262
263
  children: "Loading instruction files…"
263
- }) : G.length === 0 ? /* @__PURE__ */ p("p", {
264
+ }) : q.length === 0 ? /* @__PURE__ */ h("p", {
264
265
  className: "rounded-md border border-border-default bg-bg-sunken p-4 text-sm text-text-secondary",
265
266
  children: "No instruction files yet. Create one to share it with your agent."
266
- }) : /* @__PURE__ */ p("ul", {
267
+ }) : /* @__PURE__ */ h("ul", {
267
268
  className: "space-y-2",
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
+ 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", {
271
272
  "data-testid": "instruction-file-row",
272
273
  className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-border-default bg-bg-elevated p-3",
273
- children: [/* @__PURE__ */ m("div", {
274
+ children: [/* @__PURE__ */ g("div", {
274
275
  className: "min-w-0 space-y-1",
275
- children: [/* @__PURE__ */ m("div", {
276
+ children: [/* @__PURE__ */ g("div", {
276
277
  className: "flex flex-wrap items-center gap-2",
277
278
  children: [
278
- /* @__PURE__ */ p("span", {
279
+ /* @__PURE__ */ h("span", {
279
280
  className: "font-mono text-sm font-bold text-text-primary",
280
281
  children: e.effectiveFilename
281
282
  }),
282
- /* @__PURE__ */ p("span", {
283
- className: x,
283
+ /* @__PURE__ */ h("span", {
284
+ className: C,
284
285
  children: r
285
286
  }),
286
- /* @__PURE__ */ p("span", {
287
- className: x,
287
+ /* @__PURE__ */ h("span", {
288
+ className: C,
288
289
  children: n ? "Shared" : "Private"
289
290
  })
290
291
  ]
291
- }), /* @__PURE__ */ m("p", {
292
+ }), /* @__PURE__ */ g("p", {
292
293
  className: "text-xs text-text-tertiary",
293
- children: ["Updated ", E(e.updatedAt)]
294
+ children: ["Updated ", O(e.updatedAt)]
294
295
  })]
295
- }), /* @__PURE__ */ p("div", {
296
+ }), /* @__PURE__ */ h("div", {
296
297
  className: "flex items-center gap-2",
297
- children: t ? /* @__PURE__ */ m(f, { children: [
298
- /* @__PURE__ */ p("span", {
298
+ children: t ? /* @__PURE__ */ g(m, { children: [
299
+ /* @__PURE__ */ h("span", {
299
300
  className: "text-xs text-text-secondary",
300
301
  children: "Delete this file?"
301
302
  }),
302
- /* @__PURE__ */ p("button", {
303
+ /* @__PURE__ */ h("button", {
303
304
  type: "button",
304
- className: b,
305
- disabled: P,
305
+ className: S,
306
+ disabled: I,
306
307
  onClick: () => {
307
- Z(e.id);
308
+ $(e.id);
308
309
  },
309
- children: P ? "Deleting…" : "Confirm"
310
+ children: I ? "Deleting…" : "Confirm"
310
311
  }),
311
- /* @__PURE__ */ p("button", {
312
+ /* @__PURE__ */ h("button", {
312
313
  type: "button",
313
- className: y,
314
- disabled: P,
315
- onClick: () => H(null),
314
+ className: x,
315
+ disabled: I,
316
+ onClick: () => W(null),
316
317
  children: "Cancel"
317
318
  })
318
- ] }) : /* @__PURE__ */ m(f, { children: [
319
- /* @__PURE__ */ p("button", {
319
+ ] }) : /* @__PURE__ */ g(m, { children: [
320
+ /* @__PURE__ */ h("button", {
320
321
  type: "button",
321
- className: y,
322
- onClick: () => J(e),
322
+ className: x,
323
+ onClick: () => X(e),
323
324
  children: "Edit"
324
325
  }),
325
- /* @__PURE__ */ p(l, {
326
+ /* @__PURE__ */ h(u, {
327
+ entityType: o.InstructionFile,
328
+ entityId: e.id,
329
+ currentVibeId: e.vibeId ?? null,
330
+ currentVisibility: e.visibility,
331
+ refetchQueries: ["ListAgentInstructionFiles"]
332
+ }),
333
+ /* @__PURE__ */ h(d, {
326
334
  entity: "instructionfile",
327
335
  resource: {
328
336
  id: e.id,
@@ -331,10 +339,10 @@ function D({ agentId: s }) {
331
339
  },
332
340
  label: "Share"
333
341
  }),
334
- /* @__PURE__ */ p("button", {
342
+ /* @__PURE__ */ h("button", {
335
343
  type: "button",
336
- className: b,
337
- onClick: () => H(e.id),
344
+ className: S,
345
+ onClick: () => W(e.id),
338
346
  children: "Delete"
339
347
  })
340
348
  ] })
@@ -346,6 +354,6 @@ function D({ agentId: s }) {
346
354
  });
347
355
  }
348
356
  //#endregion
349
- export { D as InstructionFilesManager };
357
+ export { k as InstructionFilesManager };
350
358
 
351
359
  //# 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';\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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"}
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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"}