skills-console 0.4.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 (101) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +130 -0
  4. package/dist/adapters/filesystem/agent-registry.d.ts +5 -0
  5. package/dist/adapters/filesystem/agent-registry.js +236 -0
  6. package/dist/adapters/filesystem/agent-registry.js.map +1 -0
  7. package/dist/adapters/filesystem/frontmatter.d.ts +2 -0
  8. package/dist/adapters/filesystem/frontmatter.js +73 -0
  9. package/dist/adapters/filesystem/frontmatter.js.map +1 -0
  10. package/dist/adapters/filesystem/skill-scanner.d.ts +8 -0
  11. package/dist/adapters/filesystem/skill-scanner.js +157 -0
  12. package/dist/adapters/filesystem/skill-scanner.js.map +1 -0
  13. package/dist/adapters/filesystem/skills-lock.d.ts +2 -0
  14. package/dist/adapters/filesystem/skills-lock.js +44 -0
  15. package/dist/adapters/filesystem/skills-lock.js.map +1 -0
  16. package/dist/adapters/skills-cli/command-builder.d.ts +7 -0
  17. package/dist/adapters/skills-cli/command-builder.js +144 -0
  18. package/dist/adapters/skills-cli/command-builder.js.map +1 -0
  19. package/dist/adapters/skills-cli/executor.d.ts +20 -0
  20. package/dist/adapters/skills-cli/executor.js +51 -0
  21. package/dist/adapters/skills-cli/executor.js.map +1 -0
  22. package/dist/adapters/skills-cli/source-parser.d.ts +3 -0
  23. package/dist/adapters/skills-cli/source-parser.js +38 -0
  24. package/dist/adapters/skills-cli/source-parser.js.map +1 -0
  25. package/dist/adapters/skills-cli/types.d.ts +56 -0
  26. package/dist/adapters/skills-cli/types.js +2 -0
  27. package/dist/adapters/skills-cli/types.js.map +1 -0
  28. package/dist/application/backup-manager.d.ts +7 -0
  29. package/dist/application/backup-manager.js +164 -0
  30. package/dist/application/backup-manager.js.map +1 -0
  31. package/dist/application/build-inventory.d.ts +5 -0
  32. package/dist/application/build-inventory.js +103 -0
  33. package/dist/application/build-inventory.js.map +1 -0
  34. package/dist/application/doctor-fixes.d.ts +21 -0
  35. package/dist/application/doctor-fixes.js +103 -0
  36. package/dist/application/doctor-fixes.js.map +1 -0
  37. package/dist/application/history-store.d.ts +5 -0
  38. package/dist/application/history-store.js +42 -0
  39. package/dist/application/history-store.js.map +1 -0
  40. package/dist/application/profile-apply.d.ts +22 -0
  41. package/dist/application/profile-apply.js +69 -0
  42. package/dist/application/profile-apply.js.map +1 -0
  43. package/dist/application/profile-diff.d.ts +3 -0
  44. package/dist/application/profile-diff.js +105 -0
  45. package/dist/application/profile-diff.js.map +1 -0
  46. package/dist/application/profile-store.d.ts +9 -0
  47. package/dist/application/profile-store.js +109 -0
  48. package/dist/application/profile-store.js.map +1 -0
  49. package/dist/application/restore-operation.d.ts +8 -0
  50. package/dist/application/restore-operation.js +27 -0
  51. package/dist/application/restore-operation.js.map +1 -0
  52. package/dist/application/skill-operations.d.ts +32 -0
  53. package/dist/application/skill-operations.js +129 -0
  54. package/dist/application/skill-operations.js.map +1 -0
  55. package/dist/cli-commands.d.ts +8 -0
  56. package/dist/cli-commands.js +111 -0
  57. package/dist/cli-commands.js.map +1 -0
  58. package/dist/cli.d.ts +2 -0
  59. package/dist/cli.js +15 -0
  60. package/dist/cli.js.map +1 -0
  61. package/dist/domain/operations.d.ts +50 -0
  62. package/dist/domain/operations.js +25 -0
  63. package/dist/domain/operations.js.map +1 -0
  64. package/dist/domain/profile.d.ts +43 -0
  65. package/dist/domain/profile.js +2 -0
  66. package/dist/domain/profile.js.map +1 -0
  67. package/dist/domain/types.d.ts +98 -0
  68. package/dist/domain/types.js +2 -0
  69. package/dist/domain/types.js.map +1 -0
  70. package/dist/platform/data-paths.d.ts +3 -0
  71. package/dist/platform/data-paths.js +17 -0
  72. package/dist/platform/data-paths.js.map +1 -0
  73. package/dist/platform/environment.d.ts +6 -0
  74. package/dist/platform/environment.js +71 -0
  75. package/dist/platform/environment.js.map +1 -0
  76. package/dist/platform/redaction.d.ts +1 -0
  77. package/dist/platform/redaction.js +7 -0
  78. package/dist/platform/redaction.js.map +1 -0
  79. package/dist/ui/App.d.ts +2 -0
  80. package/dist/ui/App.js +330 -0
  81. package/dist/ui/App.js.map +1 -0
  82. package/dist/ui/DoctorFixWizard.d.ts +12 -0
  83. package/dist/ui/DoctorFixWizard.js +58 -0
  84. package/dist/ui/DoctorFixWizard.js.map +1 -0
  85. package/dist/ui/OperationWizard.d.ts +19 -0
  86. package/dist/ui/OperationWizard.js +301 -0
  87. package/dist/ui/OperationWizard.js.map +1 -0
  88. package/dist/ui/ProfileWizard.d.ts +15 -0
  89. package/dist/ui/ProfileWizard.js +68 -0
  90. package/dist/ui/ProfileWizard.js.map +1 -0
  91. package/dist/ui/RestoreWizard.d.ts +12 -0
  92. package/dist/ui/RestoreWizard.js +42 -0
  93. package/dist/ui/RestoreWizard.js.map +1 -0
  94. package/dist/version.d.ts +1 -0
  95. package/dist/version.js +2 -0
  96. package/dist/version.js.map +1 -0
  97. package/docs/ARCHITECTURE.md +145 -0
  98. package/docs/OPERATIONS.md +200 -0
  99. package/docs/PROFILES.md +83 -0
  100. package/examples/skills-profile.json +21 -0
  101. package/package.json +71 -0
