dsh-skill-hub 0.0.1 → 0.2.0
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/CONTRIBUTING.md +56 -0
- package/README.md +355 -20
- package/cordis.patch.yml +12 -0
- package/lib/client.js +4514 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +3119 -0
- package/lib/invariant.js +6 -0
- package/lib/types/client/SkillHubSettingsCard.d.ts +53 -0
- package/lib/types/client/api-config-scope.d.ts +48 -0
- package/lib/types/client/api.d.ts +64 -0
- package/lib/types/client/grouping.d.ts +64 -0
- package/lib/types/client/helpers.d.ts +11 -0
- package/lib/types/client/index.d.ts +42 -0
- package/lib/types/client/locales.d.ts +216 -0
- package/lib/types/client/market-catalog.d.ts +14 -0
- package/lib/types/client/panel/DisabledRow.d.ts +12 -0
- package/lib/types/client/panel/GroupSummary.d.ts +10 -0
- package/lib/types/client/panel/MarketView.d.ts +11 -0
- package/lib/types/client/panel/ScenesView.d.ts +11 -0
- package/lib/types/client/panel/SkillDetailView.d.ts +31 -0
- package/lib/types/client/panel/SkillHubPanel.d.ts +18 -0
- package/lib/types/client/panel/SkillRow.d.ts +11 -0
- package/lib/types/client/panel/SourceStatusBadge.d.ts +18 -0
- package/lib/types/client/panel/SourcesView.d.ts +10 -0
- package/lib/types/client/panel/TagEditorView.d.ts +29 -0
- package/lib/types/client/panel/dialogs.d.ts +73 -0
- package/lib/types/client/panel/format.d.ts +14 -0
- package/lib/types/client/panel/useSkillHub.d.ts +183 -0
- package/lib/types/client/settings-card.d.ts +81 -0
- package/lib/types/client/settings-form.d.ts +95 -0
- package/lib/types/client/settings-nav-icon.d.ts +8 -0
- package/lib/types/index.d.ts +36 -0
- package/lib/types/invariant.d.ts +3 -0
- package/lib/types/protocol.d.ts +571 -0
- package/lib/types/provider.d.ts +47 -0
- package/lib/types/repo.d.ts +133 -0
- package/lib/types/routes.d.ts +51 -0
- package/lib/types/skillfs.d.ts +95 -0
- package/lib/types/stats.d.ts +49 -0
- package/lib/types/store.d.ts +142 -0
- package/lib/types/update.d.ts +20 -0
- package/package.json +115 -11
- package/src/client/SkillHubSettingsCard.tsx +161 -0
- package/src/client/api-config-scope.test.ts +79 -0
- package/src/client/api-config-scope.ts +119 -0
- package/src/client/api.ts +327 -0
- package/src/client/css-modules.d.ts +5 -0
- package/src/client/grouping.test.ts +109 -0
- package/src/client/grouping.ts +120 -0
- package/src/client/helpers.ts +23 -0
- package/src/client/index.tsx +104 -0
- package/src/client/locales.ts +432 -0
- package/src/client/market-catalog.ts +22 -0
- package/src/client/panel/DisabledRow.tsx +32 -0
- package/src/client/panel/GroupSummary.tsx +27 -0
- package/src/client/panel/MarketView.tsx +173 -0
- package/src/client/panel/ScenesView.tsx +75 -0
- package/src/client/panel/SkillDetailView.tsx +95 -0
- package/src/client/panel/SkillHubPanel.tsx +347 -0
- package/src/client/panel/SkillRow.tsx +54 -0
- package/src/client/panel/SourceStatusBadge.tsx +61 -0
- package/src/client/panel/SourcesView.tsx +104 -0
- package/src/client/panel/TagEditorView.tsx +89 -0
- package/src/client/panel/dialogs.tsx +185 -0
- package/src/client/panel/format.ts +31 -0
- package/src/client/panel/panel.module.css +219 -0
- package/src/client/panel/useSkillHub.ts +797 -0
- package/src/client/settings-card.module.css +52 -0
- package/src/client/settings-card.tsx +237 -0
- package/src/client/settings-form.ts +227 -0
- package/src/client/settings-nav-icon.ts +42 -0
- package/src/index.ts +181 -0
- package/src/invariant.ts +4 -0
- package/src/protocol.ts +622 -0
- package/src/provider.test.ts +112 -0
- package/src/provider.ts +168 -0
- package/src/repo.test.ts +212 -0
- package/src/repo.ts +528 -0
- package/src/routes.test.ts +786 -0
- package/src/routes.ts +1252 -0
- package/src/skillfs.test.ts +290 -0
- package/src/skillfs.ts +306 -0
- package/src/stats.test.ts +168 -0
- package/src/stats.ts +124 -0
- package/src/store.test.ts +253 -0
- package/src/store.ts +628 -0
- package/src/update.test.ts +73 -0
- package/src/update.ts +136 -0
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dsh-skill-hub plugin settings card: bridges the hub's own config route
|
|
3
|
+
* (ApiConfigScope → /api/skill-hub/config) onto the family-style staged card
|
|
4
|
+
* form (enabled master switch + agent announcement). Registered into the
|
|
5
|
+
* official `settings.plugin.item` slot so the plugin shows up in Settings →
|
|
6
|
+
* 插件. The scope is a FormScope, so the card never touches the settings
|
|
7
|
+
* service (the host refuses third-party namespaces).
|
|
8
|
+
*/
|
|
9
|
+
import type { ReactElement } from 'react';
|
|
10
|
+
import type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';
|
|
11
|
+
import { CardForm, type CardShell, type FieldState, type FormScope } from './settings-form.ts';
|
|
12
|
+
/** The card's projected state. */
|
|
13
|
+
export interface SkillHubSettingsState extends CardShell {
|
|
14
|
+
enabled: FieldState;
|
|
15
|
+
announceToAgent: FieldState;
|
|
16
|
+
dotModelColor: FieldState;
|
|
17
|
+
dotUserColor: FieldState;
|
|
18
|
+
showUseCount: FieldState;
|
|
19
|
+
showUseTime: FieldState;
|
|
20
|
+
showGroupSummary: FieldState;
|
|
21
|
+
}
|
|
22
|
+
/** Props the slot renderer receives (locale copy + injected form actions). */
|
|
23
|
+
export interface SkillHubSettingsCardProps {
|
|
24
|
+
t: (key: string) => string;
|
|
25
|
+
useSkillHubSettingsCard: <T>(selector: (snapshot: SkillHubSettingsState) => T) => T;
|
|
26
|
+
save: () => void;
|
|
27
|
+
discard: () => void;
|
|
28
|
+
edit: (field: string, text: string) => void;
|
|
29
|
+
resetField: (field: string) => void;
|
|
30
|
+
}
|
|
31
|
+
/** Bridges the hub's config scope onto the card's staged form. */
|
|
32
|
+
export declare class SkillHubSettingsCardController {
|
|
33
|
+
private readonly form;
|
|
34
|
+
private readonly store;
|
|
35
|
+
/** @param scope - the hub config scope the card edits (ApiConfigScope). */
|
|
36
|
+
constructor(scope: FormScope);
|
|
37
|
+
private projection;
|
|
38
|
+
/**
|
|
39
|
+
* Build the face the card's slot registration injects.
|
|
40
|
+
* @returns the card's snapshot hook and its form actions.
|
|
41
|
+
*/
|
|
42
|
+
inject(): {
|
|
43
|
+
hooks: {
|
|
44
|
+
skillHubSettingsCard: SnapshotStore<SkillHubSettingsState>;
|
|
45
|
+
};
|
|
46
|
+
} & ReturnType<CardForm['actions']>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Render the dsh-skill-hub card.
|
|
50
|
+
* @param props - locale copy, the card snapshot, and its form actions.
|
|
51
|
+
* @returns the card.
|
|
52
|
+
*/
|
|
53
|
+
export declare function SkillHubSettingsCard(props: SkillHubSettingsCardProps): ReactElement;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApiConfigScope — a FormScope-compatible view over the hub's own config
|
|
3
|
+
* route (/api/skill-hub/config). The host's settings service refuses to
|
|
4
|
+
* expose third-party namespaces to the web client (dsh-host-apiproxy's
|
|
5
|
+
* allowlist), so the settings card talks to this plugin-owned route instead
|
|
6
|
+
* of the settings transport.
|
|
7
|
+
*
|
|
8
|
+
* The scope mirrors the settings-scope contract the vendored CardForm
|
|
9
|
+
* consumes: `value` is the effective config, `base` the built-in defaults,
|
|
10
|
+
* and `user` the raw saved overrides (a field's presence there marks it
|
|
11
|
+
* overridden). Writes go straight through saveConfig and re-seed the
|
|
12
|
+
* snapshot from the route's response, so the card's save-verification
|
|
13
|
+
* (user layer equals the written value) sees the persisted state.
|
|
14
|
+
*/
|
|
15
|
+
import type { SkillHubApi } from './api.ts';
|
|
16
|
+
import type { FormScope } from './settings-form.ts';
|
|
17
|
+
/** Model-invocable dot color default. Single source for the TS side; the
|
|
18
|
+
* panel's CSS mirrors it via --hub-model (panel.module.css). */
|
|
19
|
+
export declare const DEFAULT_DOT_MODEL_COLOR = "#2f81f7";
|
|
20
|
+
/** User-invocable dot color default. Single source for the TS side; the
|
|
21
|
+
* panel's CSS mirrors it via --hub-user (panel.module.css). */
|
|
22
|
+
export declare const DEFAULT_DOT_USER_COLOR = "#3fb950";
|
|
23
|
+
/** FormScope-compatible reactive config handle (see module doc). */
|
|
24
|
+
export declare class ApiConfigScope implements FormScope {
|
|
25
|
+
private readonly api;
|
|
26
|
+
private status;
|
|
27
|
+
private value;
|
|
28
|
+
private saved;
|
|
29
|
+
private readonly listeners;
|
|
30
|
+
/** @param api - the browser-half API client (shared with the skill panel). */
|
|
31
|
+
constructor(api: SkillHubApi);
|
|
32
|
+
private load;
|
|
33
|
+
subscribe(listener: () => void): () => void;
|
|
34
|
+
getSnapshot(): {
|
|
35
|
+
status: string;
|
|
36
|
+
writable: boolean;
|
|
37
|
+
value?: Record<string, unknown>;
|
|
38
|
+
base?: unknown;
|
|
39
|
+
user?: unknown;
|
|
40
|
+
};
|
|
41
|
+
/** Write one field through the config route and adopt the persisted state. */
|
|
42
|
+
set(field: string, value: unknown): Promise<void>;
|
|
43
|
+
/** Clear one field's override so it re-inherits the default. */
|
|
44
|
+
unset(field: string): Promise<void>;
|
|
45
|
+
/** Persist a patch, then re-seed from the route's fresh response. */
|
|
46
|
+
private apply;
|
|
47
|
+
private publish;
|
|
48
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-side API client for the /api/skill-hub route family. The only
|
|
3
|
+
* data access path the panel uses — plain fetch, same origin.
|
|
4
|
+
*/
|
|
5
|
+
import { type CatalogResponse, type ConfigRequest, type ConfigResponse, type CreateRequest, type CreateResponse, type MarketCheckResponse, type MarketSourcesResponse, type MarketSyncResponse, type RepoDiscoverResponse, type RepoImportResponse, type SkillDetail, type SkillDeleteResponse, type SourceCheckResponse, type SourceDeleteResponse, type SourceRestoreResponse, type SourceTrashClearResponse, type SourcesResponse, type SourceSyncResponse, type StatsResponse, type ToggleBatchResponse, type UpdateCheckResponse } from '../protocol.ts';
|
|
6
|
+
/** Error carrying the route's JSON error message. */
|
|
7
|
+
export declare class SkillHubApiError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
/** The browser half's only data entry point. */
|
|
11
|
+
export declare class SkillHubApi {
|
|
12
|
+
catalog(): Promise<CatalogResponse>;
|
|
13
|
+
skill(name: string): Promise<SkillDetail>;
|
|
14
|
+
/** Move one writable skill into the restorable trash. */
|
|
15
|
+
deleteSkill(name: string): Promise<SkillDeleteResponse>;
|
|
16
|
+
/** Toggle one skill; resolves with the fresh catalog from the route. */
|
|
17
|
+
toggle(name: string, enabled: boolean): Promise<CatalogResponse>;
|
|
18
|
+
create(payload: CreateRequest): Promise<CreateResponse>;
|
|
19
|
+
stats(): Promise<StatsResponse>;
|
|
20
|
+
/** Toggle a whole group in one write; resolves with the fresh catalog + failures. */
|
|
21
|
+
toggleBatch(names: string[], enabled: boolean): Promise<ToggleBatchResponse>;
|
|
22
|
+
/** The user's added market sources (codex-style repo slugs). */
|
|
23
|
+
market(): Promise<MarketSourcesResponse>;
|
|
24
|
+
/** Add a market source repo; resolves with the fresh list. */
|
|
25
|
+
addMarketSource(repo: string): Promise<MarketSourcesResponse>;
|
|
26
|
+
/** Remove a market source repo; resolves with the fresh list. */
|
|
27
|
+
removeMarketSource(repo: string): Promise<MarketSourcesResponse>;
|
|
28
|
+
/** Check every market source for updates (throttled server-side). */
|
|
29
|
+
marketCheck(): Promise<MarketCheckResponse>;
|
|
30
|
+
/** Align a market source to its pinned ref; resolves with tracked skills. */
|
|
31
|
+
marketSync(repo: string): Promise<MarketSyncResponse>;
|
|
32
|
+
/** Pin a market source to an explicit ref (branch picker). */
|
|
33
|
+
setMarketSourceRef(repo: string, ref: string): Promise<MarketSourcesResponse>;
|
|
34
|
+
/** Check the hub's own latest GitHub release. */
|
|
35
|
+
updateCheck(): Promise<UpdateCheckResponse>;
|
|
36
|
+
/** Discover importable skills in a GitHub repo. */
|
|
37
|
+
repoDiscover(repo: string): Promise<RepoDiscoverResponse>;
|
|
38
|
+
/** Install selected repo skills into the user-dsh root (records the source). */
|
|
39
|
+
repoImport(repo: string, paths: string[], ref?: string): Promise<RepoImportResponse>;
|
|
40
|
+
/** Read the hub's runtime config (effective values + saved overrides). */
|
|
41
|
+
config(): Promise<ConfigResponse>;
|
|
42
|
+
/** Patch the hub's runtime config (null clears a saved override). */
|
|
43
|
+
saveConfig(patch: ConfigRequest): Promise<ConfigResponse>;
|
|
44
|
+
/** 用户 tag 分组 + 系统集合组 + origin 映射。 */
|
|
45
|
+
groups(): Promise<import('../protocol.ts').GroupsResponse>;
|
|
46
|
+
/** 新建(无 id)或重命名(带 id)一个 tag 分组;返回全部 tag。 */
|
|
47
|
+
saveTag(payload: import('../protocol.ts').TagSaveRequest): Promise<import('../protocol.ts').SkillTag[]>;
|
|
48
|
+
/** 删除一个 tag 分组;返回全部 tag。 */
|
|
49
|
+
deleteTag(id: string): Promise<import('../protocol.ts').SkillTag[]>;
|
|
50
|
+
/** 直接设置某 tag 的完整成员列表;返回全部 tag。 */
|
|
51
|
+
setTagMembers(id: string, skillNames: string[]): Promise<import('../protocol.ts').SkillTag[]>;
|
|
52
|
+
/** 来源列表 + 派生 origin 映射 + 集合组 + 回收站。 */
|
|
53
|
+
sources(): Promise<SourcesResponse>;
|
|
54
|
+
/** 检查指定(或全部)来源的上游更新。 */
|
|
55
|
+
checkSources(repo?: string): Promise<SourceCheckResponse>;
|
|
56
|
+
/** 同步一个来源的所选(或全部)技能到上游最新版本。 */
|
|
57
|
+
syncSource(repo: string, skills?: string[]): Promise<SourceSyncResponse>;
|
|
58
|
+
/** 跟进上游删除:把所选技能移入回收站。 */
|
|
59
|
+
confirmDeleteSource(repo: string, skills: string[]): Promise<SourceDeleteResponse>;
|
|
60
|
+
/** 从回收站恢复一个技能。 */
|
|
61
|
+
restoreSource(name: string): Promise<SourceRestoreResponse>;
|
|
62
|
+
/** Permanently delete every skill currently in the trash. */
|
|
63
|
+
clearTrash(): Promise<SourceTrashClearResponse>;
|
|
64
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure grouping helpers for the skill-hub panel (no React/DOM deps, so the
|
|
3
|
+
* merge/classify/filter logic stays unit-testable).
|
|
4
|
+
*
|
|
5
|
+
* The "分组" view unifies two ways a skill can belong to a group:
|
|
6
|
+
* - user tags (sidecar SkillTag)
|
|
7
|
+
* - origin collections (sidecar sources → backend-aggregated CollectionGroup)
|
|
8
|
+
*
|
|
9
|
+
* Switch semantics: a skill's enabled state is global (the file is renamed
|
|
10
|
+
* once), so a group switch is derived from its members' actual states:
|
|
11
|
+
* all members enabled → 'on', all disabled → 'off', otherwise 'mixed'.
|
|
12
|
+
* Closing a group whose member is enabled in another group is a conflict the
|
|
13
|
+
* GUI resolves with a dialog; the helpers below compute both sides.
|
|
14
|
+
*/
|
|
15
|
+
import type { CatalogSkill, CollectionGroup, SkillTag } from '../protocol.ts';
|
|
16
|
+
/** Grouped switch state derived from member enablement. */
|
|
17
|
+
export type GroupSwitchState = 'on' | 'off' | 'mixed';
|
|
18
|
+
/** The derived switch view of one group. */
|
|
19
|
+
export interface GroupSwitchView {
|
|
20
|
+
state: GroupSwitchState;
|
|
21
|
+
/** Writable members currently enabled. */
|
|
22
|
+
enabled: string[];
|
|
23
|
+
/** Writable members currently disabled. */
|
|
24
|
+
disabled: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Derive a group switch view from its member names and the set of currently
|
|
28
|
+
* enabled skill names (catalog.skills). Members not in the enabled set count
|
|
29
|
+
* as disabled (catalog.disabled or absent read-only rows).
|
|
30
|
+
*/
|
|
31
|
+
export declare function groupSwitchView(members: readonly string[], enabledNames: ReadonlySet<string>): GroupSwitchView;
|
|
32
|
+
/** Names of every group a skill belongs to (tags + collections). */
|
|
33
|
+
export declare function groupNamesOf(name: string, tags: readonly SkillTag[], collections: readonly CollectionGroup[]): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Members of a group that are currently enabled AND also belong to at least
|
|
36
|
+
* one other group — the set a "close" action must ask about.
|
|
37
|
+
*/
|
|
38
|
+
export declare function conflictsOnClose(members: readonly string[], enabledNames: ReadonlySet<string>, otherGroups: ReadonlyArray<{
|
|
39
|
+
members: readonly string[];
|
|
40
|
+
}>): string[];
|
|
41
|
+
/** Origin-repo filter value: skills with no source record (private skills). */
|
|
42
|
+
export declare const PRIVATE_SOURCE = "private";
|
|
43
|
+
/**
|
|
44
|
+
* Apply the origin filter ('all' or a specific origin repo; skills without a
|
|
45
|
+
* source record count as PRIVATE_SOURCE). The origins map is the store's
|
|
46
|
+
* skillName → repo derivation, so filtering follows the tracked source
|
|
47
|
+
* records instead of the filesystem root a skill happens to live under.
|
|
48
|
+
*/
|
|
49
|
+
export declare function filterBySource(skills: readonly CatalogSkill[], source: string, origins: Readonly<Record<string, string>>): CatalogSkill[];
|
|
50
|
+
/** Catalog sort keys offered by the filter bar. */
|
|
51
|
+
export type SortKey = 'name' | 'added' | 'uses';
|
|
52
|
+
/**
|
|
53
|
+
* Sort a skill list in place-safe copy order: name ascending, added
|
|
54
|
+
* descending (newest first, unknown addedAt last), or uses descending
|
|
55
|
+
* (most-called first). Unknown values always trail.
|
|
56
|
+
*/
|
|
57
|
+
export declare function sortSkills(skills: readonly CatalogSkill[], key: SortKey, getUses?: (name: string) => number | undefined): CatalogSkill[];
|
|
58
|
+
/** Localized relative-time tuple; the caller resolves it via tt(). */
|
|
59
|
+
export interface RelativeTime {
|
|
60
|
+
key: 'time.justNow' | 'time.minutesAgo' | 'time.hoursAgo' | 'time.daysAgo' | 'time.weeksAgo';
|
|
61
|
+
value?: number;
|
|
62
|
+
}
|
|
63
|
+
/** Format an epoch-ms timestamp as a short relative time bucket. */
|
|
64
|
+
export declare function formatRelativeTime(ms: number, now?: number): RelativeTime;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared panel helpers: the active-dictionary pick (document-language
|
|
3
|
+
* based, family precedent) plus a small error-message extractor.
|
|
4
|
+
*/
|
|
5
|
+
import { type HubKey, type TranslateValues } from './locales.ts';
|
|
6
|
+
/** Active dictionary, picked by the document language at call time. */
|
|
7
|
+
export declare function dictionary(): Record<string, string>;
|
|
8
|
+
/** Translate a key with optional {name} template params (current language). */
|
|
9
|
+
export declare function tt(key: HubKey, values?: TranslateValues): string;
|
|
10
|
+
/** Human-readable error text from an unknown thrown value. */
|
|
11
|
+
export declare function errorMessage(error: unknown): string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-half entry for the dsh-skill-hub plugin — runs inside the dsh
|
|
3
|
+
* web GUI.
|
|
4
|
+
*
|
|
5
|
+
* Registers the dsh-skill-hub locale dictionaries and mounts two Settings
|
|
6
|
+
* surfaces, both through official slots (no DOM injection):
|
|
7
|
+
* - a plugin-management card in the `settings.plugin.item` slot (Settings →
|
|
8
|
+
* 插件 → 可配置插件列表), bound to the hub's own /api/skill-hub/config
|
|
9
|
+
* route via ApiConfigScope — the family-bucket card pattern
|
|
10
|
+
* (PluginSettingsCard + CardForm vendored from dsh-task-board). The host's
|
|
11
|
+
* settings service refuses third-party namespaces, so the card never
|
|
12
|
+
* touches the settings transport;
|
|
13
|
+
* - a top-level Settings section (Settings → 技能) hosting the skill hub
|
|
14
|
+
* panel: catalog, search, enable/disable, diagnostics, new-skill form.
|
|
15
|
+
*
|
|
16
|
+
* Failure policy: mounting problems are logged, never thrown — the web
|
|
17
|
+
* shell fails the whole boot when a plugin apply throws, and an external
|
|
18
|
+
* plugin must not take the GUI down.
|
|
19
|
+
*
|
|
20
|
+
* Export discipline (packages/client rule): the /client surface carries
|
|
21
|
+
* what cordis loading needs plus types only — all value exports stay
|
|
22
|
+
* internal.
|
|
23
|
+
*/
|
|
24
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
25
|
+
import { type HubKey } from './locales.ts';
|
|
26
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
27
|
+
interface LocaleNamespaceMap {
|
|
28
|
+
/** dsh-skill-hub surface copy. */
|
|
29
|
+
'dsh-skill-hub': HubKey;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Required services (fiber inject waiting — the runtime must be up first). */
|
|
33
|
+
export declare const inject: string[];
|
|
34
|
+
/** Type-only surface (export discipline: no value exports beyond the plugin contract). */
|
|
35
|
+
export type { SkillHubPanelProps } from './panel/SkillHubPanel.tsx';
|
|
36
|
+
export type { SkillHubSettingsState } from './SkillHubSettingsCard.tsx';
|
|
37
|
+
export type { HubKey } from './locales.ts';
|
|
38
|
+
/**
|
|
39
|
+
* Mount the settings card and the skill hub section.
|
|
40
|
+
* @param ctx - client root context (slots, locale).
|
|
41
|
+
*/
|
|
42
|
+
export declare function apply(ctx: ClientContext): void;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-skill-hub surface copy (zh/en). The dictionary type is re-exported
|
|
3
|
+
* so the LocaleNamespaceMap module augmentation in client/index.ts can
|
|
4
|
+
* reference it without a value import.
|
|
5
|
+
*/
|
|
6
|
+
export declare const zh: {
|
|
7
|
+
readonly 'entry.label': "技能";
|
|
8
|
+
readonly 'entry.tooltip': "技能中枢:浏览、分组与同步管理本地技能";
|
|
9
|
+
readonly 'view.sources': "来源";
|
|
10
|
+
readonly 'view.scenes': "场景";
|
|
11
|
+
readonly 'view.market': "市场";
|
|
12
|
+
readonly 'view.flat': "平铺";
|
|
13
|
+
readonly 'view.grouped': "分组";
|
|
14
|
+
readonly 'panel.title': "技能中枢";
|
|
15
|
+
readonly 'panel.count': "共 {count} 个技能";
|
|
16
|
+
readonly 'panel.disabledCount': "已禁用 {count}";
|
|
17
|
+
readonly 'panel.new': "新建技能";
|
|
18
|
+
readonly 'panel.search': "搜索技能…";
|
|
19
|
+
readonly 'legend.model': "模型可调 — Agent 可自动调用";
|
|
20
|
+
readonly 'legend.user': "用户可调 — 仅显式点名时触发";
|
|
21
|
+
readonly 'legend.hint': "圆点标在技能名旁;无圆点表示该技能不可被调用。";
|
|
22
|
+
readonly 'panel.enabled': "已启用";
|
|
23
|
+
readonly 'panel.disabled': "已禁用";
|
|
24
|
+
readonly 'panel.diagnostics': "发现诊断";
|
|
25
|
+
readonly 'panel.empty': "没有匹配的技能。";
|
|
26
|
+
readonly 'panel.emptyAll': "本地还没有技能。点击「新建技能」创建第一个。";
|
|
27
|
+
readonly 'panel.loading': "读取中…";
|
|
28
|
+
readonly 'panel.incomplete': "(目录可能不完整)";
|
|
29
|
+
readonly 'market.addHint': "像 codex 一样添加仓库源:输入 owner/repo 或 GitHub 链接,扫描其中的技能并一键导入;导入后自动跟踪上游更新。";
|
|
30
|
+
readonly 'market.addPlaceholder': "owner/repo 或 https://github.com/…";
|
|
31
|
+
readonly 'market.addSource': "添加源";
|
|
32
|
+
readonly 'market.noSources': "还没有市场源。从下方内置市场添加,或输入一个 GitHub 仓库。";
|
|
33
|
+
readonly 'market.catalogTitle': "内置市场";
|
|
34
|
+
readonly 'market.catalogHint': "精选技能仓库,添加后即可扫描安装,并持续检查更新。";
|
|
35
|
+
readonly 'market.catalog.anthropics': "Anthropic 官方技能合集(Claude Skills)";
|
|
36
|
+
readonly 'market.catalog.superpowers': "Superpowers 社区技能合集";
|
|
37
|
+
readonly 'market.catalog.mattpocock': "Matt Pocock 技能集";
|
|
38
|
+
readonly 'market.catalog.openDesign': "设计技能合集(design-templates)";
|
|
39
|
+
readonly 'market.added': "已添加";
|
|
40
|
+
readonly 'market.add': "添加";
|
|
41
|
+
readonly 'market.mySources': "我的市场源";
|
|
42
|
+
readonly 'market.installed': "已装 {count}";
|
|
43
|
+
readonly 'market.updatable': "可更新 {count}";
|
|
44
|
+
readonly 'market.deletedUpstream': "上游已删 {count}";
|
|
45
|
+
readonly 'market.checkAll': "检查全部";
|
|
46
|
+
readonly 'market.updateAll': "全部更新";
|
|
47
|
+
readonly 'market.updateAllConfirmTitle': "批量更新全部技能?";
|
|
48
|
+
readonly 'market.updateAllConfirmText': "将把以下来源的可更新技能更新到上游最新版本(覆盖本地修改):";
|
|
49
|
+
readonly 'market.updateAllItem': "{repo}({count} 个技能)";
|
|
50
|
+
readonly 'market.updateAllDone': "已更新 {count} 个来源";
|
|
51
|
+
readonly 'market.deleteSource': "移除源";
|
|
52
|
+
readonly 'market.scan': "扫描";
|
|
53
|
+
readonly 'market.scanning': "扫描中…";
|
|
54
|
+
readonly 'market.check': "检查";
|
|
55
|
+
readonly 'market.sync': "同步";
|
|
56
|
+
readonly 'market.syncing': "同步中…";
|
|
57
|
+
readonly 'market.updated': "有更新";
|
|
58
|
+
readonly 'market.newRelease': "新版本 v{version}";
|
|
59
|
+
readonly 'market.branchTitle': "选择分支";
|
|
60
|
+
readonly 'market.branchHint': "该仓库没有正式发布,选择要跟踪的分支(默认为 main):";
|
|
61
|
+
readonly 'market.branchConfirm': "确定";
|
|
62
|
+
readonly 'market.syncTitle': "同步本地技能";
|
|
63
|
+
readonly 'market.syncText': "市场源已对齐到 {ref},要同步更新以下本地技能吗?";
|
|
64
|
+
readonly 'market.syncNone': "该来源还没有导入本地技能。";
|
|
65
|
+
readonly 'market.syncCancel': "跳过";
|
|
66
|
+
readonly 'market.removeHint': "移除源不影响已安装的技能。";
|
|
67
|
+
readonly 'repo.ready': "发现 {count} 个可导入技能";
|
|
68
|
+
readonly 'repo.empty': "没有找到可导入技能。";
|
|
69
|
+
readonly 'repo.selectAll': "全选";
|
|
70
|
+
readonly 'repo.clearAll': "清空";
|
|
71
|
+
readonly 'repo.import': "导入所选 ({count})";
|
|
72
|
+
readonly 'repo.importing': "导入中…";
|
|
73
|
+
readonly 'repo.existing': "已存在";
|
|
74
|
+
readonly 'repo.files': "{count} 个文件 · {size}";
|
|
75
|
+
readonly 'repo.imported': "导入成功 {count} 个";
|
|
76
|
+
readonly 'repo.skippedExisting': "跳过已存在 {count} 个";
|
|
77
|
+
readonly 'repo.failed': "失败 {count} 个";
|
|
78
|
+
readonly 'repo.root.skills': "技能 skills";
|
|
79
|
+
readonly 'repo.root.designTemplates': "模板 design-templates";
|
|
80
|
+
readonly 'update.check': "检查更新";
|
|
81
|
+
readonly 'update.checking': "检查中…";
|
|
82
|
+
readonly 'update.upToDate': "已是最新版本 v{version}";
|
|
83
|
+
readonly 'update.available': "发现新版本 v{version}(当前 v{current})";
|
|
84
|
+
readonly 'update.newVersion': "新版本 v{version}";
|
|
85
|
+
readonly 'update.viewRelease': "查看发布";
|
|
86
|
+
readonly 'update.error': "检查更新失败:{error}";
|
|
87
|
+
readonly 'update.unavailable': "暂无可用的发布版本";
|
|
88
|
+
readonly 'group.project-dsh': "项目 .dsh/skills";
|
|
89
|
+
readonly 'group.project-agents': "项目 .agents/skills";
|
|
90
|
+
readonly 'group.custom': "自定义目录";
|
|
91
|
+
readonly 'group.runtime': "运行时";
|
|
92
|
+
readonly 'group.user-dsh': "用户 ~/.dsh/skills";
|
|
93
|
+
readonly 'group.user-agents': "用户 ~/.agents/skills";
|
|
94
|
+
readonly 'group.bundled': "内置";
|
|
95
|
+
readonly 'group.other': "其他来源";
|
|
96
|
+
readonly 'groups.new': "新建场景";
|
|
97
|
+
readonly 'groups.namePlaceholder': "场景名";
|
|
98
|
+
readonly 'groups.edit': "编辑";
|
|
99
|
+
readonly 'groups.rename': "保存名称";
|
|
100
|
+
readonly 'groups.delete': "删除场景";
|
|
101
|
+
readonly 'groups.saveMembers': "保存成员";
|
|
102
|
+
readonly 'groups.membersHint': "勾选技能加入此场景(含已禁用)。";
|
|
103
|
+
readonly 'groups.empty': "还没有场景。先新建一个,再把技能归类。";
|
|
104
|
+
readonly 'groups.noCollections': "暂无来源组。从市场导入技能后自动按来源聚合。";
|
|
105
|
+
readonly 'groups.personal': "个人";
|
|
106
|
+
readonly 'groups.noWritable': "该组没有可写技能(只读技能无法由中枢开关)";
|
|
107
|
+
readonly 'groups.closeAll': "全部关闭";
|
|
108
|
+
readonly 'groups.keepOn': "保留开启";
|
|
109
|
+
readonly 'groups.conflictTitle': "关闭此组?";
|
|
110
|
+
readonly 'groups.conflictText': "以下技能也在其他组中开启,关闭它们会影响那些组:";
|
|
111
|
+
readonly 'filter.allSources': "全部来源";
|
|
112
|
+
readonly 'filter.private': "个人";
|
|
113
|
+
readonly 'sort.name': "按名称";
|
|
114
|
+
readonly 'sort.added': "按添加时间";
|
|
115
|
+
readonly 'sort.uses': "按调用次数";
|
|
116
|
+
readonly 'time.justNow': "刚刚";
|
|
117
|
+
readonly 'time.minutesAgo': "{value} 分钟前";
|
|
118
|
+
readonly 'time.hoursAgo': "{value} 小时前";
|
|
119
|
+
readonly 'time.daysAgo': "{value} 天前";
|
|
120
|
+
readonly 'time.weeksAgo': "{value} 周前";
|
|
121
|
+
readonly 'badge.source.project-dsh': "项目 .dsh";
|
|
122
|
+
readonly 'badge.source.project-agents': "项目 .agents";
|
|
123
|
+
readonly 'badge.source.custom': "自定义";
|
|
124
|
+
readonly 'badge.source.runtime': "运行时";
|
|
125
|
+
readonly 'badge.source.user-dsh': "用户 .dsh";
|
|
126
|
+
readonly 'badge.source.user-agents': "用户 .agents";
|
|
127
|
+
readonly 'badge.source.bundled': "内置";
|
|
128
|
+
readonly 'row.readonly': "只读";
|
|
129
|
+
readonly 'row.disable': "禁用";
|
|
130
|
+
readonly 'row.enable': "启用";
|
|
131
|
+
readonly 'row.delete': "移入回收站";
|
|
132
|
+
readonly 'delete.confirmTitle': "移入回收站?";
|
|
133
|
+
readonly 'delete.confirmText': "确定把「{name}」移入回收站吗?可随时恢复。";
|
|
134
|
+
readonly 'delete.confirm': "移入回收站";
|
|
135
|
+
readonly 'detail.back': "返回列表";
|
|
136
|
+
readonly 'detail.provider': "提供者";
|
|
137
|
+
readonly 'detail.addedAt': "添加时间";
|
|
138
|
+
readonly 'detail.updatedAt': "更新时间";
|
|
139
|
+
readonly 'detail.path': "路径";
|
|
140
|
+
readonly 'detail.whenToUse': "适用场景";
|
|
141
|
+
readonly 'detail.uses': "调用次数";
|
|
142
|
+
readonly 'detail.groups': "所属场景";
|
|
143
|
+
readonly 'detail.loading': "读取技能正文…";
|
|
144
|
+
readonly 'source.private': "个人技能(未绑定上游,不检查更新)";
|
|
145
|
+
readonly 'source.commit': "已同步版本";
|
|
146
|
+
readonly 'source.unverified': "尚未核对上游";
|
|
147
|
+
readonly 'source.check': "检查更新";
|
|
148
|
+
readonly 'source.checkHint': "点击检查上游更新";
|
|
149
|
+
readonly 'source.checking': "检查中…";
|
|
150
|
+
readonly 'source.upToDate': "已是最新";
|
|
151
|
+
readonly 'source.updated': "有更新 {count} 个";
|
|
152
|
+
readonly 'source.deleted': "上游已删除 {count} 个";
|
|
153
|
+
readonly 'source.error': "检查失败";
|
|
154
|
+
readonly 'source.throttled': "刚刚检查过";
|
|
155
|
+
readonly 'source.sync': "同步";
|
|
156
|
+
readonly 'source.syncing': "同步中…";
|
|
157
|
+
readonly 'source.syncConfirmTitle': "同步技能?";
|
|
158
|
+
readonly 'source.syncConfirmText': "将用上游最新版本覆盖本地对以下技能的所有修改:";
|
|
159
|
+
readonly 'source.followDelete': "跟进删除";
|
|
160
|
+
readonly 'source.deleteConfirmTitle': "跟进上游删除?";
|
|
161
|
+
readonly 'source.deleteConfirmText': "以下技能已从上游仓库移除,本地目录将移入回收站(可恢复):";
|
|
162
|
+
readonly 'source.trash': "回收站";
|
|
163
|
+
readonly 'source.restore': "恢复";
|
|
164
|
+
readonly 'source.clearTrash': "清空回收站";
|
|
165
|
+
readonly 'source.clearTrashConfirmTitle': "清空回收站?";
|
|
166
|
+
readonly 'source.clearTrashConfirmText': "回收站里的技能会被永久删除,无法恢复。此操作不可撤销。";
|
|
167
|
+
readonly 'source.clearTrashConfirm': "永久删除";
|
|
168
|
+
readonly 'form.capabilityHint': "能力怎么选:重复方法 → 技能;外部系统 → MCP;长期资料 → 知识库。";
|
|
169
|
+
readonly 'form.descPlaceholder': "一句话说明用途(含触发词),Agent 靠它自动激活技能";
|
|
170
|
+
readonly 'form.name': "技能名(kebab-case,如 code-review)";
|
|
171
|
+
readonly 'form.desc': "描述(一句话路由说明)";
|
|
172
|
+
readonly 'form.root': "目标目录";
|
|
173
|
+
readonly 'form.submit': "创建";
|
|
174
|
+
readonly 'form.cancel': "取消";
|
|
175
|
+
readonly 'form.busy': "创建中…";
|
|
176
|
+
readonly 'form.success': "已创建:";
|
|
177
|
+
readonly 'form.error': "创建失败:";
|
|
178
|
+
readonly 'err.dismiss': "知道了";
|
|
179
|
+
readonly 'settings.title': "Skill Hub";
|
|
180
|
+
readonly 'settings.description': "管理 dsh 本地技能目录:浏览、分组、来源同步与新建。";
|
|
181
|
+
readonly 'settings.enabled': "启用插件";
|
|
182
|
+
readonly 'settings.enabledHint': "关闭后技能中枢的路由、入口与公告全部下线。";
|
|
183
|
+
readonly 'settings.announceToAgent': "向 Agent 公告";
|
|
184
|
+
readonly 'settings.announceToAgentHint': "在系统提示中加入本插件说明,用户提到技能管理时 Agent 知道如何协作。";
|
|
185
|
+
readonly 'settings.dotModelColor': "模型可调圆点颜色";
|
|
186
|
+
readonly 'settings.dotModelColorHint': "技能名旁蓝色圆点的颜色(#rrggbb)。";
|
|
187
|
+
readonly 'settings.dotUserColor': "用户可调圆点颜色";
|
|
188
|
+
readonly 'settings.dotUserColorHint': "技能名旁绿色圆点的颜色(#rrggbb)。";
|
|
189
|
+
readonly 'settings.showUseCount': "显示调用次数";
|
|
190
|
+
readonly 'settings.showUseCountHint': "在技能名旁显示琥珀色调用次数。";
|
|
191
|
+
readonly 'settings.showUseTime': "显示最近调用时间";
|
|
192
|
+
readonly 'settings.showUseTimeHint': "在技能名行右侧显示相对时间(如「3 天前」)。";
|
|
193
|
+
readonly 'settings.showGroupSummary': "显示分组汇总";
|
|
194
|
+
readonly 'settings.showGroupSummaryHint': "在分组标题后汇总调用次数与最近调用时间。";
|
|
195
|
+
readonly 'settings.inherit': "继承";
|
|
196
|
+
readonly 'settings.on': "开";
|
|
197
|
+
readonly 'settings.off': "关";
|
|
198
|
+
readonly 'settings.overridden': "已覆盖";
|
|
199
|
+
readonly 'settings.reset': "恢复默认";
|
|
200
|
+
readonly 'settings.unsaved': "未保存";
|
|
201
|
+
readonly 'settings.save': "保存";
|
|
202
|
+
readonly 'settings.saving': "保存中…";
|
|
203
|
+
readonly 'settings.discard': "放弃修改";
|
|
204
|
+
readonly 'settings.saveFailed': "本部署没有接受这些值,已保留供你修改。";
|
|
205
|
+
readonly 'settings.readOnly': "本部署的设置为只读。";
|
|
206
|
+
readonly 'settings.notExposed': "本部署没有挂载该设置命名空间。";
|
|
207
|
+
readonly 'settings.collapse': "收起设置";
|
|
208
|
+
readonly 'settings.expand': "展开设置";
|
|
209
|
+
};
|
|
210
|
+
export declare const en: Record<HubKey, string>;
|
|
211
|
+
/** Union of every translatable key (the namespace's registered dictionary type). */
|
|
212
|
+
export type HubKey = keyof typeof zh;
|
|
213
|
+
/** Template values accepted by the interpolator. */
|
|
214
|
+
export type TranslateValues = Record<string, string | number>;
|
|
215
|
+
/** Interpolate a {name} template with the given values. */
|
|
216
|
+
export declare function t(dict: Record<string, string>, key: HubKey, values?: TranslateValues): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in market catalog: well-known skill repos shown on the market tab so
|
|
3
|
+
* users can browse and install without knowing repo URLs (cc-switch-style).
|
|
4
|
+
* Only the repo slug lives here; adding goes through the normal
|
|
5
|
+
* market-source route and records upstream tracking like any manual source.
|
|
6
|
+
*/
|
|
7
|
+
import type { HubKey } from './locales.ts';
|
|
8
|
+
export interface MarketCatalogEntry {
|
|
9
|
+
repo: string;
|
|
10
|
+
/** locales.ts key for the one-line description. */
|
|
11
|
+
descriptionKey: HubKey;
|
|
12
|
+
}
|
|
13
|
+
/** 默认市场目录:精选技能仓库(顺序即展示顺序)。 */
|
|
14
|
+
export declare const MARKET_CATALOG: readonly MarketCatalogEntry[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One disabled skill row (name + description + root badge + enable switch).
|
|
3
|
+
* Shared by the source-group lists, the scene-group lists, and the bottom
|
|
4
|
+
* disabled section.
|
|
5
|
+
*/
|
|
6
|
+
import type { JSX } from 'react';
|
|
7
|
+
import type { DisabledSkill } from '../../protocol.ts';
|
|
8
|
+
export declare function DisabledRow(props: {
|
|
9
|
+
record: DisabledSkill;
|
|
10
|
+
busy: boolean;
|
|
11
|
+
onEnable: () => void;
|
|
12
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group-header usage summary: total invocation count chip + the group's most
|
|
3
|
+
* recent last-used time. Honours the showGroupSummary config switch.
|
|
4
|
+
*/
|
|
5
|
+
import type { JSX } from 'react';
|
|
6
|
+
import type { SkillHubState } from './useSkillHub.ts';
|
|
7
|
+
export declare function GroupSummary(props: {
|
|
8
|
+
members: readonly string[];
|
|
9
|
+
hub: SkillHubState;
|
|
10
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Market tab: the built-in market catalog (one-click add), the user's market
|
|
3
|
+
* sources with aggregated per-repo state (installed / updatable / deleted
|
|
4
|
+
* upstream), check-all and update-all actions, and the repo scan result with
|
|
5
|
+
* the importable skill checklist.
|
|
6
|
+
*/
|
|
7
|
+
import type { JSX } from 'react';
|
|
8
|
+
import type { SkillHubState } from './useSkillHub.ts';
|
|
9
|
+
export declare function MarketView(props: {
|
|
10
|
+
hub: SkillHubState;
|
|
11
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scenes tab: user tag groups (one card per scene with the tri-state switch
|
|
3
|
+
* and edit entry) plus the new-scene form. Scenes are the user's own
|
|
4
|
+
* enable/disable units (e.g. a Godot scene vs a Java scene); upstream repos
|
|
5
|
+
* are managed in the sources tab.
|
|
6
|
+
*/
|
|
7
|
+
import type { JSX } from 'react';
|
|
8
|
+
import type { SkillHubState } from './useSkillHub.ts';
|
|
9
|
+
export declare function ScenesView(props: {
|
|
10
|
+
hub: SkillHubState;
|
|
11
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full-page skill detail view: metadata, upstream source card with
|
|
3
|
+
* check/sync/follow-delete actions, and the raw SKILL.md body. Pure
|
|
4
|
+
* presentation — every state value and action arrives as a prop, so the
|
|
5
|
+
* panel stays the single owner of state.
|
|
6
|
+
*/
|
|
7
|
+
import type { JSX } from 'react';
|
|
8
|
+
import type { GroupsResponse, HubConfig, SkillDetail, SourceCheckResult, SourcesResponse } from '../../protocol.ts';
|
|
9
|
+
export interface SkillDetailViewProps {
|
|
10
|
+
detail: SkillDetail;
|
|
11
|
+
hubConfig: HubConfig | null;
|
|
12
|
+
/** skillName → usage stat (count + last used). */
|
|
13
|
+
uses: ReadonlyMap<string, {
|
|
14
|
+
count: number;
|
|
15
|
+
lastUsed?: number;
|
|
16
|
+
}>;
|
|
17
|
+
groupsState: GroupsResponse | null;
|
|
18
|
+
sourcesState: SourcesResponse | null;
|
|
19
|
+
sourceCheck: Readonly<Record<string, SourceCheckResult>>;
|
|
20
|
+
checkingSource: string | null;
|
|
21
|
+
syncingSource: string | null;
|
|
22
|
+
loading: boolean;
|
|
23
|
+
onBack: () => void;
|
|
24
|
+
/** Check one source repo for upstream updates. */
|
|
25
|
+
onCheck: (repo: string) => void;
|
|
26
|
+
/** Request syncing the skill (overwrites local edits; opens a confirm). */
|
|
27
|
+
onSync: (repo: string, skills: string[]) => void;
|
|
28
|
+
/** Request following the upstream deletion (moves into the trash). */
|
|
29
|
+
onFollowDelete: (repo: string, skills: string[]) => void;
|
|
30
|
+
}
|
|
31
|
+
export declare function SkillDetailView(props: SkillDetailViewProps): JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skill hub panel: catalog grouped by tags + source collections, search
|
|
3
|
+
* and filter in one row, per-group tri-state switches with conflict dialogs,
|
|
4
|
+
* upstream source tracking (check / sync / follow upstream deletion into a
|
|
5
|
+
* restorable trash), codex-style market sources, disabled re-enable,
|
|
6
|
+
* detail inspection, and the new-skill scaffold form.
|
|
7
|
+
*
|
|
8
|
+
* Thin shell: state and flows live in useSkillHub, the tab contents live in
|
|
9
|
+
* SourcesView / ScenesView / MarketView, and the dialog family lives in
|
|
10
|
+
* dialogs.tsx. This component owns only the shared chrome (header, banners,
|
|
11
|
+
* filter bar, shared sections) and the view routing — and holds no hooks,
|
|
12
|
+
* so the detail / tag-editor early returns are safe.
|
|
13
|
+
*/
|
|
14
|
+
import type { SkillHubApi } from '../api.ts';
|
|
15
|
+
export interface SkillHubPanelProps {
|
|
16
|
+
api: SkillHubApi;
|
|
17
|
+
}
|
|
18
|
+
export declare function SkillHubPanel(props: SkillHubPanelProps): React.JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One enabled skill row: name + invocation dots + usage meta, delete and
|
|
3
|
+
* disable actions. Shared by the flat list and both grouped views.
|
|
4
|
+
*/
|
|
5
|
+
import type { JSX } from 'react';
|
|
6
|
+
import type { CatalogSkill } from '../../protocol.ts';
|
|
7
|
+
import type { SkillHubState } from './useSkillHub.ts';
|
|
8
|
+
export declare function SkillRow(props: {
|
|
9
|
+
skill: CatalogSkill;
|
|
10
|
+
hub: SkillHubState;
|
|
11
|
+
}): JSX.Element;
|