@burdenoff/microfe-vibecontrols 2026.527.16 → 2026.528.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/gitops/GitOpsProviderPicker.js +29 -0
- package/dist/components/gitops/GitOpsProviderPicker.js.map +1 -0
- package/dist/components/gitops/GitOpsSetup.js +148 -102
- package/dist/components/gitops/GitOpsSetup.js.map +1 -1
- package/dist/components/gitops/VibeGitOpsTab.js +231 -223
- package/dist/components/gitops/VibeGitOpsTab.js.map +1 -1
- package/dist/components/gitops/types.js +65 -0
- package/dist/components/gitops/types.js.map +1 -0
- package/dist/components/security/SecurityEmptyState.js +2 -32
- package/dist/components/security/SecurityTabPanel.js +40 -97
- package/dist/components/security/SecurityTabPanel.js.map +1 -1
- package/dist/components/security/index.js +1 -6
- package/dist/components/security/types.js +3 -5
- package/dist/components/security/types.js.map +1 -1
- package/dist/components/settings/SettingsForm.js +30 -32
- package/dist/components/settings/SettingsForm.js.map +1 -1
- package/dist/components/settings/WorkspaceDefaultsSection.js +113 -118
- package/dist/components/settings/WorkspaceDefaultsSection.js.map +1 -1
- package/dist/components/shared/ConfirmDialog.js +51 -108
- package/dist/components/shared/ConfirmDialog.js.map +1 -1
- package/dist/components/shared/EmptyState.js +9 -102
- package/dist/components/shared/EmptyState.js.map +1 -1
- package/dist/components/shared/PageHeader.js +16 -47
- package/dist/components/shared/PageHeader.js.map +1 -1
- package/dist/components/tunnels/TunnelCreateWizard.js +17 -14
- package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
- package/dist/constants/pluginCatalog.js +139 -4
- package/dist/constants/pluginCatalog.js.map +1 -1
- package/dist/hooks/useGitops.js +135 -0
- package/dist/hooks/useGitops.js.map +1 -0
- package/dist/pages/GettingStartedPage.js +6 -6
- package/dist/pages/PluginStandalonePage.js +12 -12
- package/dist/pages/VibeDetailsPage.js +4 -1
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/VibesPage.js +304 -291
- package/dist/pages/VibesPage.js.map +1 -1
- package/dist/services/gitopsApi.js +128 -0
- package/dist/services/gitopsApi.js.map +1 -0
- package/package.json +2 -2
- package/dist/components/security/SecurityEmptyState.js.map +0 -1
- package/dist/components/security/SecurityEvidenceList.js +0 -42
- package/dist/components/security/SecurityEvidenceList.js.map +0 -1
- package/dist/components/security/SecurityFindingsTable.js +0 -201
- package/dist/components/security/SecurityFindingsTable.js.map +0 -1
- package/dist/components/security/SecurityHeaderStrip.js +0 -67
- package/dist/components/security/SecurityHeaderStrip.js.map +0 -1
- package/dist/components/security/SecurityLifecycleStepper.js +0 -66
- package/dist/components/security/SecurityLifecycleStepper.js.map +0 -1
- package/dist/components/security/SecurityProviderDrawer.js +0 -187
- package/dist/components/security/SecurityProviderDrawer.js.map +0 -1
- package/dist/components/security/gql.js +0 -128
- package/dist/components/security/gql.js.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
2
|
+
//#region src/components/gitops/GitOpsProviderPicker.tsx
|
|
3
|
+
var n = {
|
|
4
|
+
github: "GitHub",
|
|
5
|
+
gitlab: "GitLab",
|
|
6
|
+
bitbucket: "Bitbucket",
|
|
7
|
+
azdevops: "Azure DevOps"
|
|
8
|
+
}, r = ({ providers: r, selected: i, onChange: a }) => r.length === 0 ? null : r.length === 1 && r[0] ? /* @__PURE__ */ e("span", {
|
|
9
|
+
className: "inline-flex items-center px-2 py-0.5 text-xs rounded-md bg-bg-sunken text-text-secondary",
|
|
10
|
+
"data-testid": "gitops-provider-badge",
|
|
11
|
+
children: n[r[0]]
|
|
12
|
+
}) : /* @__PURE__ */ t("select", {
|
|
13
|
+
"aria-label": "GitOps provider",
|
|
14
|
+
"data-testid": "gitops-provider-picker",
|
|
15
|
+
value: i ?? "",
|
|
16
|
+
onChange: (e) => a(e.target.value),
|
|
17
|
+
className: "px-2 py-1 text-xs rounded-md border border-border-default bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40",
|
|
18
|
+
children: [!i && /* @__PURE__ */ e("option", {
|
|
19
|
+
value: "",
|
|
20
|
+
children: "Select…"
|
|
21
|
+
}), r.map((t) => /* @__PURE__ */ e("option", {
|
|
22
|
+
value: t,
|
|
23
|
+
children: n[t]
|
|
24
|
+
}, t))]
|
|
25
|
+
});
|
|
26
|
+
//#endregion
|
|
27
|
+
export { r as GitOpsProviderPicker };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=GitOpsProviderPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitOpsProviderPicker.js","names":[],"sources":["../../../src/components/gitops/GitOpsProviderPicker.tsx"],"sourcesContent":["/**\n * GitOpsProviderPicker — small select to switch between authenticated\n * providers (github / gitlab / bitbucket / azdevops).\n *\n * Only providers that the user has authenticated against are surfaced.\n */\nimport type { FC } from 'react';\n\nimport type { ProviderName } from './types';\n\nconst LABELS: Record<ProviderName, string> = {\n github: 'GitHub',\n gitlab: 'GitLab',\n bitbucket: 'Bitbucket',\n azdevops: 'Azure DevOps',\n};\n\ninterface GitOpsProviderPickerProps {\n providers: ProviderName[];\n selected: ProviderName | null;\n onChange: (next: ProviderName) => void;\n}\n\nexport const GitOpsProviderPicker: FC<GitOpsProviderPickerProps> = ({\n providers,\n selected,\n onChange,\n}) => {\n if (providers.length === 0) return null;\n if (providers.length === 1 && providers[0]) {\n return (\n <span\n className=\"inline-flex items-center px-2 py-0.5 text-xs rounded-md bg-bg-sunken text-text-secondary\"\n data-testid=\"gitops-provider-badge\"\n >\n {LABELS[providers[0]]}\n </span>\n );\n }\n return (\n <select\n aria-label=\"GitOps provider\"\n data-testid=\"gitops-provider-picker\"\n value={selected ?? ''}\n onChange={(e) => onChange(e.target.value as ProviderName)}\n className=\"px-2 py-1 text-xs rounded-md border border-border-default bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40\"\n >\n {!selected && <option value=\"\">Select…</option>}\n {providers.map((p) => (\n <option key={p} value={p}>\n {LABELS[p]}\n </option>\n ))}\n </select>\n );\n};\n"],"mappings":";;AAUA,IAAM,IAAuC;CAC3C,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,UAAU;CACX,EAQY,KAAuD,EAClE,cACA,aACA,kBAEI,EAAU,WAAW,IAAU,OAC/B,EAAU,WAAW,KAAK,EAAU,KAEpC,kBAAC,QAAD;CACE,WAAU;CACV,eAAY;WAEX,EAAO,EAAU;CACb,CAAA,GAIT,kBAAC,UAAD;CACE,cAAW;CACX,eAAY;CACZ,OAAO,KAAY;CACnB,WAAW,MAAM,EAAS,EAAE,OAAO,MAAsB;CACzD,WAAU;WALZ,CAOG,CAAC,KAAY,kBAAC,UAAD;EAAQ,OAAM;YAAG;EAAgB,CAAA,EAC9C,EAAU,KAAK,MACd,kBAAC,UAAD;EAAgB,OAAO;YACpB,EAAO;EACD,EAFI,EAEJ,CACT,CACK"}
|
|
@@ -1,150 +1,196 @@
|
|
|
1
1
|
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
|
-
import {
|
|
2
|
+
import { useGitopsAuth as t } from "../../hooks/useGitops.js";
|
|
3
3
|
import { useCallback as n, useMemo as r, useState as i } from "react";
|
|
4
|
-
import {
|
|
5
|
-
import { jsx as
|
|
4
|
+
import { ExternalLink as a, GitMerge as o, Loader2 as s } from "lucide-react";
|
|
5
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
6
6
|
//#region src/components/gitops/GitOpsSetup.tsx
|
|
7
|
-
var
|
|
7
|
+
var u = [
|
|
8
8
|
{
|
|
9
|
-
value: "
|
|
10
|
-
label: "GitHub"
|
|
9
|
+
value: "github",
|
|
10
|
+
label: "GitHub",
|
|
11
|
+
tokenLabel: "Personal Access Token",
|
|
12
|
+
tokenPlaceholder: "ghp_xxxxxxxxxxxxxxxxxxxx",
|
|
13
|
+
helpUrl: "https://github.com/settings/tokens",
|
|
14
|
+
helpText: "Required scopes: repo, workflow, read:org, security_events"
|
|
11
15
|
},
|
|
12
16
|
{
|
|
13
|
-
value: "
|
|
14
|
-
label: "GitLab"
|
|
17
|
+
value: "gitlab",
|
|
18
|
+
label: "GitLab",
|
|
19
|
+
tokenLabel: "Personal Access Token",
|
|
20
|
+
tokenPlaceholder: "glpat-xxxxxxxxxxxxxxxxxxxx",
|
|
21
|
+
helpUrl: "https://gitlab.com/-/profile/personal_access_tokens",
|
|
22
|
+
helpText: "Required scope: api. For self-hosted instances, set the host below.",
|
|
23
|
+
showHost: !0
|
|
15
24
|
},
|
|
16
25
|
{
|
|
17
|
-
value: "
|
|
18
|
-
label: "Bitbucket"
|
|
26
|
+
value: "bitbucket",
|
|
27
|
+
label: "Bitbucket Cloud",
|
|
28
|
+
tokenLabel: "username:app_password",
|
|
29
|
+
tokenPlaceholder: "vignesh:ATBBxxxxxxxxxxxxxx",
|
|
30
|
+
helpUrl: "https://bitbucket.org/account/settings/app-passwords/",
|
|
31
|
+
helpText: "Required permissions: Repositories Read, Pull Requests Read, Pipelines Read"
|
|
19
32
|
},
|
|
20
33
|
{
|
|
21
|
-
value: "
|
|
22
|
-
label: "Azure DevOps"
|
|
34
|
+
value: "azdevops",
|
|
35
|
+
label: "Azure DevOps",
|
|
36
|
+
tokenLabel: "Personal Access Token",
|
|
37
|
+
tokenPlaceholder: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
38
|
+
helpUrl: "https://dev.azure.com/_usersSettings/tokens",
|
|
39
|
+
helpText: "Required scopes: Code Read, Pull Request Read, Build Read",
|
|
40
|
+
showOrg: !0
|
|
23
41
|
}
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
repoUrl: _.trim()
|
|
44
|
-
} } }), p();
|
|
42
|
+
], d = ({ ctx: d, onCreated: f, onCancel: p }) => {
|
|
43
|
+
let m = e(), [h, g] = i("github"), [_, v] = i(""), [y, b] = i(""), [x, S] = i(""), [C, w] = i(""), [T, E] = i(null), D = r(() => u.find((e) => e.value === h) ?? u[0], [h]), O = t(d), k = r(() => !(_.trim().length === 0 || D.showOrg && y.trim().length === 0), [
|
|
44
|
+
D.showOrg,
|
|
45
|
+
y,
|
|
46
|
+
_
|
|
47
|
+
]), A = n(async (e) => {
|
|
48
|
+
if (e.preventDefault(), w(""), E(null), !k) return;
|
|
49
|
+
let t = {};
|
|
50
|
+
D.showOrg && y && (t.organization = y.trim()), D.showHost && x && (t.host = x.trim());
|
|
51
|
+
try {
|
|
52
|
+
let e = await O.mutateAsync({
|
|
53
|
+
provider: h,
|
|
54
|
+
input: {
|
|
55
|
+
kind: "pat",
|
|
56
|
+
token: _.trim(),
|
|
57
|
+
meta: Object.keys(t).length ? t : void 0
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
E(e), e.ok ? (v(""), f()) : e.message && w(e.message);
|
|
45
61
|
} catch (e) {
|
|
46
|
-
w(e instanceof Error ? e.message : "Failed to
|
|
62
|
+
w(e instanceof Error ? e.message : "Failed to save credentials");
|
|
47
63
|
}
|
|
48
64
|
}, [
|
|
49
65
|
O,
|
|
50
|
-
T,
|
|
51
|
-
d,
|
|
52
|
-
h,
|
|
53
|
-
y,
|
|
54
|
-
_,
|
|
55
66
|
x,
|
|
56
|
-
|
|
67
|
+
k,
|
|
68
|
+
f,
|
|
69
|
+
D.showHost,
|
|
70
|
+
D.showOrg,
|
|
71
|
+
y,
|
|
72
|
+
h,
|
|
73
|
+
_
|
|
57
74
|
]);
|
|
58
|
-
return /* @__PURE__ */
|
|
75
|
+
return /* @__PURE__ */ c("div", {
|
|
59
76
|
className: "max-w-xl mx-auto",
|
|
60
|
-
children: /* @__PURE__ */
|
|
77
|
+
children: /* @__PURE__ */ l("div", {
|
|
61
78
|
className: "bg-bg-surface border border-border-default rounded-xl shadow-sm p-6 sm:p-8",
|
|
62
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ l("div", {
|
|
63
80
|
className: "flex flex-col items-center text-center mb-6",
|
|
64
81
|
children: [
|
|
65
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ c("div", {
|
|
66
83
|
className: "size-12 rounded-xl bg-bg-sunken flex items-center justify-center mb-4",
|
|
67
|
-
children: /* @__PURE__ */
|
|
84
|
+
children: /* @__PURE__ */ c(o, { className: "size-6 text-text-secondary" })
|
|
68
85
|
}),
|
|
69
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ c("h2", {
|
|
70
87
|
className: "text-lg font-semibold text-text-primary",
|
|
71
|
-
children: m("vibecontrols.gitops.setup.title", "Connect a
|
|
88
|
+
children: m("vibecontrols.gitops.setup.title", "Connect a provider")
|
|
72
89
|
}),
|
|
73
|
-
/* @__PURE__ */
|
|
90
|
+
/* @__PURE__ */ c("p", {
|
|
74
91
|
className: "text-sm text-text-secondary mt-1",
|
|
75
|
-
children: m("vibecontrols.gitops.setup.description", "
|
|
92
|
+
children: m("vibecontrols.gitops.setup.description", "Paste a personal access token. It is stored encrypted on your agent — never sent to the backend.")
|
|
76
93
|
})
|
|
77
94
|
]
|
|
78
|
-
}), /* @__PURE__ */
|
|
79
|
-
onSubmit:
|
|
95
|
+
}), /* @__PURE__ */ l("form", {
|
|
96
|
+
onSubmit: A,
|
|
80
97
|
className: "space-y-4",
|
|
81
98
|
children: [
|
|
82
|
-
/* @__PURE__ */
|
|
83
|
-
htmlFor: "gitops-
|
|
99
|
+
/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
|
|
100
|
+
htmlFor: "gitops-provider",
|
|
84
101
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
85
|
-
children: m("vibecontrols.gitops.setup.
|
|
86
|
-
}), /* @__PURE__ */
|
|
87
|
-
|
|
88
|
-
id: "gitops-name",
|
|
89
|
-
type: "text",
|
|
102
|
+
children: m("vibecontrols.gitops.setup.providerType", "Provider")
|
|
103
|
+
}), /* @__PURE__ */ c("select", {
|
|
104
|
+
id: "gitops-provider",
|
|
90
105
|
value: h,
|
|
91
106
|
onChange: (e) => g(e.target.value),
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
className: "block text-sm font-medium text-text-primary mb-1",
|
|
98
|
-
children: m("vibecontrols.gitops.setup.repoUrl", "Repository URL")
|
|
99
|
-
}), /* @__PURE__ */ s("input", {
|
|
100
|
-
"aria-label": "https://github.com/org/repo",
|
|
101
|
-
id: "gitops-url",
|
|
102
|
-
type: "url",
|
|
103
|
-
value: _,
|
|
104
|
-
onChange: (e) => D(e.target.value),
|
|
105
|
-
placeholder: "https://github.com/org/repo",
|
|
106
|
-
className: "w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40 focus:border-action-primary-bg transition-colors"
|
|
107
|
+
className: "w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40",
|
|
108
|
+
children: u.map((e) => /* @__PURE__ */ c("option", {
|
|
109
|
+
value: e.value,
|
|
110
|
+
children: e.label
|
|
111
|
+
}, e.value))
|
|
107
112
|
})] }),
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
-
htmlFor: "gitops-
|
|
113
|
+
D.showOrg && /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
|
|
114
|
+
htmlFor: "gitops-org",
|
|
110
115
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
111
|
-
children: m("vibecontrols.gitops.setup.
|
|
112
|
-
}), /* @__PURE__ */
|
|
113
|
-
id: "gitops-
|
|
116
|
+
children: m("vibecontrols.gitops.setup.organization", "Organisation")
|
|
117
|
+
}), /* @__PURE__ */ c("input", {
|
|
118
|
+
id: "gitops-org",
|
|
119
|
+
type: "text",
|
|
114
120
|
value: y,
|
|
115
121
|
onChange: (e) => b(e.target.value),
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
children: e.label
|
|
120
|
-
}, e.value))
|
|
122
|
+
placeholder: "my-org",
|
|
123
|
+
"aria-label": "Azure DevOps organisation",
|
|
124
|
+
className: "w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40"
|
|
121
125
|
})] }),
|
|
122
|
-
/* @__PURE__ */
|
|
123
|
-
htmlFor: "gitops-
|
|
126
|
+
D.showHost && /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
|
|
127
|
+
htmlFor: "gitops-host",
|
|
124
128
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
125
|
-
children: m("vibecontrols.gitops.setup.
|
|
126
|
-
}),
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}) : /* @__PURE__ */ s("select", {
|
|
130
|
-
id: "gitops-agent",
|
|
129
|
+
children: m("vibecontrols.gitops.setup.host", "GitLab host (optional, for self-hosted)")
|
|
130
|
+
}), /* @__PURE__ */ c("input", {
|
|
131
|
+
id: "gitops-host",
|
|
132
|
+
type: "url",
|
|
131
133
|
value: x,
|
|
132
134
|
onChange: (e) => S(e.target.value),
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
value: e.id,
|
|
136
|
-
children: e.name
|
|
137
|
-
}, e.id))
|
|
135
|
+
placeholder: "https://gitlab.acme.com",
|
|
136
|
+
className: "w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40"
|
|
138
137
|
})] }),
|
|
139
|
-
|
|
138
|
+
/* @__PURE__ */ l("div", { children: [
|
|
139
|
+
/* @__PURE__ */ c("label", {
|
|
140
|
+
htmlFor: "gitops-token",
|
|
141
|
+
className: "block text-sm font-medium text-text-primary mb-1",
|
|
142
|
+
children: D.tokenLabel
|
|
143
|
+
}),
|
|
144
|
+
/* @__PURE__ */ c("input", {
|
|
145
|
+
id: "gitops-token",
|
|
146
|
+
type: "password",
|
|
147
|
+
value: _,
|
|
148
|
+
onChange: (e) => v(e.target.value),
|
|
149
|
+
placeholder: D.tokenPlaceholder,
|
|
150
|
+
"aria-label": "Personal access token",
|
|
151
|
+
autoComplete: "off",
|
|
152
|
+
className: "w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40"
|
|
153
|
+
}),
|
|
154
|
+
/* @__PURE__ */ l("p", {
|
|
155
|
+
className: "text-xs text-text-secondary mt-1.5 flex items-center gap-1",
|
|
156
|
+
children: [
|
|
157
|
+
D.helpText,
|
|
158
|
+
" ",
|
|
159
|
+
/* @__PURE__ */ l("a", {
|
|
160
|
+
href: D.helpUrl,
|
|
161
|
+
target: "_blank",
|
|
162
|
+
rel: "noopener noreferrer",
|
|
163
|
+
className: "inline-flex items-center text-action-primary-bg hover:underline",
|
|
164
|
+
children: ["Create token ", /* @__PURE__ */ c(a, { className: "size-3 ml-0.5" })]
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
})
|
|
168
|
+
] }),
|
|
169
|
+
T?.ok && /* @__PURE__ */ l("div", {
|
|
170
|
+
className: "text-sm text-status-success-text bg-status-success-bg-subtle rounded-lg px-3 py-2",
|
|
171
|
+
children: [
|
|
172
|
+
m("vibecontrols.gitops.setup.validated", "Token validated"),
|
|
173
|
+
T.account ? ` — ${T.account}` : "",
|
|
174
|
+
T.scopes?.length ? ` (scopes: ${T.scopes.join(", ")})` : ""
|
|
175
|
+
]
|
|
176
|
+
}),
|
|
177
|
+
C && /* @__PURE__ */ c("div", {
|
|
140
178
|
className: "text-sm text-status-error-text bg-status-error-bg-subtle rounded-lg px-3 py-2",
|
|
141
179
|
children: C
|
|
142
180
|
}),
|
|
143
|
-
/* @__PURE__ */
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
181
|
+
/* @__PURE__ */ l("div", {
|
|
182
|
+
className: "flex items-center gap-3",
|
|
183
|
+
children: [/* @__PURE__ */ l("button", {
|
|
184
|
+
type: "submit",
|
|
185
|
+
disabled: O.isPending || !k,
|
|
186
|
+
className: "flex-1 flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
187
|
+
children: [O.isPending && /* @__PURE__ */ c(s, { className: "size-4 animate-spin" }), m("vibecontrols.gitops.setup.connect", "Save and connect")]
|
|
188
|
+
}), p && /* @__PURE__ */ c("button", {
|
|
189
|
+
type: "button",
|
|
190
|
+
onClick: p,
|
|
191
|
+
className: "px-4 py-2.5 text-sm font-medium rounded-lg border border-border-default text-text-secondary hover:text-text-primary transition-colors",
|
|
192
|
+
children: m("vibecontrols.gitops.setup.cancel", "Cancel")
|
|
193
|
+
})]
|
|
148
194
|
})
|
|
149
195
|
]
|
|
150
196
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitOpsSetup.js","names":[],"sources":["../../../src/components/gitops/GitOpsSetup.tsx"],"sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport type { FC, FormEvent } from 'react';\nimport { GitMerge, Loader2 } from 'lucide-react';\nimport { useCreateGitopsProviderMutation } from '../../generated/wspace-operations';\nimport type { GitProviderType } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface GitOpsSetupProps {\n workspaceId: string;\n agents: Array<{ id: string; name: string }>;\n onCreated: () => void;\n}\n\nconst PROVIDER_OPTIONS: { value: GitProviderType; label: string }[] = [\n { value: 'GITHUB', label: 'GitHub' },\n { value: 'GITLAB', label: 'GitLab' },\n { value: 'BITBUCKET', label: 'Bitbucket' },\n { value: 'AZURE_DEVOPS', label: 'Azure DevOps' },\n];\n\nfunction detectProvider(url: string): GitProviderType | null {\n const lower = url.toLowerCase();\n if (lower.includes('github.com') || lower.includes('github.')) return 'GITHUB';\n if (lower.includes('gitlab.com') || lower.includes('gitlab.')) return 'GITLAB';\n if (lower.includes('bitbucket.org') || lower.includes('bitbucket.')) return 'BITBUCKET';\n if (lower.includes('dev.azure.com') || lower.includes('visualstudio.com')) return 'AZURE_DEVOPS';\n return null;\n}\n\n/**\n * GitOpsSetup shows a first-time provider setup form when no providers are configured.\n */\nexport const GitOpsSetup: FC<GitOpsSetupProps> = ({ workspaceId, agents, onCreated }) => {\n const tr = useTr();\n const [name, setName] = useState('');\n const [repoUrl, setRepoUrl] = useState('');\n const [providerType, setProviderType] = useState<GitProviderType>('GITHUB');\n const [agentId, setAgentId] = useState(agents[0]?.id ?? '');\n const [error, setError] = useState('');\n\n const [createProvider, { loading }] = useCreateGitopsProviderMutation();\n\n const handleUrlChange = useCallback((url: string) => {\n setRepoUrl(url);\n const detected = detectProvider(url);\n if (detected) setProviderType(detected);\n }, []);\n\n const isValid = useMemo(\n () => name.trim().length > 0 && repoUrl.trim().length > 0 && agentId.length > 0,\n [name, repoUrl, agentId]\n );\n\n const handleSubmit = useCallback(\n async (e: FormEvent) => {\n e.preventDefault();\n setError('');\n\n if (!isValid) return;\n\n try {\n await createProvider({\n variables: {\n input: {\n name: name.trim(),\n providerType,\n repoUrl: repoUrl.trim(),\n },\n },\n });\n onCreated();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to connect repository');\n }\n },\n [isValid, createProvider, workspaceId, name, providerType, repoUrl, agentId, onCreated]\n );\n\n return (\n <div className=\"max-w-xl mx-auto\">\n <div className=\"bg-bg-surface border border-border-default rounded-xl shadow-sm p-6 sm:p-8\">\n <div className=\"flex flex-col items-center text-center mb-6\">\n <div className=\"size-12 rounded-xl bg-bg-sunken flex items-center justify-center mb-4\">\n <GitMerge className=\"size-6 text-text-secondary\" />\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('vibecontrols.gitops.setup.title', 'Connect a Repository')}\n </h2>\n <p className=\"text-sm text-text-secondary mt-1\">\n {tr(\n 'vibecontrols.gitops.setup.description',\n 'Add a Git repository to monitor stats and CI/CD pipelines'\n )}\n </p>\n </div>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {/* Name */}\n <div>\n <label\n htmlFor=\"gitops-name\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('vibecontrols.gitops.setup.name', 'Name')}\n </label>\n <input\n aria-label=\"My Repository\"\n id=\"gitops-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"My Repository\"\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40 focus:border-action-primary-bg transition-colors\"\n />\n </div>\n\n {/* Repository URL */}\n <div>\n <label\n htmlFor=\"gitops-url\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('vibecontrols.gitops.setup.repoUrl', 'Repository URL')}\n </label>\n <input\n aria-label=\"https://github.com/org/repo\"\n id=\"gitops-url\"\n type=\"url\"\n value={repoUrl}\n onChange={(e) => handleUrlChange(e.target.value)}\n placeholder=\"https://github.com/org/repo\"\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40 focus:border-action-primary-bg transition-colors\"\n />\n </div>\n\n {/* Provider Type */}\n <div>\n <label\n htmlFor=\"gitops-provider\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('vibecontrols.gitops.setup.providerType', 'Provider Type')}\n </label>\n <select\n id=\"gitops-provider\"\n value={providerType}\n onChange={(e) => setProviderType(e.target.value as GitProviderType)}\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40 focus:border-action-primary-bg transition-colors\"\n >\n {PROVIDER_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Agent */}\n <div>\n <label\n htmlFor=\"gitops-agent\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('vibecontrols.gitops.setup.agent', 'Agent')}\n </label>\n {agents.length === 0 ? (\n <p className=\"text-sm text-status-warning-text\">\n {tr(\n 'vibecontrols.gitops.setup.noAgents',\n 'No agents available. Please configure an agent first for CLI access.'\n )}\n </p>\n ) : (\n <select\n id=\"gitops-agent\"\n value={agentId}\n onChange={(e) => setAgentId(e.target.value)}\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40 focus:border-action-primary-bg transition-colors\"\n >\n {agents.map((agent) => (\n <option key={agent.id} value={agent.id}>\n {agent.name}\n </option>\n ))}\n </select>\n )}\n </div>\n\n {error && (\n <div className=\"text-sm text-status-error-text bg-status-error-bg-subtle rounded-lg px-3 py-2\">\n {error}\n </div>\n )}\n\n <button\n type=\"submit\"\n disabled={loading || !isValid}\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {loading && <Loader2 className=\"size-4 animate-spin\" />}\n {tr('vibecontrols.gitops.setup.connect', 'Connect Repository')}\n </button>\n </form>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GitOpsSetup.js","names":[],"sources":["../../../src/components/gitops/GitOpsSetup.tsx"],"sourcesContent":["/**\n * GitOpsSetup — v2: PAT entry flow.\n *\n * User picks a provider (github / gitlab / bitbucket / azdevops), pastes a\n * PAT, and the agent stores it in encrypted SQLite. No backend record is\n * created. After save, `validateCredentials` is called via the same POST\n * so the user sees `ok: true, scopes: [...]` immediately.\n *\n * Azure DevOps requires an `organization` field — surfaced conditionally.\n * Bitbucket expects `username:app_password` format — documented inline.\n * GitLab supports a `host` override for self-hosted instances.\n */\nimport { useCallback, useMemo, useState, type FC, type FormEvent } from 'react';\nimport { GitMerge, Loader2, ExternalLink } from 'lucide-react';\n\nimport { useTr } from '../../shared/hooks/useTr';\nimport { useGitopsAuth, type UseGitopsContext } from '@/hooks/useGitops';\nimport type { ProviderName } from './types';\n\ninterface GitOpsSetupProps {\n ctx: UseGitopsContext;\n onCreated: () => void;\n onCancel?: () => void;\n}\n\ninterface ProviderOption {\n value: ProviderName;\n label: string;\n tokenLabel: string;\n tokenPlaceholder: string;\n helpUrl: string;\n helpText: string;\n showOrg?: boolean;\n showHost?: boolean;\n}\n\nconst PROVIDER_OPTIONS: ProviderOption[] = [\n {\n value: 'github',\n label: 'GitHub',\n tokenLabel: 'Personal Access Token',\n tokenPlaceholder: 'ghp_xxxxxxxxxxxxxxxxxxxx',\n helpUrl: 'https://github.com/settings/tokens',\n helpText: 'Required scopes: repo, workflow, read:org, security_events',\n },\n {\n value: 'gitlab',\n label: 'GitLab',\n tokenLabel: 'Personal Access Token',\n tokenPlaceholder: 'glpat-xxxxxxxxxxxxxxxxxxxx',\n helpUrl: 'https://gitlab.com/-/profile/personal_access_tokens',\n helpText: 'Required scope: api. For self-hosted instances, set the host below.',\n showHost: true,\n },\n {\n value: 'bitbucket',\n label: 'Bitbucket Cloud',\n tokenLabel: 'username:app_password',\n tokenPlaceholder: 'vignesh:ATBBxxxxxxxxxxxxxx',\n helpUrl: 'https://bitbucket.org/account/settings/app-passwords/',\n helpText: 'Required permissions: Repositories Read, Pull Requests Read, Pipelines Read',\n },\n {\n value: 'azdevops',\n label: 'Azure DevOps',\n tokenLabel: 'Personal Access Token',\n tokenPlaceholder: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n helpUrl: 'https://dev.azure.com/_usersSettings/tokens',\n helpText: 'Required scopes: Code Read, Pull Request Read, Build Read',\n showOrg: true,\n },\n];\n\nexport const GitOpsSetup: FC<GitOpsSetupProps> = ({ ctx, onCreated, onCancel }) => {\n const tr = useTr();\n const [providerType, setProviderType] = useState<ProviderName>('github');\n const [token, setToken] = useState('');\n const [organization, setOrganization] = useState('');\n const [host, setHost] = useState('');\n const [error, setError] = useState('');\n const [validation, setValidation] = useState<{\n ok: boolean;\n account?: string;\n scopes?: string[];\n message?: string;\n } | null>(null);\n\n const opt = useMemo(\n () => PROVIDER_OPTIONS.find((o) => o.value === providerType) ?? PROVIDER_OPTIONS[0]!,\n [providerType]\n );\n\n const authMutation = useGitopsAuth(ctx);\n\n const isValid = useMemo(() => {\n if (token.trim().length === 0) return false;\n if (opt.showOrg && organization.trim().length === 0) return false;\n return true;\n }, [opt.showOrg, organization, token]);\n\n const handleSubmit = useCallback(\n async (e: FormEvent) => {\n e.preventDefault();\n setError('');\n setValidation(null);\n if (!isValid) return;\n\n const meta: Record<string, string> = {};\n if (opt.showOrg && organization) meta.organization = organization.trim();\n if (opt.showHost && host) meta.host = host.trim();\n\n try {\n const result = await authMutation.mutateAsync({\n provider: providerType,\n input: {\n kind: 'pat',\n token: token.trim(),\n meta: Object.keys(meta).length ? meta : undefined,\n },\n });\n setValidation(result);\n if (result.ok) {\n setToken('');\n onCreated();\n } else if (result.message) {\n setError(result.message);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to save credentials');\n }\n },\n [\n authMutation,\n host,\n isValid,\n onCreated,\n opt.showHost,\n opt.showOrg,\n organization,\n providerType,\n token,\n ]\n );\n\n return (\n <div className=\"max-w-xl mx-auto\">\n <div className=\"bg-bg-surface border border-border-default rounded-xl shadow-sm p-6 sm:p-8\">\n <div className=\"flex flex-col items-center text-center mb-6\">\n <div className=\"size-12 rounded-xl bg-bg-sunken flex items-center justify-center mb-4\">\n <GitMerge className=\"size-6 text-text-secondary\" />\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('vibecontrols.gitops.setup.title', 'Connect a provider')}\n </h2>\n <p className=\"text-sm text-text-secondary mt-1\">\n {tr(\n 'vibecontrols.gitops.setup.description',\n 'Paste a personal access token. It is stored encrypted on your agent — never sent to the backend.'\n )}\n </p>\n </div>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div>\n <label\n htmlFor=\"gitops-provider\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('vibecontrols.gitops.setup.providerType', 'Provider')}\n </label>\n <select\n id=\"gitops-provider\"\n value={providerType}\n onChange={(e) => setProviderType(e.target.value as ProviderName)}\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40\"\n >\n {PROVIDER_OPTIONS.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n </div>\n\n {opt.showOrg && (\n <div>\n <label\n htmlFor=\"gitops-org\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('vibecontrols.gitops.setup.organization', 'Organisation')}\n </label>\n <input\n id=\"gitops-org\"\n type=\"text\"\n value={organization}\n onChange={(e) => setOrganization(e.target.value)}\n placeholder=\"my-org\"\n aria-label=\"Azure DevOps organisation\"\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40\"\n />\n </div>\n )}\n\n {opt.showHost && (\n <div>\n <label\n htmlFor=\"gitops-host\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('vibecontrols.gitops.setup.host', 'GitLab host (optional, for self-hosted)')}\n </label>\n <input\n id=\"gitops-host\"\n type=\"url\"\n value={host}\n onChange={(e) => setHost(e.target.value)}\n placeholder=\"https://gitlab.acme.com\"\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40\"\n />\n </div>\n )}\n\n <div>\n <label\n htmlFor=\"gitops-token\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {opt.tokenLabel}\n </label>\n <input\n id=\"gitops-token\"\n type=\"password\"\n value={token}\n onChange={(e) => setToken(e.target.value)}\n placeholder={opt.tokenPlaceholder}\n aria-label=\"Personal access token\"\n autoComplete=\"off\"\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border-default bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40\"\n />\n <p className=\"text-xs text-text-secondary mt-1.5 flex items-center gap-1\">\n {opt.helpText}{' '}\n <a\n href={opt.helpUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center text-action-primary-bg hover:underline\"\n >\n Create token <ExternalLink className=\"size-3 ml-0.5\" />\n </a>\n </p>\n </div>\n\n {validation?.ok && (\n <div className=\"text-sm text-status-success-text bg-status-success-bg-subtle rounded-lg px-3 py-2\">\n {tr('vibecontrols.gitops.setup.validated', 'Token validated')}\n {validation.account ? ` — ${validation.account}` : ''}\n {validation.scopes?.length ? ` (scopes: ${validation.scopes.join(', ')})` : ''}\n </div>\n )}\n {error && (\n <div className=\"text-sm text-status-error-text bg-status-error-bg-subtle rounded-lg px-3 py-2\">\n {error}\n </div>\n )}\n\n <div className=\"flex items-center gap-3\">\n <button\n type=\"submit\"\n disabled={authMutation.isPending || !isValid}\n className=\"flex-1 flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {authMutation.isPending && <Loader2 className=\"size-4 animate-spin\" />}\n {tr('vibecontrols.gitops.setup.connect', 'Save and connect')}\n </button>\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-4 py-2.5 text-sm font-medium rounded-lg border border-border-default text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.gitops.setup.cancel', 'Cancel')}\n </button>\n )}\n </div>\n </form>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|