@@ -0,0 +1,157 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { lstat, readFile, readdir, realpath, stat } from 'node:fs/promises';
3
+ import { basename, join } from 'node:path';
4
+ import { parseSkillManifest } from './frontmatter.js';
5
+ const SKIPPED_DIRECTORIES = new Set(['.git', 'node_modules', 'dist', 'vendor']);
6
+ function stableId(...parts) {
7
+ return createHash('sha1').update(parts.join('\0')).digest('hex').slice(0, 16);
8
+ }
9
+ function diagnostic(input) {
10
+ return {
11
+ id: stableId(input.code, input.path ?? '', input.skillName ?? '', input.message),
12
+ ...input,
13
+ };
14
+ }
15
+ async function exists(path) {
16
+ try {
17
+ await stat(path);
18
+ return true;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ export async function scanSkillRoot(root) {
25
+ const installations = [];
26
+ const diagnostics = [];
27
+ if (!root.exists || !root.readable) {
28
+ if (root.exists && !root.readable) {
29
+ diagnostics.push(diagnostic({
30
+ code: 'root-unreadable',
31
+ severity: 'error',
32
+ message: 'Skill root exists but is not readable.',
33
+ path: root.path,
34
+ skillName: undefined,
35
+ }));
36
+ }
37
+ return { installations, diagnostics };
38
+ }
39
+ async function visitDirectory(path, depth, ancestors) {
40
+ let resolvedPath;
41
+ try {
42
+ resolvedPath = await realpath(path);
43
+ }
44
+ catch {
45
+ diagnostics.push(diagnostic({
46
+ code: 'broken-symlink',
47
+ severity: 'error',
48
+ message: 'Unable to resolve directory or symbolic link.',
49
+ path,
50
+ skillName: undefined,
51
+ }));
52
+ return;
53
+ }
54
+ if (ancestors.has(resolvedPath)) {
55
+ diagnostics.push(diagnostic({
56
+ code: 'symlink-cycle',
57
+ severity: 'error',
58
+ message: 'Symbolic-link cycle detected while scanning.',
59
+ path,
60
+ skillName: undefined,
61
+ }));
62
+ return;
63
+ }
64
+ const manifestPath = join(path, 'SKILL.md');
65
+ if (await exists(manifestPath)) {
66
+ try {
67
+ const [content, directoryStat, manifestStat] = await Promise.all([
68
+ readFile(manifestPath, 'utf8'),
69
+ lstat(path),
70
+ stat(manifestPath),
71
+ ]);
72
+ const manifest = parseSkillManifest(content);
73
+ const directoryName = basename(path);
74
+ const skillName = manifest.name ?? directoryName;
75
+ const itemDiagnostics = manifest.errors.map((message) => diagnostic({
76
+ code: 'invalid-manifest',
77
+ severity: 'error',
78
+ message,
79
+ path: manifestPath,
80
+ skillName,
81
+ }));
82
+ if (manifest.name && manifest.name !== directoryName) {
83
+ itemDiagnostics.push(diagnostic({
84
+ code: 'name-directory-mismatch',
85
+ severity: 'warning',
86
+ message: `Manifest name "${manifest.name}" does not match directory "${directoryName}".`,
87
+ path: manifestPath,
88
+ skillName,
89
+ }));
90
+ }
91
+ installations.push({
92
+ id: stableId(root.id, path),
93
+ skillName,
94
+ directoryName,
95
+ description: manifest.description ?? 'No description available.',
96
+ manifestPath,
97
+ path,
98
+ realPath: resolvedPath,
99
+ scope: root.scope,
100
+ rootKind: root.kind,
101
+ agentIds: root.agentIds,
102
+ linkKind: directoryStat.isSymbolicLink() ? 'symlink' : 'directory',
103
+ mutable: root.mutable,
104
+ source: manifest.source,
105
+ modifiedAtMs: manifestStat.mtimeMs,
106
+ isEffective: true,
107
+ diagnostics: itemDiagnostics,
108
+ });
109
+ diagnostics.push(...itemDiagnostics);
110
+ }
111
+ catch (error) {
112
+ diagnostics.push(diagnostic({
113
+ code: 'manifest-unreadable',
114
+ severity: 'error',
115
+ message: error instanceof Error ? error.message : 'Unable to read SKILL.md.',
116
+ path: manifestPath,
117
+ skillName: basename(path),
118
+ }));
119
+ }
120
+ return;
121
+ }
122
+ if (depth >= root.maxDepth) {
123
+ return;
124
+ }
125
+ let entries;
126
+ try {
127
+ entries = await readdir(path, { withFileTypes: true });
128
+ }
129
+ catch (error) {
130
+ diagnostics.push(diagnostic({
131
+ code: 'directory-unreadable',
132
+ severity: 'error',
133
+ message: error instanceof Error ? error.message : 'Unable to read directory.',
134
+ path,
135
+ skillName: undefined,
136
+ }));
137
+ return;
138
+ }
139
+ const nextAncestors = new Set(ancestors).add(resolvedPath);
140
+ await Promise.all(entries
141
+ .filter((entry) => !SKIPPED_DIRECTORIES.has(entry.name) &&
142
+ !root.excludedDirectoryNames.includes(entry.name))
143
+ .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())
144
+ .map((entry) => visitDirectory(join(path, entry.name), depth + 1, nextAncestors)));
145
+ }
146
+ await visitDirectory(root.path, 0, new Set());
147
+ installations.sort((a, b) => a.skillName.localeCompare(b.skillName));
148
+ return { installations, diagnostics };
149
+ }
150
+ export async function scanSkillRoots(roots) {
151
+ const results = await Promise.all(roots.map(scanSkillRoot));
152
+ return {
153
+ installations: results.flatMap((result) => result.installations),
154
+ diagnostics: results.flatMap((result) => result.diagnostics),
155
+ };
156
+ }
157
+ //# sourceMappingURL=skill-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-scanner.js","sourceRoot":"","sources":["../../../src/adapters/filesystem/skill-scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { EnvironmentInfo, SkillInstallation } from '../../domain/types.js';
2
+ export declare function enrichInstallationsFromSkillsLocks(installations: SkillInstallation[], environment: EnvironmentInfo): Promise<void>;
@@ -0,0 +1,44 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ function optionalString(value) {
4
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
5
+ }
6
+ async function readLock(path) {
7
+ try {
8
+ const parsed = JSON.parse(await readFile(path, 'utf8'));
9
+ if (!parsed.skills || typeof parsed.skills !== 'object') {
10
+ return new Map();
11
+ }
12
+ return new Map(Object.entries(parsed.skills));
13
+ }
14
+ catch {
15
+ return new Map();
16
+ }
17
+ }
18
+ export async function enrichInstallationsFromSkillsLocks(installations, environment) {
19
+ const lockPaths = {
20
+ project: join(environment.projectRoot, 'skills-lock.json'),
21
+ user: process.env.XDG_STATE_HOME
22
+ ? join(process.env.XDG_STATE_HOME, 'skills', '.skill-lock.json')
23
+ : join(environment.homeDir, '.agents', '.skill-lock.json'),
24
+ };
25
+ const [projectLock, userLock] = await Promise.all([
26
+ readLock(lockPaths.project),
27
+ readLock(lockPaths.user),
28
+ ]);
29
+ const locks = {
30
+ project: projectLock,
31
+ user: userLock,
32
+ };
33
+ for (const installation of installations) {
34
+ if (!installation.mutable || installation.source) {
35
+ continue;
36
+ }
37
+ const entry = locks[installation.scope].get(installation.skillName);
38
+ if (!entry) {
39
+ continue;
40
+ }
41
+ installation.source = optionalString(entry.sourceUrl) ?? optionalString(entry.source);
42
+ }
43
+ }
44
+ //# sourceMappingURL=skills-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-lock.js","sourceRoot":"","sources":["../../../src/adapters/filesystem/skills-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAkB/B,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAY;IAClC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAe,CAAC;QACtE,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxD,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,aAAkC,EAClC,WAA4B;IAE5B,MAAM,SAAS,GAA0B;QACvC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,kBAAkB,CAAC;QAC1D,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;YAC9B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,kBAAkB,CAAC;YAChE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,kBAAkB,CAAC;KAC7D,CAAC;IACF,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChD,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;KACzB,CAAC,CAAC;IACH,MAAM,KAAK,GAA0C;QACnD,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,QAAQ;KACf,CAAC;IAEF,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;YACjD,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAS;QACX,CAAC;QACD,YAAY,CAAC,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxF,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { InstallRequest, RemoveRequest, SkillsCliRuntime, SkillsCommandPlan, UpdateRequest } from './types.js';
2
+ export declare const TESTED_SKILLS_VERSION = "1.5.17";
3
+ export declare function bundledSkillsRuntime(): SkillsCliRuntime;
4
+ export declare function buildSourcePreviewPlan(source: string, cwd: string, runtime?: SkillsCliRuntime): SkillsCommandPlan;
5
+ export declare function buildInstallPlan(request: InstallRequest, runtime?: SkillsCliRuntime): SkillsCommandPlan;
6
+ export declare function buildUpdatePlan(request: UpdateRequest, runtime?: SkillsCliRuntime): SkillsCommandPlan;
7
+ export declare function buildRemovePlan(request: RemoveRequest, runtime?: SkillsCliRuntime): SkillsCommandPlan;
@@ -0,0 +1,144 @@
1
+ import { createRequire } from 'node:module';
2
+ import { dirname, join } from 'node:path';
3
+ import { redactSensitiveText } from '../../platform/redaction.js';
4
+ export const TESTED_SKILLS_VERSION = '1.5.17';
5
+ const SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
6
+ const AGENT_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
7
+ function quoteForDisplay(value) {
8
+ const redacted = redactSensitiveText(value);
9
+ return /^[a-zA-Z0-9_./:@%+=,-]+$/.test(redacted)
10
+ ? redacted
11
+ : `'${redacted.replaceAll("'", `'\\''`)}'`;
12
+ }
13
+ function commandDisplay(prefix, args) {
14
+ return [...prefix, ...args].map(quoteForDisplay).join(' ');
15
+ }
16
+ function assertSource(source) {
17
+ if (!source.trim()) {
18
+ throw new Error('A skill source is required.');
19
+ }
20
+ if (/[\u0000-\u001f\u007f]/.test(source)) {
21
+ throw new Error('Skill source contains control characters.');
22
+ }
23
+ }
24
+ function assertSkillNames(skillNames) {
25
+ if (skillNames.length === 0) {
26
+ throw new Error('Select at least one skill.');
27
+ }
28
+ for (const skillName of skillNames) {
29
+ if (!SKILL_NAME_PATTERN.test(skillName)) {
30
+ throw new Error(`Invalid skill name: ${skillName}`);
31
+ }
32
+ }
33
+ }
34
+ function assertAgentIds(agentIds) {
35
+ if (agentIds.length === 0) {
36
+ throw new Error('Select at least one target agent.');
37
+ }
38
+ for (const agentId of agentIds) {
39
+ if (!AGENT_ID_PATTERN.test(agentId)) {
40
+ throw new Error(`Invalid agent id: ${agentId}`);
41
+ }
42
+ }
43
+ }
44
+ function createPlan(runtime, input) {
45
+ return {
46
+ kind: input.kind,
47
+ executable: runtime.executable,
48
+ args: [...runtime.prefixArgs, ...input.commandArgs],
49
+ cwd: input.cwd,
50
+ environment: runtime.environment,
51
+ displayCommand: commandDisplay(runtime.displayPrefix, input.commandArgs),
52
+ mutatesFilesystem: input.mutatesFilesystem,
53
+ skillNames: input.skillNames ?? [],
54
+ agentIds: input.agentIds ?? [],
55
+ scope: input.scope,
56
+ source: input.source,
57
+ };
58
+ }
59
+ export function bundledSkillsRuntime() {
60
+ const require = createRequire(import.meta.url);
61
+ const packageJsonPath = require.resolve('skills/package.json');
62
+ const cliPath = join(dirname(packageJsonPath), 'bin', 'cli.mjs');
63
+ return {
64
+ executable: process.execPath,
65
+ prefixArgs: [cliPath],
66
+ displayPrefix: ['npx', `skills@${TESTED_SKILLS_VERSION}`],
67
+ environment: {
68
+ DISABLE_TELEMETRY: '1',
69
+ DO_NOT_TRACK: '1',
70
+ },
71
+ version: TESTED_SKILLS_VERSION,
72
+ };
73
+ }
74
+ export function buildSourcePreviewPlan(source, cwd, runtime = bundledSkillsRuntime()) {
75
+ assertSource(source);
76
+ const normalizedSource = source.trim();
77
+ return createPlan(runtime, {
78
+ kind: 'preview',
79
+ commandArgs: ['add', normalizedSource, '--list'],
80
+ cwd,
81
+ mutatesFilesystem: false,
82
+ source: normalizedSource,
83
+ });
84
+ }
85
+ export function buildInstallPlan(request, runtime = bundledSkillsRuntime()) {
86
+ assertSource(request.source);
87
+ assertSkillNames(request.skillNames);
88
+ assertAgentIds(request.agentIds);
89
+ const commandArgs = ['add', request.source.trim()];
90
+ for (const skillName of request.skillNames) {
91
+ commandArgs.push('--skill', skillName);
92
+ }
93
+ commandArgs.push('--agent', ...request.agentIds);
94
+ if (request.scope === 'user') {
95
+ commandArgs.push('--global');
96
+ }
97
+ if (request.mode === 'copy') {
98
+ commandArgs.push('--copy');
99
+ }
100
+ commandArgs.push('--yes');
101
+ return createPlan(runtime, {
102
+ kind: 'install',
103
+ commandArgs,
104
+ cwd: request.cwd,
105
+ mutatesFilesystem: true,
106
+ skillNames: request.skillNames,
107
+ agentIds: request.agentIds,
108
+ scope: request.scope,
109
+ source: request.source.trim(),
110
+ });
111
+ }
112
+ export function buildUpdatePlan(request, runtime = bundledSkillsRuntime()) {
113
+ assertSkillNames(request.skillNames);
114
+ const commandArgs = ['update', ...request.skillNames];
115
+ commandArgs.push(request.scope === 'user' ? '--global' : '--project');
116
+ commandArgs.push('--yes');
117
+ return createPlan(runtime, {
118
+ kind: 'update',
119
+ commandArgs,
120
+ cwd: request.cwd,
121
+ mutatesFilesystem: true,
122
+ skillNames: request.skillNames,
123
+ scope: request.scope,
124
+ });
125
+ }
126
+ export function buildRemovePlan(request, runtime = bundledSkillsRuntime()) {
127
+ assertSkillNames(request.skillNames);
128
+ assertAgentIds(request.agentIds);
129
+ const commandArgs = ['remove', ...request.skillNames, '--agent', ...request.agentIds];
130
+ if (request.scope === 'user') {
131
+ commandArgs.push('--global');
132
+ }
133
+ commandArgs.push('--yes');
134
+ return createPlan(runtime, {
135
+ kind: 'remove',
136
+ commandArgs,
137
+ cwd: request.cwd,
138
+ mutatesFilesystem: true,
139
+ skillNames: request.skillNames,
140
+ agentIds: request.agentIds,
141
+ scope: request.scope,
142
+ });
143
+ }
144
+ //# sourceMappingURL=command-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-builder.js","sourceRoot":"","sources":["../../../src/adapters/skills-cli/command-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Readable } from 'node:stream';
2
+ import type { CommandExecution, CommandOutput, SkillsCommandPlan } from './types.js';
3
+ export interface SpawnedProcess {
4
+ stdout: Readable;
5
+ stderr: Readable;
6
+ kill(signal?: NodeJS.Signals): boolean;
7
+ once(event: 'error', listener: (error: Error) => void): this;
8
+ once(event: 'close', listener: (exitCode: number | null, signal: NodeJS.Signals | null) => void): this;
9
+ }
10
+ export type SpawnProcess = (executable: string, args: string[], options: {
11
+ cwd: string;
12
+ env: NodeJS.ProcessEnv;
13
+ shell: false;
14
+ stdio: ['ignore', 'pipe', 'pipe'];
15
+ }) => SpawnedProcess;
16
+ export declare function executeSkillsCommand(plan: SkillsCommandPlan, options?: {
17
+ signal?: AbortSignal;
18
+ onOutput?: (output: CommandOutput) => void;
19
+ spawnProcess?: SpawnProcess;
20
+ }): Promise<CommandExecution>;
@@ -0,0 +1,51 @@
1
+ import { spawn } from 'node:child_process';
2
+ const defaultSpawn = (executable, args, options) => spawn(executable, args, options);
3
+ export function executeSkillsCommand(plan, options = {}) {
4
+ return new Promise((resolve, reject) => {
5
+ const startedAt = Date.now();
6
+ const child = (options.spawnProcess ?? defaultSpawn)(plan.executable, plan.args, {
7
+ cwd: plan.cwd,
8
+ env: { ...process.env, ...plan.environment },
9
+ shell: false,
10
+ stdio: ['ignore', 'pipe', 'pipe'],
11
+ });
12
+ let stdout = '';
13
+ let stderr = '';
14
+ child.stdout.setEncoding('utf8');
15
+ child.stderr.setEncoding('utf8');
16
+ child.stdout.on('data', (chunk) => {
17
+ stdout += chunk;
18
+ options.onOutput?.({ stream: 'stdout', text: chunk });
19
+ });
20
+ child.stderr.on('data', (chunk) => {
21
+ stderr += chunk;
22
+ options.onOutput?.({ stream: 'stderr', text: chunk });
23
+ });
24
+ const abort = () => {
25
+ child.kill('SIGINT');
26
+ };
27
+ if (options.signal) {
28
+ if (options.signal.aborted) {
29
+ abort();
30
+ }
31
+ else {
32
+ options.signal.addEventListener('abort', abort, { once: true });
33
+ }
34
+ }
35
+ child.once('error', (error) => {
36
+ options.signal?.removeEventListener('abort', abort);
37
+ reject(error);
38
+ });
39
+ child.once('close', (exitCode, signal) => {
40
+ options.signal?.removeEventListener('abort', abort);
41
+ resolve({
42
+ exitCode: exitCode ?? 1,
43
+ signal,
44
+ stdout,
45
+ stderr,
46
+ durationMs: Date.now() - startedAt,
47
+ });
48
+ });
49
+ });
50
+ }
51
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/adapters/skills-cli/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AA+BzC,MAAM,YAAY,GAAiB,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAC/D,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAmB,CAAC;AAErD,MAAM,UAAU,oBAAoB,CAClC,IAAuB,EACvB,OAAO,GAIH,EAAE;IAEN,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE;YAC/E,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,GAAG,EAAE,EAAC,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,EAAC;YAC1C,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,MAAM,IAAI,KAAK,CAAC;YAChB,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,MAAM,IAAI,KAAK,CAAC;YAChB,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,GAAG,EAAE;YACjB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC3B,KAAK,EAAE,CAAC;YACV,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5B,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACpD,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;YACvC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,CAAC;gBACN,QAAQ,EAAE,QAAQ,IAAI,CAAC;gBACvB,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SourceSkill } from './types.js';
2
+ export declare function stripAnsi(value: string): string;
3
+ export declare function parseSourceSkills(output: string): SourceSkill[];
@@ -0,0 +1,38 @@
1
+ const ANSI_PATTERN = /[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*)?\u0007)|(?:(?:\d{1,4}(?:[;:]\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))/g;
2
+ const SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
3
+ export function stripAnsi(value) {
4
+ return value.replace(ANSI_PATTERN, '');
5
+ }
6
+ export function parseSourceSkills(output) {
7
+ const lines = stripAnsi(output).split(/\r?\n/);
8
+ const start = lines.findIndex((line) => line.includes('Available Skills'));
9
+ if (start < 0) {
10
+ return [];
11
+ }
12
+ const skills = [];
13
+ for (let index = start + 1; index < lines.length; index += 1) {
14
+ const line = lines[index] ?? '';
15
+ if (line.includes('Use --skill')) {
16
+ break;
17
+ }
18
+ const match = /^│\s{4}([a-z0-9][a-z0-9-]{0,63})\s*$/.exec(line);
19
+ if (!match?.[1] || !SKILL_NAME_PATTERN.test(match[1])) {
20
+ continue;
21
+ }
22
+ let description = '';
23
+ for (let descriptionIndex = index + 1; descriptionIndex < lines.length; descriptionIndex += 1) {
24
+ const candidate = lines[descriptionIndex] ?? '';
25
+ if (/^│\s{4}[a-z0-9]/.test(candidate) || candidate.includes('Use --skill')) {
26
+ break;
27
+ }
28
+ const descriptionMatch = /^│\s{6}(.+?)\s*$/.exec(candidate);
29
+ if (descriptionMatch?.[1]) {
30
+ description = descriptionMatch[1];
31
+ break;
32
+ }
33
+ }
34
+ skills.push({ name: match[1], description });
35
+ }
36
+ return [...new Map(skills.map((skill) => [skill.name, skill])).values()];
37
+ }
38
+ //# sourceMappingURL=source-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-parser.js","sourceRoot":"","sources":["../../../src/adapters/skills-cli/source-parser.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,gJAAgJ,CAAC;AACtK,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;AAExD,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC3E,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,IAAI,KAAK,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,MAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,SAAS;QACX,CAAC;QAED,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,KAAK,IAAI,gBAAgB,GAAG,KAAK,GAAG,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC,MAAM,EAAE,gBAAgB,IAAI,CAAC,EAAE,CAAC;YAC9F,MAAM,SAAS,GAAG,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;YAChD,IAAI,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC3E,MAAM;YACR,CAAC;YACD,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5D,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1B,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;gBAClC,MAAM;YACR,CAAC;QACH,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAC,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { Scope } from '../../domain/types.js';
2
+ export type OperationKind = 'preview' | 'install' | 'update' | 'remove' | 'repair';
3
+ export interface SkillsCliRuntime {
4
+ executable: string;
5
+ prefixArgs: string[];
6
+ displayPrefix: string[];
7
+ environment: Record<string, string>;
8
+ version: string;
9
+ }
10
+ export interface SkillsCommandPlan {
11
+ kind: OperationKind;
12
+ executable: string;
13
+ args: string[];
14
+ cwd: string;
15
+ environment: Record<string, string>;
16
+ displayCommand: string;
17
+ mutatesFilesystem: boolean;
18
+ skillNames: string[];
19
+ agentIds: string[];
20
+ scope: Scope | undefined;
21
+ source: string | undefined;
22
+ }
23
+ export interface InstallRequest {
24
+ source: string;
25
+ skillNames: string[];
26
+ agentIds: string[];
27
+ scope: Scope;
28
+ mode: 'symlink' | 'copy';
29
+ cwd: string;
30
+ }
31
+ export interface UpdateRequest {
32
+ skillNames: string[];
33
+ scope: Scope;
34
+ cwd: string;
35
+ }
36
+ export interface RemoveRequest {
37
+ skillNames: string[];
38
+ agentIds: string[];
39
+ scope: Scope;
40
+ cwd: string;
41
+ }
42
+ export interface CommandOutput {
43
+ stream: 'stdout' | 'stderr';
44
+ text: string;
45
+ }
46
+ export interface CommandExecution {
47
+ exitCode: number;
48
+ signal: NodeJS.Signals | null;
49
+ stdout: string;
50
+ stderr: string;
51
+ durationMs: number;
52
+ }
53
+ export interface SourceSkill {
54
+ name: string;
55
+ description: string;
56
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/skills-cli/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { SkillsCommandPlan } from '../adapters/skills-cli/types.js';
2
+ import type { OperationSnapshot, RestoreResult } from '../domain/operations.js';
3
+ import type { Inventory } from '../domain/types.js';
4
+ export declare function createOperationSnapshot(plan: SkillsCommandPlan, inventory: Inventory, dataRoot: string): Promise<OperationSnapshot>;
5
+ export declare function finalizeOperationSnapshot(snapshot: OperationSnapshot, plan: SkillsCommandPlan, before: Inventory, after: Inventory): Promise<OperationSnapshot>;
6
+ export declare function loadOperationSnapshot(snapshotId: string, dataRoot: string): Promise<OperationSnapshot>;
7
+ export declare function restoreOperationSnapshot(snapshot: OperationSnapshot): Promise<RestoreResult>;