dsh-agent-skills 0.1.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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/cordis.patch.yml +13 -0
  4. package/lib/client.js +15235 -0
  5. package/lib/client.js.map +7 -0
  6. package/lib/discovery.d.ts +9 -0
  7. package/lib/discovery.js +48 -0
  8. package/lib/discovery.js.map +1 -0
  9. package/lib/index.d.ts +35 -0
  10. package/lib/index.js +26 -0
  11. package/lib/index.js.map +1 -0
  12. package/lib/preset.d.ts +9 -0
  13. package/lib/preset.js +7 -0
  14. package/lib/preset.js.map +1 -0
  15. package/lib/provider.d.ts +53 -0
  16. package/lib/provider.js +295 -0
  17. package/lib/provider.js.map +1 -0
  18. package/lib/registry.d.ts +85 -0
  19. package/lib/registry.js +122 -0
  20. package/lib/registry.js.map +1 -0
  21. package/lib/runtime.d.ts +27 -0
  22. package/lib/runtime.js +162 -0
  23. package/lib/runtime.js.map +1 -0
  24. package/lib/scan.d.ts +29 -0
  25. package/lib/scan.js +156 -0
  26. package/lib/scan.js.map +1 -0
  27. package/lib/schemas.d.ts +112 -0
  28. package/lib/schemas.js +82 -0
  29. package/lib/schemas.js.map +1 -0
  30. package/lib/store.d.ts +26 -0
  31. package/lib/store.js +88 -0
  32. package/lib/store.js.map +1 -0
  33. package/lib/typert.d.ts +195 -0
  34. package/lib/typert.js +153 -0
  35. package/lib/typert.js.map +1 -0
  36. package/lib/types/client/AgentSkillsSection.d.ts +9 -0
  37. package/lib/types/client/index.d.ts +14 -0
  38. package/lib/types/client/locales.d.ts +86 -0
  39. package/lib/types/client/styles.d.ts +4 -0
  40. package/lib/types/client/typert-remote.d.ts +152 -0
  41. package/lib/types/client/types.d.ts +13 -0
  42. package/lib/types/schemas.d.ts +112 -0
  43. package/lib/views.d.ts +27 -0
  44. package/lib/views.js +218 -0
  45. package/lib/views.js.map +1 -0
  46. package/package.json +130 -0
  47. package/scripts/install-preset.mjs +49 -0
  48. package/scripts/uninstall-preset.mjs +22 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * `agent-skills` namespace dictionaries for the Agent Skills settings page.
