@xpufx/paseo-top 0.4.3 → 0.4.5
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/OVERVIEW.md +17 -0
- package/client/host-ui.tsx +184 -0
- package/client/multi-host-view.tsx +57 -43
- package/client/multi-host.ts +36 -13
- package/client/pill-labels.ts +124 -7
- package/client/pill.tsx +724 -669
- package/client/resources-query.ts +1 -1
- package/client/settings-events.ts +33 -0
- package/client/settings-ui.tsx +86 -9
- package/client/surface.tsx +310 -274
- package/client/telemetry-copy.ts +8 -2
- package/client/telemetry.tsx +372 -321
- package/client/turn-panel.tsx +126 -104
- package/client/vendor/paseo-plugin-helper/{host.ts → core/host.ts} +21 -61
- package/client/vendor/paseo-plugin-helper/core/index.ts +76 -0
- package/client/vendor/paseo-plugin-helper/core/plugin-load-count.ts +89 -0
- package/client/vendor/paseo-plugin-helper/{query-refresh.ts → core/query-refresh.ts} +2 -2
- package/client/vendor/paseo-plugin-helper/{query.ts → core/query.ts} +2 -2
- package/client/vendor/paseo-plugin-helper/{settings.ts → core/settings.ts} +1 -1
- package/client/vendor/paseo-plugin-helper/{shared-settings.ts → core/shared-settings.ts} +2 -2
- package/client/vendor/paseo-plugin-helper/{utils → lifecycle}/clipboard.ts +2 -2
- package/client/vendor/paseo-plugin-helper/lifecycle/flair.ts +26 -0
- package/client/vendor/paseo-plugin-helper/{theme/color-utils.ts → lifecycle/host-color.ts} +95 -38
- package/client/vendor/paseo-plugin-helper/lifecycle/host-theme.tsx +109 -0
- package/client/vendor/paseo-plugin-helper/lifecycle/index.ts +23 -0
- package/client/vendor/paseo-plugin-helper/lifecycle/multi-host.ts +66 -0
- package/client/vendor/paseo-plugin-helper/{panel.tsx → lifecycle/panel.tsx} +7 -7
- package/client/vendor/paseo-plugin-helper/{pill.tsx → lifecycle/pill.tsx} +118 -338
- package/client/vendor/paseo-plugin-helper/lifecycle/providers.tsx +46 -0
- package/client/vendor/paseo-plugin-helper/lifecycle/scroll-owner.ts +26 -0
- package/client/vendor/paseo-plugin-helper/lifecycle/surface.tsx +140 -0
- package/client/vendor/paseo-plugin-helper/ui/color.ts +1 -0
- package/client/vendor/paseo-plugin-helper/ui/content.tsx +1326 -0
- package/client/vendor/paseo-plugin-helper/ui/controls.tsx +1018 -0
- package/client/vendor/paseo-plugin-helper/{components/DataTable.tsx → ui/data.tsx} +55 -47
- package/client/vendor/paseo-plugin-helper/ui/index.ts +44 -0
- package/client/vendor/paseo-plugin-helper/ui/layout.tsx +263 -0
- package/client/vendor/paseo-plugin-helper/ui/modal.tsx +111 -0
- package/client/vendor/paseo-plugin-helper/ui/plugin-reload-banner.tsx +119 -0
- package/client/vendor/paseo-plugin-helper/{settings-screen.tsx → ui/settings-screen.tsx} +3 -3
- package/client/vendor/paseo-plugin-helper/ui/settings.ts +36 -0
- package/client/vendor/paseo-plugin-helper/ui/text.tsx +821 -0
- package/client/vendor/paseo-plugin-helper/ui/theme.tsx +1 -0
- package/client/vendor/permission-audit/client.tsx +706 -0
- package/client/vendor/permission-audit/index.tsx +1 -0
- package/index.client.tsx +58 -37
- package/index.server.ts +256 -227
- package/package.json +14 -2
- package/paseo-plugin.json +2 -0
- package/screenshots/1-paseo-top-modal-system.jpg +0 -0
- package/screenshots/2-paseo-top-modal-workspace.jpg +0 -0
- package/screenshots/3-paseo-top-modal-settings.jpg +0 -0
- package/screenshots/4-paseo-top-modal-about.jpg +0 -0
- package/screenshots/paseo-top-dashboard.jpg +0 -0
- package/screenshots/paseo-top-general-view.jpg +0 -0
- package/server/resources.ts +98 -0
- package/server/vendor/paseo-plugin-helper/custom-pills.ts +70 -0
- package/server/vendor/paseo-plugin-helper/index.ts +4 -0
- package/server/vendor/paseo-plugin-helper/logger.ts +5 -16
- package/server/vendor/paseo-plugin-helper/mcp-injection.ts +20 -2
- package/server/vendor/paseo-plugin-helper/plugins.ts +184 -19
- package/server/vendor/paseo-plugin-helper/rpc-guard.ts +2 -2
- package/server/vendor/paseo-plugin-helper/storage-guard.ts +294 -0
- package/server/vendor/paseo-plugin-helper/storage.ts +36 -2
- package/server/vendor/paseo-plugin-helper/telemetry.ts +486 -0
- package/server/vendor/paseo-plugin-helper/tickets.ts +1232 -0
- package/server/vendor/permission-audit/index.ts +1 -0
- package/server/vendor/permission-audit/server.ts +839 -0
- package/shared/helper-version.ts +20 -0
- package/shared/multi-host.ts +156 -155
- package/shared/resources.ts +146 -1
- package/shared/vendor/paseo-plugin-helper/async.ts +14 -7
- package/shared/vendor/paseo-plugin-helper/features.ts +244 -0
- package/shared/vendor/paseo-plugin-helper/forge.ts +27 -0
- package/shared/vendor/paseo-plugin-helper/index.ts +2 -0
- package/shared/vendor/paseo-plugin-helper/tickets.ts +1104 -0
- package/shared/vendor/permission-audit/filter.ts +61 -0
- package/shared/vendor/permission-audit/index.ts +2 -0
- package/shared/vendor/permission-audit/shared.ts +119 -0
- package/shared/version.ts +1 -1
- package/client/vendor/paseo-plugin-helper/components/AboutSection.tsx +0 -493
- package/client/vendor/paseo-plugin-helper/components/AttentionBeacon.tsx +0 -250
- package/client/vendor/paseo-plugin-helper/components/Badge.tsx +0 -156
- package/client/vendor/paseo-plugin-helper/components/Button.tsx +0 -184
- package/client/vendor/paseo-plugin-helper/components/Card.tsx +0 -225
- package/client/vendor/paseo-plugin-helper/components/CodeBlock.tsx +0 -196
- package/client/vendor/paseo-plugin-helper/components/Collapsible.tsx +0 -277
- package/client/vendor/paseo-plugin-helper/components/CommandBox.tsx +0 -172
- package/client/vendor/paseo-plugin-helper/components/CopyButton.tsx +0 -180
- package/client/vendor/paseo-plugin-helper/components/EmptyState.tsx +0 -97
- package/client/vendor/paseo-plugin-helper/components/HighlightedText.tsx +0 -70
- package/client/vendor/paseo-plugin-helper/components/InlineButton.tsx +0 -75
- package/client/vendor/paseo-plugin-helper/components/KeyValue.tsx +0 -446
- package/client/vendor/paseo-plugin-helper/components/MetricGauge.tsx +0 -247
- package/client/vendor/paseo-plugin-helper/components/ProgressBar.tsx +0 -117
- package/client/vendor/paseo-plugin-helper/components/Responsive.tsx +0 -53
- package/client/vendor/paseo-plugin-helper/components/SearchInput.tsx +0 -118
- package/client/vendor/paseo-plugin-helper/components/SectionHeader.tsx +0 -80
- package/client/vendor/paseo-plugin-helper/components/Select.tsx +0 -215
- package/client/vendor/paseo-plugin-helper/components/StatusDot.tsx +0 -80
- package/client/vendor/paseo-plugin-helper/components/Tabs.tsx +0 -319
- package/client/vendor/paseo-plugin-helper/components/TextInput.tsx +0 -150
- package/client/vendor/paseo-plugin-helper/components/Toggle.tsx +0 -163
- package/client/vendor/paseo-plugin-helper/components/TruncatedText.tsx +0 -157
- package/client/vendor/paseo-plugin-helper/components/index.ts +0 -25
- package/client/vendor/paseo-plugin-helper/custom-pills.tsx +0 -224
- package/client/vendor/paseo-plugin-helper/forge-icon.tsx +0 -79
- package/client/vendor/paseo-plugin-helper/icon.tsx +0 -39
- package/client/vendor/paseo-plugin-helper/index.ts +0 -29
- package/client/vendor/paseo-plugin-helper/layout/ActionBar.tsx +0 -49
- package/client/vendor/paseo-plugin-helper/layout/FormRow.tsx +0 -103
- package/client/vendor/paseo-plugin-helper/layout/Grid.tsx +0 -65
- package/client/vendor/paseo-plugin-helper/layout/ModalBody.tsx +0 -378
- package/client/vendor/paseo-plugin-helper/layout/ModalContent.tsx +0 -51
- package/client/vendor/paseo-plugin-helper/layout/Row.tsx +0 -39
- package/client/vendor/paseo-plugin-helper/layout/Stack.tsx +0 -39
- package/client/vendor/paseo-plugin-helper/layout/index.ts +0 -7
- package/client/vendor/paseo-plugin-helper/styles/index.ts +0 -1
- package/client/vendor/paseo-plugin-helper/styles/recipes.ts +0 -550
- package/client/vendor/paseo-plugin-helper/surface.tsx +0 -80
- package/client/vendor/paseo-plugin-helper/theme/flair.ts +0 -76
- package/client/vendor/paseo-plugin-helper/theme/host-variables.ts +0 -121
- package/client/vendor/paseo-plugin-helper/theme/index.ts +0 -7
- package/client/vendor/paseo-plugin-helper/theme/provider.tsx +0 -178
- package/client/vendor/paseo-plugin-helper/theme/responsive.ts +0 -213
- package/client/vendor/paseo-plugin-helper/theme/tokens.ts +0 -200
- package/client/vendor/paseo-plugin-helper/theme/useResponsive.ts +0 -57
- /package/client/vendor/paseo-plugin-helper/{command-center.ts → core/command-center.ts} +0 -0
- /package/client/vendor/paseo-plugin-helper/{snapshot.ts → core/snapshot.ts} +0 -0
- /package/client/vendor/paseo-plugin-helper/{utils → lifecycle}/haptics.ts +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import type { PluginRpcContract } from "./rpc";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cleanup handle returned by a feature contribution.
|
|
5
|
+
*
|
|
6
|
+
* A disposer MUST be idempotent: calling it more than once must not throw and
|
|
7
|
+
* must not tear down anything twice. `composeFeatureModules` additionally
|
|
8
|
+
* wraps every disposer it receives so the *composed* teardown is idempotent
|
|
9
|
+
* even if an individual module forgets.
|
|
10
|
+
*/
|
|
11
|
+
export type FeatureDisposer = () => void;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A self-contained, droppable unit of plugin functionality.
|
|
15
|
+
*
|
|
16
|
+
* A feature module owns one concern (custom pills, timeline telemetry,
|
|
17
|
+
* permission auditing, …) and exposes it through up to two contribution hooks:
|
|
18
|
+
* `contributeServer` for the daemon-side `PluginServerContext` and
|
|
19
|
+
* `contributeClient` for the client-side `PluginClientContext`. Both hooks are
|
|
20
|
+
* optional; a module may contribute to one side, both, or neither.
|
|
21
|
+
*
|
|
22
|
+
* Lifecycle contract
|
|
23
|
+
* ------------------
|
|
24
|
+
* - A contribution hook runs at most once per `contribute*` call on the
|
|
25
|
+
* composing plugin entry.
|
|
26
|
+
* - It may return a {@link FeatureDisposer} for cleanup, or `void` when it owns
|
|
27
|
+
* nothing to release.
|
|
28
|
+
* - Returned disposers MUST be idempotent (see {@link FeatureDisposer}).
|
|
29
|
+
* - The plugin entry composes modules with {@link composeFeatureModules} and
|
|
30
|
+
* returns the combined disposer to Paseo.
|
|
31
|
+
* - `contracts` is declarative metadata (name-keyed RPC contracts the module
|
|
32
|
+
* owns); it is not registered automatically. The composing entry still calls
|
|
33
|
+
* `server.handle(contract, handler)`.
|
|
34
|
+
*
|
|
35
|
+
* Context types are generic because `paseo-plugin-helper/shared` must not
|
|
36
|
+
* import the Paseo SDK. Type a module with the SDK contexts at the call site:
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import type { PluginClientContext } from "@getpaseo/plugin/client";
|
|
40
|
+
* import type { PluginServerContext } from "@getpaseo/plugin/server";
|
|
41
|
+
* import type { FeatureModule } from "paseo-plugin-helper/shared";
|
|
42
|
+
*
|
|
43
|
+
* export const customPills: FeatureModule<PluginServerContext, PluginClientContext> = {
|
|
44
|
+
* id: "custom-pills",
|
|
45
|
+
* contracts: { list: listCustomPillsRpc },
|
|
46
|
+
* contributeServer(server) {
|
|
47
|
+
* const { unsubscribe } = registerCustomPillsServer(server);
|
|
48
|
+
* return unsubscribe;
|
|
49
|
+
* },
|
|
50
|
+
* contributeClient(client) {
|
|
51
|
+
* const remove = registerCustomPills(client);
|
|
52
|
+
* return remove;
|
|
53
|
+
* },
|
|
54
|
+
* };
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export interface FeatureModule<
|
|
58
|
+
TServerContext = unknown,
|
|
59
|
+
TClientContext = unknown,
|
|
60
|
+
> {
|
|
61
|
+
/** Stable, plugin-unique module id (e.g. `"custom-pills"`). */
|
|
62
|
+
readonly id: string;
|
|
63
|
+
/** Daemon-side contribution. Returns an idempotent disposer, or `void`. */
|
|
64
|
+
readonly contributeServer?: (server: TServerContext) => FeatureDisposer | void;
|
|
65
|
+
/** Client-side contribution. Returns an idempotent disposer, or `void`. */
|
|
66
|
+
readonly contributeClient?: (client: TClientContext) => FeatureDisposer | void;
|
|
67
|
+
/** RPC contracts this module owns, keyed by a local name. */
|
|
68
|
+
readonly contracts?: Record<string, PluginRpcContract>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* A composed set of feature modules. `contributeServer` / `contributeClient`
|
|
73
|
+
* run every module's hook for that side and return a single combined,
|
|
74
|
+
* idempotent disposer that tears the modules down in reverse order.
|
|
75
|
+
*/
|
|
76
|
+
export interface FeatureComposition<
|
|
77
|
+
TServerContext = unknown,
|
|
78
|
+
TClientContext = unknown,
|
|
79
|
+
> {
|
|
80
|
+
/** Module ids in composition order. */
|
|
81
|
+
readonly ids: readonly string[];
|
|
82
|
+
/** Every declared contract, flattened in module order and de-duplicated. */
|
|
83
|
+
readonly contracts: readonly PluginRpcContract[];
|
|
84
|
+
/** Run all `contributeServer` hooks; returns the combined disposer. */
|
|
85
|
+
contributeServer(server: TServerContext): FeatureDisposer;
|
|
86
|
+
/** Run all `contributeClient` hooks; returns the combined disposer. */
|
|
87
|
+
contributeClient(client: TClientContext): FeatureDisposer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function toIdempotentDisposer(disposer: FeatureDisposer): FeatureDisposer {
|
|
91
|
+
let called = false;
|
|
92
|
+
return () => {
|
|
93
|
+
if (called) return;
|
|
94
|
+
called = true;
|
|
95
|
+
disposer();
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Run a set of disposers in reverse (LIFO) order. Every disposer runs even if
|
|
101
|
+
* an earlier one throws; the first error is re-thrown after teardown finishes.
|
|
102
|
+
*/
|
|
103
|
+
function disposeAll(disposers: readonly FeatureDisposer[]): void {
|
|
104
|
+
let hasError = false;
|
|
105
|
+
let firstError: unknown;
|
|
106
|
+
for (let i = disposers.length - 1; i >= 0; i -= 1) {
|
|
107
|
+
try {
|
|
108
|
+
disposers[i]!();
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (!hasError) {
|
|
111
|
+
hasError = true;
|
|
112
|
+
firstError = error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (hasError) throw firstError;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Collect the disposers produced by a per-side contribution hook. If a module
|
|
121
|
+
* throws mid-composition, already-contributed modules are disposed before the
|
|
122
|
+
* error is re-thrown so a failed composition never leaks partial state.
|
|
123
|
+
*/
|
|
124
|
+
function runContributions<TServerContext, TClientContext>(
|
|
125
|
+
modules: readonly FeatureModule<TServerContext, TClientContext>[],
|
|
126
|
+
contribute: (
|
|
127
|
+
module: FeatureModule<TServerContext, TClientContext>,
|
|
128
|
+
) => FeatureDisposer | void,
|
|
129
|
+
): FeatureDisposer {
|
|
130
|
+
const disposers: FeatureDisposer[] = [];
|
|
131
|
+
let disposed = false;
|
|
132
|
+
const dispose = () => {
|
|
133
|
+
if (disposed) return;
|
|
134
|
+
disposed = true;
|
|
135
|
+
disposeAll(disposers);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
for (const module of modules) {
|
|
140
|
+
const result = contribute(module);
|
|
141
|
+
if (typeof result === "function") {
|
|
142
|
+
disposers.push(toIdempotentDisposer(result));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} catch (error) {
|
|
146
|
+
// Roll back what already mounted, but never let a failing disposer mask
|
|
147
|
+
// the contribution error that triggered the rollback.
|
|
148
|
+
try {
|
|
149
|
+
dispose();
|
|
150
|
+
} catch {
|
|
151
|
+
// ignored
|
|
152
|
+
}
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return dispose;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function assertUniqueModules<TServerContext, TClientContext>(
|
|
160
|
+
modules: readonly FeatureModule<TServerContext, TClientContext>[],
|
|
161
|
+
): void {
|
|
162
|
+
const seen = new Set<string>();
|
|
163
|
+
for (const module of modules) {
|
|
164
|
+
const id = typeof module.id === "string" ? module.id.trim() : "";
|
|
165
|
+
if (!id) {
|
|
166
|
+
throw new Error("Feature module id must be a non-empty string");
|
|
167
|
+
}
|
|
168
|
+
if (seen.has(id)) {
|
|
169
|
+
throw new Error(`Duplicate feature module id "${id}"`);
|
|
170
|
+
}
|
|
171
|
+
seen.add(id);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function collectContracts<TServerContext, TClientContext>(
|
|
176
|
+
modules: readonly FeatureModule<TServerContext, TClientContext>[],
|
|
177
|
+
): readonly PluginRpcContract[] {
|
|
178
|
+
const contracts: PluginRpcContract[] = [];
|
|
179
|
+
const seen = new Set<string>();
|
|
180
|
+
for (const module of modules) {
|
|
181
|
+
for (const contract of Object.values(module.contracts ?? {})) {
|
|
182
|
+
if (seen.has(contract.name)) {
|
|
183
|
+
throw new Error(
|
|
184
|
+
`Duplicate RPC contract "${contract.name}" across feature modules`,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
seen.add(contract.name);
|
|
188
|
+
contracts.push(contract);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return Object.freeze(contracts);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Compose {@link FeatureModule}s into one contribution unit for a plugin entry.
|
|
196
|
+
*
|
|
197
|
+
* Modules run in array order on contribution and are disposed in reverse (LIFO)
|
|
198
|
+
* order. The returned combined disposer is idempotent: calling it twice runs
|
|
199
|
+
* teardown once and never throws the first error a second time.
|
|
200
|
+
*
|
|
201
|
+
* ```ts
|
|
202
|
+
* import type { PluginClientContext } from "@getpaseo/plugin/client";
|
|
203
|
+
* import type { PluginServerContext } from "@getpaseo/plugin/server";
|
|
204
|
+
* import { composeFeatureModules } from "paseo-plugin-helper/shared";
|
|
205
|
+
* import { customPills } from "./features/custom-pills";
|
|
206
|
+
* import { timelineTelemetry } from "./features/timeline-telemetry";
|
|
207
|
+
*
|
|
208
|
+
* const features = composeFeatureModules<PluginServerContext, PluginClientContext>([
|
|
209
|
+
* customPills,
|
|
210
|
+
* timelineTelemetry,
|
|
211
|
+
* ]);
|
|
212
|
+
*
|
|
213
|
+
* export function contributeServer(server: PluginServerContext) {
|
|
214
|
+
* return features.contributeServer(server);
|
|
215
|
+
* }
|
|
216
|
+
*
|
|
217
|
+
* export function contributeClient(client: PluginClientContext) {
|
|
218
|
+
* return features.contributeClient(client);
|
|
219
|
+
* }
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* @throws if two modules share an `id` or declare the same RPC contract `name`.
|
|
223
|
+
*/
|
|
224
|
+
export function composeFeatureModules<
|
|
225
|
+
TServerContext = unknown,
|
|
226
|
+
TClientContext = unknown,
|
|
227
|
+
>(
|
|
228
|
+
modules: readonly FeatureModule<TServerContext, TClientContext>[],
|
|
229
|
+
): FeatureComposition<TServerContext, TClientContext> {
|
|
230
|
+
const list = [...modules];
|
|
231
|
+
assertUniqueModules(list);
|
|
232
|
+
const contracts = collectContracts(list);
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
ids: Object.freeze(list.map((module) => module.id)),
|
|
236
|
+
contracts,
|
|
237
|
+
contributeServer(server) {
|
|
238
|
+
return runContributions(list, (module) => module.contributeServer?.(server));
|
|
239
|
+
},
|
|
240
|
+
contributeClient(client) {
|
|
241
|
+
return runContributions(list, (module) => module.contributeClient?.(client));
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
@@ -108,3 +108,30 @@ export function resolveForgeMark(
|
|
|
108
108
|
const resolved = isForgeKind(explicit) ? explicit : forgeKindFromHost(host);
|
|
109
109
|
return FORGE_MARKS[resolved];
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Official monochrome forge marks (Simple Icons, CC0 / project trademarks),
|
|
114
|
+
* authored on a 24x24 viewBox. Rendered as inline SVG through a data URI so a
|
|
115
|
+
* consumer needs no SVG dependency: exact vector marks on web/Electron, where
|
|
116
|
+
* Paseo renders React Native Web, and a Lucide fallback on native.
|
|
117
|
+
*
|
|
118
|
+
* Pure and React-free so it lives in `shared/` next to the resolver.
|
|
119
|
+
*/
|
|
120
|
+
const FORGE_MARK_PATHS: Partial<Record<ForgeKind, string>> = {
|
|
121
|
+
codeberg:
|
|
122
|
+
"M11.999.747A11.974 11.974 0 0 0 0 12.75c0 2.254.635 4.465 1.833 6.376L11.837 6.19c.072-.092.251-.092.323 0l4.178 5.402h-2.992l.065.239h3.113l.882 1.138h-3.674l.103.374h3.86l.777 1.003h-4.358l.135.483h4.593l.695.894h-5.038l.165.589h5.326l.609.785h-5.717l.182.65h6.038l.562.727h-6.397l.183.65h6.717A12.003 12.003 0 0 0 24 12.75 11.977 11.977 0 0 0 11.999.747zm3.654 19.104.182.65h5.326c.173-.204.353-.433.513-.65zm.385 1.377.18.65h3.563c.233-.198.485-.428.712-.65zm.383 1.377.182.648h1.203c.356-.204.685-.412 1.042-.648zz",
|
|
123
|
+
forgejo:
|
|
124
|
+
"M16.7773 0c1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.1175a7.0759 7.0759 0 0 1 4.148-1.4205l.1176-.001 1.3385.0002c.4973-.8827 1.4434-1.4788 2.5288-1.4788 1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.319c.8827.4973 1.4788 1.4434 1.4788 2.5287 0 1.602-1.2986 2.9005-2.9005 2.9005-1.6018 0-2.9004-1.2986-2.9004-2.9005 0-1.0853.596-2.0314 1.4788-2.5287l-.0002-9.9831c0-3.887 3.1195-7.0453 6.9915-7.108l.1176-.001h1.3385C14.7458.5962 15.692 0 16.7773 0ZM7.2227 19.9052c-.6596 0-1.1943.5347-1.1943 1.1943s.5347 1.1943 1.1943 1.1943 1.1944-.5347 1.1944-1.1943-.5348-1.1943-1.1944-1.1943Zm9.5546-10.4644c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Zm0-7.7346c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Z",
|
|
125
|
+
gitea:
|
|
126
|
+
"M4.209 4.603c-.247 0-.525.02-.84.088-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768 1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367 2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068 0 0 2.107-4.471 2.107-8.823-.042-1.318-.367-1.55-.443-1.627-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12zm8.33 2.554c.26.003.509.127.509.127l.868.422-.529 1.075a.686.686 0 0 0-.614.359.685.685 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527.687.687 0 0 0 .347.763.686.686 0 0 0 .867-.206.688.688 0 0 0-.069-.882l.916-1.874a.667.667 0 0 0 .237-.02.657.657 0 0 0 .271-.137 8.826 8.826 0 0 1 1.016.512.761.761 0 0 1 .286.282c.073.21-.073.569-.073.569-.087.29-.702 1.55-.702 1.55a.692.692 0 0 0-.676.477.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431.19-.397.515-1.16.515-1.16.035-.066.218-.394.103-.814-.095-.435-.48-.638-.48-.638-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.688.688 0 0 0-.148-.241l.516-1.062 2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.065 1.065 0 0 1-.393-.045l-.202-.08-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.855.855 0 0 1 .35-.077z",
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/** Inline SVG data URI for a custom mark, tinted with the resolved color. */
|
|
130
|
+
export function forgeMarkSource(kind: ForgeKind, color: string): { uri: string } | null {
|
|
131
|
+
const path = FORGE_MARK_PATHS[kind];
|
|
132
|
+
if (!path) return null;
|
|
133
|
+
const svg =
|
|
134
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">` +
|
|
135
|
+
`<path fill="${color}" d="${path}"/></svg>`;
|
|
136
|
+
return { uri: `data:image/svg+xml,${encodeURIComponent(svg)}` };
|
|
137
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./types";
|
|
2
2
|
export * from "./rpc";
|
|
3
|
+
export * from "./features";
|
|
3
4
|
export * from "./formatters";
|
|
4
5
|
export * from "./settings";
|
|
5
6
|
export * from "./suite-settings";
|
|
@@ -8,3 +9,4 @@ export * from "./suppressed";
|
|
|
8
9
|
export * from "./custom-pills";
|
|
9
10
|
export * from "./forge";
|
|
10
11
|
export * from "./highlight";
|
|
12
|
+
export * from "./tickets";
|