3
+ * Simplified Chinese is the source of truth; English mirrors it.
4
+ *
5
+ * @module dsh-agent-skills/client/locales
6
+ */
7
+ /** Simplified Chinese dictionary. */
8
+ export declare const zh: {
9
+ nav: string;
10
+ title: string;
11
+ subtitle: string;
12
+ searchPlaceholder: string;
13
+ sources: string;
14
+ validCount: string;
15
+ missingCount: string;
16
+ addDir: string;
17
+ rescan: string;
18
+ collapseAll: string;
19
+ expandAll: string;
20
+ dirTagUser: string;
21
+ dirTagBuiltin: string;
22
+ validSkills: string;
23
+ viewSkills: string;
24
+ hideSkills: string;
25
+ noSkillsInDir: string;
26
+ dirMissing: string;
27
+ enabledHeader: string;
28
+ noSkills: string;
29
+ noMatch: string;
30
+ tagCustom: string;
31
+ tagGlobal: string;
32
+ tagBuiltin: string;
33
+ expand: string;
34
+ collapse: string;
35
+ loading: string;
36
+ errorLoad: string;
37
+ errorSave: string;
38
+ addDirPlaceholder: string;
39
+ addConfirm: string;
40
+ addCancel: string;
41
+ removeDir: string;
42
+ autoBadge: string;
43
+ enabled: string;
44
+ disabled: string;
45
+ emptyDirs: string;
46
+ };
47
+ /** English dictionary. */
48
+ export declare const en: {
49
+ nav: string;
50
+ title: string;
51
+ subtitle: string;
52
+ searchPlaceholder: string;
53
+ sources: string;
54
+ validCount: string;
55
+ missingCount: string;
56
+ addDir: string;
57
+ rescan: string;
58
+ collapseAll: string;
59
+ expandAll: string;
60
+ dirTagUser: string;
61
+ dirTagBuiltin: string;
62
+ validSkills: string;
63
+ viewSkills: string;
64
+ hideSkills: string;
65
+ noSkillsInDir: string;
66
+ dirMissing: string;
67
+ enabledHeader: string;
68
+ noSkills: string;
69
+ noMatch: string;
70
+ tagCustom: string;
71
+ tagGlobal: string;
72
+ tagBuiltin: string;
73
+ expand: string;
74
+ collapse: string;
75
+ loading: string;
76
+ errorLoad: string;
77
+ errorSave: string;
78
+ addDirPlaceholder: string;
79
+ addConfirm: string;
80
+ addCancel: string;
81
+ removeDir: string;
82
+ autoBadge: string;
83
+ enabled: string;
84
+ disabled: string;
85
+ emptyDirs: string;
86
+ };
@@ -0,0 +1,4 @@
1
+ /** Inject the stylesheet once per browser document; returns the element. */
2
+ export declare function injectStyles(): HTMLStyleElement;
3
+ /** Remove the stylesheet (client fiber dispose). */
4
+ export declare function removeStyles(): void;
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Client remote face: installs the `agentSkills` namespace on the client
3
+ * through `ctx.remote.$mount(...)`, mirroring the host TYPERT manifest
4
+ * one-to-one so both directions validate with the same strict codecs.
5
+ *
6
+ * @module dsh-agent-skills/client/typert-remote
7
+ */
8
+ import { z } from "zod";
9
+ /** Remote contribution consumed by `ctx.remote.$mount(...)`. */
10
+ export declare const TYPERT_REMOTE: {
11
+ readonly package: "dsh-agent-skills";
12
+ readonly descriptors: readonly [{
13
+ readonly id: "dsh-agent-skills#agentSkills/list";
14
+ readonly service: "agentSkills";
15
+ readonly namespace: "agentSkills";
16
+ readonly method: "list";
17
+ readonly invocation: {
18
+ readonly kind: "direct";
19
+ };
20
+ readonly parameters: readonly [];
21
+ readonly result: {
22
+ mode: "strict";
23
+ typeSymbol: string;
24
+ schema: z.ZodType;
25
+ };
26
+ }, {
27
+ readonly id: "dsh-agent-skills#agentSkills/toggleSkill";
28
+ readonly service: "agentSkills";
29
+ readonly namespace: "agentSkills";
30
+ readonly method: "toggleSkill";
31
+ readonly invocation: {
32
+ readonly kind: "direct";
33
+ };
34
+ readonly parameters: readonly [{
35
+ readonly name: "input";
36
+ readonly wire: "input";
37
+ readonly source: "json";
38
+ readonly codec: {
39
+ mode: "strict";
40
+ typeSymbol: string;
41
+ schema: z.ZodType;
42
+ };
43
+ }];
44
+ readonly result: {
45
+ mode: "strict";
46
+ typeSymbol: string;
47
+ schema: z.ZodType;
48
+ };
49
+ }, {
50
+ readonly id: "dsh-agent-skills#agentSkills/toggleDir";
51
+ readonly service: "agentSkills";
52
+ readonly namespace: "agentSkills";
53
+ readonly method: "toggleDir";
54
+ readonly invocation: {
55
+ readonly kind: "direct";
56
+ };
57
+ readonly parameters: readonly [{
58
+ readonly name: "input";
59
+ readonly wire: "input";
60
+ readonly source: "json";
61
+ readonly codec: {
62
+ mode: "strict";
63
+ typeSymbol: string;
64
+ schema: z.ZodType;
65
+ };
66
+ }];
67
+ readonly result: {
68
+ mode: "strict";
69
+ typeSymbol: string;
70
+ schema: z.ZodType;
71
+ };
72
+ }, {
73
+ readonly id: "dsh-agent-skills#agentSkills/addDir";
74
+ readonly service: "agentSkills";
75
+ readonly namespace: "agentSkills";
76
+ readonly method: "addDir";
77
+ readonly invocation: {
78
+ readonly kind: "direct";
79
+ };
80
+ readonly parameters: readonly [{
81
+ readonly name: "input";
82
+ readonly wire: "input";
83
+ readonly source: "json";
84
+ readonly codec: {
85
+ mode: "strict";
86
+ typeSymbol: string;
87
+ schema: z.ZodType;
88
+ };
89
+ }];
90
+ readonly result: {
91
+ mode: "strict";
92
+ typeSymbol: string;
93
+ schema: z.ZodType;
94
+ };
95
+ }, {
96
+ readonly id: "dsh-agent-skills#agentSkills/removeDir";
97
+ readonly service: "agentSkills";
98
+ readonly namespace: "agentSkills";
99
+ readonly method: "removeDir";
100
+ readonly invocation: {
101
+ readonly kind: "direct";
102
+ };
103
+ readonly parameters: readonly [{
104
+ readonly name: "input";
105
+ readonly wire: "input";
106
+ readonly source: "json";
107
+ readonly codec: {
108
+ mode: "strict";
109
+ typeSymbol: string;
110
+ schema: z.ZodType;
111
+ };
112
+ }];
113
+ readonly result: {
114
+ mode: "strict";
115
+ typeSymbol: string;
116
+ schema: z.ZodType;
117
+ };
118
+ }, {
119
+ readonly id: "dsh-agent-skills#agentSkills/rescan";
120
+ readonly service: "agentSkills";
121
+ readonly namespace: "agentSkills";
122
+ readonly method: "rescan";
123
+ readonly invocation: {
124
+ readonly kind: "direct";
125
+ };
126
+ readonly parameters: readonly [];
127
+ readonly result: {
128
+ mode: "strict";
129
+ typeSymbol: string;
130
+ schema: z.ZodType;
131
+ };
132
+ }];
133
+ };
134
+ /** Result envelope of every remote method. */
135
+ export type RemoteResult<T> = {
136
+ ok: true;
137
+ value: T;
138
+ } | {
139
+ ok: false;
140
+ error: {
141
+ message: string;
142
+ };
143
+ };
144
+ /** The client-side `agentSkills` remote API. */
145
+ export interface AgentSkillsApi {
146
+ list(): Promise<RemoteResult<import("../schemas.js").AgentSkillsView>>;
147
+ toggleSkill(input: import("../schemas.js").ToggleSkillInput): Promise<RemoteResult<import("../schemas.js").AgentSkillsView>>;
148
+ toggleDir(input: import("../schemas.js").ToggleDirInput): Promise<RemoteResult<import("../schemas.js").AgentSkillsView>>;
149
+ addDir(input: import("../schemas.js").AddDirInput): Promise<RemoteResult<import("../schemas.js").AgentSkillsView>>;
150
+ removeDir(input: import("../schemas.js").RemoveDirInput): Promise<RemoteResult<import("../schemas.js").AgentSkillsView>>;
151
+ rescan(): Promise<RemoteResult<import("../schemas.js").AgentSkillsView>>;
152
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Type-only module augmentations owned by this plugin: the `agent-skills`
3
+ * locale namespace registered into the slots locale map. Imported from the
4
+ * client entry so the section registration type-checks with its own keys.
5
+ *
6
+ * @module dsh-agent-skills/client/types
7
+ */
8
+ declare module "@deepseek-ai/dsh-client-ui-slots" {
9
+ interface LocaleNamespaceMap {
10
+ "agent-skills": "nav" | "title" | "subtitle" | "searchPlaceholder" | "sources" | "validCount" | "missingCount" | "addDir" | "rescan" | "collapseAll" | "expandAll" | "dirTagUser" | "dirTagBuiltin" | "validSkills" | "viewSkills" | "hideSkills" | "noSkillsInDir" | "dirMissing" | "enabledHeader" | "noSkills" | "noMatch" | "tagCustom" | "tagGlobal" | "tagBuiltin" | "expand" | "collapse" | "loading" | "errorLoad" | "errorSave" | "addDirPlaceholder" | "addConfirm" | "addCancel" | "removeDir" | "autoBadge" | "enabled" | "disabled" | "emptyDirs";
11
+ }
12
+ }
13
+ export {};
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Wire schemas shared by the host typert face and the client remote.
3
+ * Zod v4 instances — the typert gateway re-checks JSON-safety after schema
4
+ * parsing, so optional fields must never be `undefined` on the wire.
5
+ *
6
+ * @module dsh-agent-skills/schemas
7
+ */
8
+ import { z } from "zod";
9
+ /** A scan directory shown on the Agent Skills page. */
10
+ export declare const dirViewSchema: z.ZodObject<{
11
+ path: z.ZodString;
12
+ kind: z.ZodEnum<{
13
+ custom: "custom";
14
+ builtin: "builtin";
15
+ }>;
16
+ exists: z.ZodBoolean;
17
+ enabled: z.ZodBoolean;
18
+ skillCount: z.ZodNumber;
19
+ tag: z.ZodEnum<{
20
+ builtin: "builtin";
21
+ user: "user";
22
+ }>;
23
+ auto: z.ZodOptional<z.ZodBoolean>;
24
+ skills: z.ZodArray<z.ZodObject<{
25
+ name: z.ZodString;
26
+ description: z.ZodString;
27
+ }, z.core.$strip>>;
28
+ }, z.core.$strip>;
29
+ export type DirView = z.infer<typeof dirViewSchema>;
30
+ /** One skill shown on the Agent Skills page. */
31
+ export declare const skillViewSchema: z.ZodObject<{
32
+ name: z.ZodString;
33
+ description: z.ZodString;
34
+ whenToUse: z.ZodOptional<z.ZodString>;
35
+ source: z.ZodString;
36
+ kind: z.ZodEnum<{
37
+ custom: "custom";
38
+ builtin: "builtin";
39
+ global: "global";
40
+ }>;
41
+ directory: z.ZodOptional<z.ZodString>;
42
+ enabled: z.ZodBoolean;
43
+ toggleable: z.ZodBoolean;
44
+ }, z.core.$strip>;
45
+ export type SkillView = z.infer<typeof skillViewSchema>;
46
+ /** The full page view. */
47
+ export declare const agentSkillsViewSchema: z.ZodObject<{
48
+ dirs: z.ZodArray<z.ZodObject<{
49
+ path: z.ZodString;
50
+ kind: z.ZodEnum<{
51
+ custom: "custom";
52
+ builtin: "builtin";
53
+ }>;
54
+ exists: z.ZodBoolean;
55
+ enabled: z.ZodBoolean;
56
+ skillCount: z.ZodNumber;
57
+ tag: z.ZodEnum<{
58
+ builtin: "builtin";
59
+ user: "user";
60
+ }>;
61
+ auto: z.ZodOptional<z.ZodBoolean>;
62
+ skills: z.ZodArray<z.ZodObject<{
63
+ name: z.ZodString;
64
+ description: z.ZodString;
65
+ }, z.core.$strip>>;
66
+ }, z.core.$strip>>;
67
+ skills: z.ZodArray<z.ZodObject<{
68
+ name: z.ZodString;
69
+ description: z.ZodString;
70
+ whenToUse: z.ZodOptional<z.ZodString>;
71
+ source: z.ZodString;
72
+ kind: z.ZodEnum<{
73
+ custom: "custom";
74
+ builtin: "builtin";
75
+ global: "global";
76
+ }>;
77
+ directory: z.ZodOptional<z.ZodString>;
78
+ enabled: z.ZodBoolean;
79
+ toggleable: z.ZodBoolean;
80
+ }, z.core.$strip>>;
81
+ counts: z.ZodObject<{
82
+ total: z.ZodNumber;
83
+ custom: z.ZodNumber;
84
+ global: z.ZodNumber;
85
+ builtin: z.ZodNumber;
86
+ }, z.core.$strip>;
87
+ validDirs: z.ZodNumber;
88
+ missingDirs: z.ZodNumber;
89
+ }, z.core.$strip>;
90
+ export type AgentSkillsView = z.infer<typeof agentSkillsViewSchema>;
91
+ /** Input for toggling one skill. */
92
+ export declare const toggleSkillInputSchema: z.ZodObject<{
93
+ name: z.ZodString;
94
+ enabled: z.ZodBoolean;
95
+ }, z.core.$strip>;
96
+ export type ToggleSkillInput = z.infer<typeof toggleSkillInputSchema>;
97
+ /** Input for toggling one scan directory. */
98
+ export declare const toggleDirInputSchema: z.ZodObject<{
99
+ path: z.ZodString;
100
+ enabled: z.ZodBoolean;
101
+ }, z.core.$strip>;
102
+ export type ToggleDirInput = z.infer<typeof toggleDirInputSchema>;
103
+ /** Input for adding a custom scan directory. */
104
+ export declare const addDirInputSchema: z.ZodObject<{
105
+ path: z.ZodString;
106
+ }, z.core.$strip>;
107
+ export type AddDirInput = z.infer<typeof addDirInputSchema>;
108
+ /** Input for removing a custom scan directory. */
109
+ export declare const removeDirInputSchema: z.ZodObject<{
110
+ path: z.ZodString;
111
+ }, z.core.$strip>;
112
+ export type RemoveDirInput = z.infer<typeof removeDirInputSchema>;
package/lib/views.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Host-side page views: directories (sources) and the full skill catalog,
3
+ * built from the live registry plus the durable store. Used by the typert
4
+ * service that backs the Agent Skills settings page.
5
+ *
6
+ * @module dsh-agent-skills/views
7
+ */
8
+ import type { Context } from "@deepseek-ai/cordis";
9
+ import type { AgentSkillsState } from "./store.js";
10
+ import type { AgentSkillsView } from "./schemas.js";
11
+ import { type RootPolicy } from "./provider.js";
12
+ /** Resolve every scan root (custom + auto + builtin) with its current policy. */
13
+ export declare function resolveRoots(ctx: Context, state: AgentSkillsState, dshHome?: string): Promise<{
14
+ roots: RootPolicy[];
15
+ builtin: RootPolicy[];
16
+ }>;
17
+ /** Map one candidate to the skill category shown in the UI. */
18
+ export declare function skillKindOf(source: string): "custom" | "global" | "builtin";
19
+ /**
20
+ * Build the full page view. Mutations are not performed here; the typert
21
+ * service calls this after each write so the returned payload is always the
22
+ * fresh post-write state.
23
+ */
24
+ export declare function buildView(ctx: Context, state: AgentSkillsState): Promise<AgentSkillsView>;
25
+ /** Auto-discover other agents' skill dirs into the state (once per process). */
26
+ export declare function ensureDiscovered(state: AgentSkillsState): Promise<boolean>;
27
+ export declare function canonicalizeDir(path: string): string;
package/lib/views.js ADDED
@@ -0,0 +1,218 @@
1
+ import { builtinRoots, findPresetProvider, PROVIDER_NAME, rootFor } from "./provider.js";
2
+ import { collectAllLayers, dedupeWinners, registryOf } from "./registry.js";
3
+ import { scanRoot } from "./scan.js";
4
+ import { resolveDshHome } from "@deepseek-ai/dsh-home-paths";
5
+ import { resolve } from "node:path";
6
+ import { access } from "node:fs/promises";
7
+ import { discoverAgentSkillDirs } from "./discovery.js";
8
+ /** Resolve every scan root (custom + auto + builtin) with its current policy. */
9
+ export async function resolveRoots(ctx, state, dshHome = resolveDshHome()) {
10
+ const custom = state.dirs.map((dir) => ({
11
+ path: resolve(dir.path),
12
+ disabled: dir.enabled === false
13
+ }));
14
+ const builtin = await builtinRoots(dshHome);
15
+ return { roots: [...custom, ...builtin], builtin };
16
+ }
17
+ async function exists(path) {
18
+ try {
19
+ await access(path);
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ function kindOf(root, builtinPaths) {
27
+ return builtinPaths.has(root.path) ? "builtin" : "custom";
28
+ }
29
+ /** Map one candidate to the skill category shown in the UI. */
30
+ export function skillKindOf(source) {
31
+ if (source === "custom")
32
+ return "custom";
33
+ if (source === "bundled")
34
+ return "builtin";
35
+ return "global";
36
+ }
37
+ /**
38
+ * The catalog the agent sees: prefer the preset-scope provider's emission
39
+ * (it already merges every layer and applies toggles); fall back to a plain
40
+ * global merge when the preset row is not mounted.
41
+ */
42
+ async function catalogCandidates(ctx) {
43
+ const preset = findPresetProvider(ctx.skills);
44
+ if (preset !== undefined) {
45
+ try {
46
+ const observation = await preset.provider.list({});
47
+ const candidates = Array.isArray(observation)
48
+ ? observation
49
+ : observation.candidates;
50
+ return [...candidates].map((candidate) => ({
51
+ candidate,
52
+ provider: undefined,
53
+ providerOrder: 0,
54
+ localOrder: 0
55
+ }));
56
+ }
57
+ catch {
58
+ /* fall through to the raw merge */
59
+ }
60
+ }
61
+ // Fallback (no preset row mounted, e.g. before the next restart): merge
62
+ // every layer INCLUDING this plugin's own provider, so custom directories
63
+ // and toggles still surface in the page view.
64
+ const registry = registryOf(ctx.skills);
65
+ const collected = await collectAllLayers(registry, {}, ctx.logger);
66
+ return dedupeWinners(collected.entries);
67
+ }
68
+ /**
69
+ * Build the full page view. Mutations are not performed here; the typert
70
+ * service calls this after each write so the returned payload is always the
71
+ * fresh post-write state.
72
+ */
73
+ export async function buildView(ctx, state) {
74
+ const dshHome = resolveDshHome();
75
+ const { roots, builtin } = await resolveRoots(ctx, state, dshHome);
76
+ const builtinPaths = new Set(builtin.map((root) => root.path));
77
+ const disabledDirs = new Set(state.disabledDirs);
78
+ const disabledSkills = new Set(state.disabledSkills);
79
+ // Per-directory raw discovery: builtin roots come from the filesystem
80
+ // provider's own candidates; custom roots are scanned directly (this
81
+ // plugin's own provider is excluded so its re-emissions are not double
82
+ // counted).
83
+ const registry = registryOf(ctx.skills);
84
+ const collected = await collectAllLayers(registry, {}, ctx.logger, PROVIDER_NAME);
85
+ const rawByDir = new Map();
86
+ for (const entry of collected.entries) {
87
+ const dir = rootFor(entry.candidate.resourceBase?.kind === "directory" ? entry.candidate.resourceBase.path : entry.candidate.path, roots);
88
+ if (dir === undefined)
89
+ continue;
90
+ rawByDir.set(dir.path, (rawByDir.get(dir.path) ?? 0) + 1);
91
+ }
92
+ for (const dir of state.dirs) {
93
+ const { scanRoot } = await import("./scan.js");
94
+ const scanned = await scanRoot(dir.path, ctx.logger);
95
+ rawByDir.set(scanned.path, scanned.skills.length);
96
+ }
97
+ // The host can render before a preset-scoped filesystem provider exists.
98
+ // Fill only missing roots so a live provider remains the source of truth.
99
+ for (const root of builtin) {
100
+ if (rawByDir.has(root.path))
101
+ continue;
102
+ const scanned = await scanRoot(root.path, ctx.logger);
103
+ rawByDir.set(scanned.path, scanned.skills.length);
104
+ }
105
+ // Undeduplicated per-directory skill lists (the "查看技能" expansion).
106
+ const skillsByDir = new Map();
107
+ for (const entry of collected.entries) {
108
+ const dir = rootFor(entry.candidate.resourceBase?.kind === "directory" ? entry.candidate.resourceBase.path : entry.candidate.path, roots);
109
+ if (dir === undefined)
110
+ continue;
111
+ const list = skillsByDir.get(dir.path) ?? [];
112
+ list.push({ name: entry.candidate.name, description: entry.candidate.description });
113
+ skillsByDir.set(dir.path, list);
114
+ }
115
+ for (const dir of state.dirs) {
116
+ const { scanRoot } = await import("./scan.js");
117
+ const scanned = await scanRoot(dir.path, ctx.logger);
118
+ const list = skillsByDir.get(scanned.path) ?? [];
119
+ for (const skill of scanned.skills) {
120
+ list.push({ name: skill.name, description: skill.description });
121
+ }
122
+ skillsByDir.set(scanned.path, list);
123
+ }
124
+ for (const root of builtin) {
125
+ if (skillsByDir.has(root.path))
126
+ continue;
127
+ const scanned = await scanRoot(root.path, ctx.logger);
128
+ skillsByDir.set(scanned.path, scanned.skills.map((skill) => ({
129
+ name: skill.name,
130
+ description: skill.description
131
+ })));
132
+ }
133
+ for (const list of skillsByDir.values()) {
134
+ list.sort((a, b) => a.name.localeCompare(b.name));
135
+ }
136
+ const autoDirs = new Set(state.dirs.filter((dir) => dir.auto === true).map((dir) => resolve(dir.path)));
137
+ const dirs = [];
138
+ let validDirs = 0;
139
+ let missingDirs = 0;
140
+ for (const root of roots) {
141
+ const existing = await exists(root.path);
142
+ let skillCount = rawByDir.get(root.path) ?? 0;
143
+ if (!existing)
144
+ skillCount = 0;
145
+ if (existing)
146
+ validDirs += 1;
147
+ else
148
+ missingDirs += 1;
149
+ const kind = kindOf(root, builtinPaths);
150
+ const enabled = root.disabled !== true && !disabledDirs.has(root.path);
151
+ dirs.push({
152
+ path: root.path,
153
+ kind,
154
+ exists: existing,
155
+ enabled,
156
+ skillCount,
157
+ tag: kind === "builtin" ? "builtin" : "user",
158
+ ...(kind === "custom" && autoDirs.has(root.path) ? { auto: true } : {}),
159
+ skills: (skillsByDir.get(root.path) ?? []).map((skill) => ({ ...skill }))
160
+ });
161
+ }
162
+ dirs.sort((a, b) => (a.kind === b.kind ? a.path.localeCompare(b.path) : a.kind === "custom" ? -1 : 1));
163
+ // The agent-visible catalog with effective toggles.
164
+ const catalog = await catalogCandidates(ctx);
165
+ const skills = [];
166
+ const counts = { total: 0, custom: 0, global: 0, builtin: 0 };
167
+ for (const entry of catalog) {
168
+ const candidate = entry.candidate;
169
+ const dir = rootFor(candidate.resourceBase?.kind === "directory" ? candidate.resourceBase.path : candidate.path, roots);
170
+ const enabled = !disabledSkills.has(candidate.name) &&
171
+ (dir === undefined || (!dir.disabled && !disabledDirs.has(dir.path)));
172
+ const kind = skillKindOf(candidate.source);
173
+ if (enabled) {
174
+ counts.total += 1;
175
+ if (kind === "custom")
176
+ counts.custom += 1;
177
+ else if (kind === "builtin")
178
+ counts.builtin += 1;
179
+ else
180
+ counts.global += 1;
181
+ }
182
+ skills.push({
183
+ name: candidate.name,
184
+ description: candidate.description,
185
+ ...(candidate.whenToUse !== undefined ? { whenToUse: candidate.whenToUse } : {}),
186
+ source: candidate.source,
187
+ kind,
188
+ ...(dir !== undefined ? { directory: dir.path } : {}),
189
+ enabled,
190
+ toggleable: true
191
+ });
192
+ }
193
+ skills.sort((a, b) => a.name.localeCompare(b.name));
194
+ return {
195
+ dirs,
196
+ skills,
197
+ counts,
198
+ validDirs,
199
+ missingDirs
200
+ };
201
+ }
202
+ /** Auto-discover other agents' skill dirs into the state (once per process). */
203
+ export async function ensureDiscovered(state) {
204
+ let changed = false;
205
+ const existing = new Set(state.dirs.map((dir) => resolve(dir.path)));
206
+ const discovered = await discoverAgentSkillDirs();
207
+ for (const path of discovered) {
208
+ if (existing.has(path))
209
+ continue;
210
+ state.dirs.push({ path, enabled: true, auto: true });
211
+ changed = true;
212
+ }
213
+ return changed;
214
+ }
215
+ export function canonicalizeDir(path) {
216
+ return resolve(path);
217
+ }
218
+ //# sourceMappingURL=views.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.js","sourceRoot":"","sources":["../src/views.ts"],"names":[],"mappings":"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"}