@senior-skills/core 1.0.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 (177) hide show
  1. package/dist/application/agent-selection.d.ts +42 -0
  2. package/dist/application/agent-selection.d.ts.map +1 -0
  3. package/dist/application/agent-selection.js +143 -0
  4. package/dist/application/agent-selection.js.map +1 -0
  5. package/dist/application/apply-skill-updates.d.ts +10 -0
  6. package/dist/application/apply-skill-updates.d.ts.map +1 -0
  7. package/dist/application/apply-skill-updates.js +75 -0
  8. package/dist/application/apply-skill-updates.js.map +1 -0
  9. package/dist/application/check-updates.d.ts +40 -0
  10. package/dist/application/check-updates.d.ts.map +1 -0
  11. package/dist/application/check-updates.js +130 -0
  12. package/dist/application/check-updates.js.map +1 -0
  13. package/dist/application/context.d.ts +28 -0
  14. package/dist/application/context.d.ts.map +1 -0
  15. package/dist/application/context.js +2 -0
  16. package/dist/application/context.js.map +1 -0
  17. package/dist/application/create-skill.d.ts +33 -0
  18. package/dist/application/create-skill.d.ts.map +1 -0
  19. package/dist/application/create-skill.js +58 -0
  20. package/dist/application/create-skill.js.map +1 -0
  21. package/dist/application/diagnose.d.ts +44 -0
  22. package/dist/application/diagnose.d.ts.map +1 -0
  23. package/dist/application/diagnose.js +228 -0
  24. package/dist/application/diagnose.js.map +1 -0
  25. package/dist/application/install-skills.d.ts +59 -0
  26. package/dist/application/install-skills.d.ts.map +1 -0
  27. package/dist/application/install-skills.js +191 -0
  28. package/dist/application/install-skills.js.map +1 -0
  29. package/dist/application/list-installed.d.ts +39 -0
  30. package/dist/application/list-installed.d.ts.map +1 -0
  31. package/dist/application/list-installed.js +68 -0
  32. package/dist/application/list-installed.js.map +1 -0
  33. package/dist/application/package-loader.d.ts +42 -0
  34. package/dist/application/package-loader.d.ts.map +1 -0
  35. package/dist/application/package-loader.js +320 -0
  36. package/dist/application/package-loader.js.map +1 -0
  37. package/dist/application/publish-skill.d.ts +41 -0
  38. package/dist/application/publish-skill.d.ts.map +1 -0
  39. package/dist/application/publish-skill.js +112 -0
  40. package/dist/application/publish-skill.js.map +1 -0
  41. package/dist/application/remove-skills.d.ts +34 -0
  42. package/dist/application/remove-skills.d.ts.map +1 -0
  43. package/dist/application/remove-skills.js +95 -0
  44. package/dist/application/remove-skills.js.map +1 -0
  45. package/dist/application/resolution-source.d.ts +25 -0
  46. package/dist/application/resolution-source.d.ts.map +1 -0
  47. package/dist/application/resolution-source.js +60 -0
  48. package/dist/application/resolution-source.js.map +1 -0
  49. package/dist/application/resolve-suggestions.d.ts +17 -0
  50. package/dist/application/resolve-suggestions.d.ts.map +1 -0
  51. package/dist/application/resolve-suggestions.js +77 -0
  52. package/dist/application/resolve-suggestions.js.map +1 -0
  53. package/dist/application/search-skills.d.ts +36 -0
  54. package/dist/application/search-skills.d.ts.map +1 -0
  55. package/dist/application/search-skills.js +78 -0
  56. package/dist/application/search-skills.js.map +1 -0
  57. package/dist/application/update-skills.d.ts +55 -0
  58. package/dist/application/update-skills.d.ts.map +1 -0
  59. package/dist/application/update-skills.js +115 -0
  60. package/dist/application/update-skills.js.map +1 -0
  61. package/dist/application/validate-package.d.ts +27 -0
  62. package/dist/application/validate-package.d.ts.map +1 -0
  63. package/dist/application/validate-package.js +165 -0
  64. package/dist/application/validate-package.js.map +1 -0
  65. package/dist/application/workspace.d.ts +22 -0
  66. package/dist/application/workspace.d.ts.map +1 -0
  67. package/dist/application/workspace.js +66 -0
  68. package/dist/application/workspace.js.map +1 -0
  69. package/dist/domain/agent.d.ts +89 -0
  70. package/dist/domain/agent.d.ts.map +1 -0
  71. package/dist/domain/agent.js +20 -0
  72. package/dist/domain/agent.js.map +1 -0
  73. package/dist/domain/errors.d.ts +91 -0
  74. package/dist/domain/errors.d.ts.map +1 -0
  75. package/dist/domain/errors.js +121 -0
  76. package/dist/domain/errors.js.map +1 -0
  77. package/dist/domain/integrity.d.ts +19 -0
  78. package/dist/domain/integrity.d.ts.map +1 -0
  79. package/dist/domain/integrity.js +0 -0
  80. package/dist/domain/integrity.js.map +1 -0
  81. package/dist/domain/js-literal.d.ts +22 -0
  82. package/dist/domain/js-literal.d.ts.map +1 -0
  83. package/dist/domain/js-literal.js +221 -0
  84. package/dist/domain/js-literal.js.map +1 -0
  85. package/dist/domain/lockfile.d.ts +36 -0
  86. package/dist/domain/lockfile.d.ts.map +1 -0
  87. package/dist/domain/lockfile.js +148 -0
  88. package/dist/domain/lockfile.js.map +1 -0
  89. package/dist/domain/manifest.d.ts +96 -0
  90. package/dist/domain/manifest.d.ts.map +1 -0
  91. package/dist/domain/manifest.js +448 -0
  92. package/dist/domain/manifest.js.map +1 -0
  93. package/dist/domain/path-safety.d.ts +19 -0
  94. package/dist/domain/path-safety.d.ts.map +1 -0
  95. package/dist/domain/path-safety.js +125 -0
  96. package/dist/domain/path-safety.js.map +1 -0
  97. package/dist/domain/posix-path.d.ts +28 -0
  98. package/dist/domain/posix-path.d.ts.map +1 -0
  99. package/dist/domain/posix-path.js +84 -0
  100. package/dist/domain/posix-path.js.map +1 -0
  101. package/dist/domain/receipt.d.ts +41 -0
  102. package/dist/domain/receipt.d.ts.map +1 -0
  103. package/dist/domain/receipt.js +93 -0
  104. package/dist/domain/receipt.js.map +1 -0
  105. package/dist/domain/registry-index.d.ts +41 -0
  106. package/dist/domain/registry-index.d.ts.map +1 -0
  107. package/dist/domain/registry-index.js +150 -0
  108. package/dist/domain/registry-index.js.map +1 -0
  109. package/dist/domain/resolver.d.ts +54 -0
  110. package/dist/domain/resolver.d.ts.map +1 -0
  111. package/dist/domain/resolver.js +238 -0
  112. package/dist/domain/resolver.js.map +1 -0
  113. package/dist/domain/skill-document.d.ts +16 -0
  114. package/dist/domain/skill-document.d.ts.map +1 -0
  115. package/dist/domain/skill-document.js +60 -0
  116. package/dist/domain/skill-document.js.map +1 -0
  117. package/dist/domain/skill-package.d.ts +43 -0
  118. package/dist/domain/skill-package.d.ts.map +1 -0
  119. package/dist/domain/skill-package.js +63 -0
  120. package/dist/domain/skill-package.js.map +1 -0
  121. package/dist/domain/skill-ref.d.ts +30 -0
  122. package/dist/domain/skill-ref.d.ts.map +1 -0
  123. package/dist/domain/skill-ref.js +119 -0
  124. package/dist/domain/skill-ref.js.map +1 -0
  125. package/dist/domain/validation.d.ts +30 -0
  126. package/dist/domain/validation.d.ts.map +1 -0
  127. package/dist/domain/validation.js +32 -0
  128. package/dist/domain/validation.js.map +1 -0
  129. package/dist/domain/version.d.ts +23 -0
  130. package/dist/domain/version.d.ts.map +1 -0
  131. package/dist/domain/version.js +81 -0
  132. package/dist/domain/version.js.map +1 -0
  133. package/dist/domain/workflow-document.d.ts +23 -0
  134. package/dist/domain/workflow-document.d.ts.map +1 -0
  135. package/dist/domain/workflow-document.js +56 -0
  136. package/dist/domain/workflow-document.js.map +1 -0
  137. package/dist/index.d.ts +47 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +45 -0
  140. package/dist/index.js.map +1 -0
  141. package/dist/ports/agent-adapter.d.ts +65 -0
  142. package/dist/ports/agent-adapter.d.ts.map +1 -0
  143. package/dist/ports/agent-adapter.js +28 -0
  144. package/dist/ports/agent-adapter.js.map +1 -0
  145. package/dist/ports/config-store.d.ts +27 -0
  146. package/dist/ports/config-store.d.ts.map +1 -0
  147. package/dist/ports/config-store.js +2 -0
  148. package/dist/ports/config-store.js.map +1 -0
  149. package/dist/ports/infrastructure.d.ts +123 -0
  150. package/dist/ports/infrastructure.d.ts.map +1 -0
  151. package/dist/ports/infrastructure.js +9 -0
  152. package/dist/ports/infrastructure.js.map +1 -0
  153. package/dist/ports/installation.d.ts +86 -0
  154. package/dist/ports/installation.d.ts.map +1 -0
  155. package/dist/ports/installation.js +2 -0
  156. package/dist/ports/installation.js.map +1 -0
  157. package/dist/ports/skill-registry.d.ts +74 -0
  158. package/dist/ports/skill-registry.d.ts.map +1 -0
  159. package/dist/ports/skill-registry.js +2 -0
  160. package/dist/ports/skill-registry.js.map +1 -0
  161. package/dist/ports/updates.d.ts +31 -0
  162. package/dist/ports/updates.d.ts.map +1 -0
  163. package/dist/ports/updates.js +4 -0
  164. package/dist/ports/updates.js.map +1 -0
  165. package/dist/testing/doubles.d.ts +127 -0
  166. package/dist/testing/doubles.d.ts.map +1 -0
  167. package/dist/testing/doubles.js +299 -0
  168. package/dist/testing/doubles.js.map +1 -0
  169. package/dist/testing/in-memory-file-system.d.ts +61 -0
  170. package/dist/testing/in-memory-file-system.d.ts.map +1 -0
  171. package/dist/testing/in-memory-file-system.js +297 -0
  172. package/dist/testing/in-memory-file-system.js.map +1 -0
  173. package/dist/testing/index.d.ts +10 -0
  174. package/dist/testing/index.d.ts.map +1 -0
  175. package/dist/testing/index.js +10 -0
  176. package/dist/testing/index.js.map +1 -0
  177. package/package.json +37 -0
@@ -0,0 +1,68 @@
1
+ import { INSTALL_SCOPES } from "../domain/agent.js";
2
+ import { targetsFor } from "./agent-selection.js";
3
+ import { findProjectRoot } from "./workspace.js";
4
+ /**
5
+ * Lists what is installed, per agent and scope.
6
+ *
7
+ * Unlike install, this never fails when an agent is undetected: showing an empty Codex
8
+ * section is more useful than an error, because the usual question is "what do I have?"
9
+ * rather than "what can I install into?".
10
+ */
11
+ export class ListInstalled {
12
+ ctx;
13
+ constructor(ctx) {
14
+ this.ctx = ctx;
15
+ }
16
+ async execute(options = {}) {
17
+ const requested = (options.agents ?? []).filter((value) => value.trim() !== '');
18
+ const adapters = requested.length === 0 || requested.includes('all')
19
+ ? this.ctx.agents.all()
20
+ : requested
21
+ .map((value) => this.ctx.agents.find(value))
22
+ .filter((adapter) => adapter !== undefined);
23
+ const projectRoot = options.projectRoot ??
24
+ (await findProjectRoot(this.ctx.fs, options.startDir ?? this.ctx.env.cwd(), this.ctx.env.homeDir()));
25
+ const scopes = options.scope === undefined ? INSTALL_SCOPES : [options.scope];
26
+ const entries = [];
27
+ const seenRoots = new Set();
28
+ let total = 0;
29
+ for (const adapter of adapters) {
30
+ for (const scope of scopes) {
31
+ // A project scope without a project is not an error here, just nothing to show.
32
+ if (scope === 'project' && projectRoot === undefined)
33
+ continue;
34
+ for (const target of targetsFor(this.ctx, adapter, scope, projectRoot)) {
35
+ // An agent whose global and project roots resolve to the same directory (possible
36
+ // when the config directory has been relocated into a repository) must not have its
37
+ // skills counted twice. The comparison must be on the canonical path: the global
38
+ // root comes from an environment variable and the project root from the cwd, and
39
+ // on macOS those can name the same directory through different symlink forms
40
+ // (/var/... versus /private/var/...).
41
+ const rootKey = await this.canonical(target.root);
42
+ if (seenRoots.has(`${adapter.id}:${rootKey}`))
43
+ continue;
44
+ seenRoots.add(`${adapter.id}:${rootKey}`);
45
+ const all = await this.ctx.installer.list(target);
46
+ const skills = options.includeUnmanaged === true ? all : all.filter((skill) => !skill.unmanaged);
47
+ total += skills.length;
48
+ entries.push({ target, skills });
49
+ }
50
+ }
51
+ }
52
+ return {
53
+ entries,
54
+ ...(projectRoot === undefined ? {} : { projectRoot }),
55
+ total,
56
+ };
57
+ }
58
+ /**
59
+ * Canonical form of a root for identity comparison. A root that does not exist yet has no
60
+ * canonical form to resolve — the resolved literal path is the best available identity.
61
+ */
62
+ async canonical(root) {
63
+ if (!(await this.ctx.fs.exists(root)))
64
+ return this.ctx.fs.resolve(root);
65
+ return this.ctx.fs.realpath(root);
66
+ }
67
+ }
68
+ //# sourceMappingURL=list-installed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-installed.js","sourceRoot":"","sources":["../../src/application/list-installed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type PackageKind } from '../domain/manifest.ts';
2
+ import { type PackageFile, type SkillPackage } from '../domain/skill-package.ts';
3
+ import type { FileSystem } from '../ports/infrastructure.ts';
4
+ import type { ValidationIssue } from '../domain/validation.ts';
5
+ export interface LoadPackageOptions {
6
+ /** Unknown manifest fields become errors. Used by `publish` and `validate --strict`. */
7
+ readonly strict?: boolean;
8
+ /** Hard cap on total package size, guarding against a hostile local tree. */
9
+ readonly maxTotalBytes?: number;
10
+ readonly maxFiles?: number;
11
+ }
12
+ export interface LoadedPackage {
13
+ readonly pkg: SkillPackage;
14
+ readonly directory: string;
15
+ readonly issues: readonly ValidationIssue[];
16
+ }
17
+ export declare const DEFAULT_MAX_TOTAL_BYTES: number;
18
+ export declare const DEFAULT_MAX_FILES = 2000;
19
+ /**
20
+ * Reads a skill package from a directory on disk.
21
+ *
22
+ * Shared by `validate`, `publish`, `create --check` and the local/git registries, so the
23
+ * definition of "what is in a package" exists once.
24
+ */
25
+ export declare function loadPackageFromDirectory(fs: FileSystem, directory: string, options?: LoadPackageOptions): Promise<LoadedPackage>;
26
+ /**
27
+ * Builds the initial package contents for `senior-skills create`.
28
+ * Kept here so the scaffold and the validator cannot drift apart.
29
+ */
30
+ export declare function scaffoldPackage(name: string, options?: {
31
+ readonly kind?: PackageKind;
32
+ readonly description?: string;
33
+ readonly license?: string;
34
+ readonly author?: string;
35
+ }): readonly PackageFile[];
36
+ /** Reads name/description/version out of a `SKILL.md` on disk without loading the package. */
37
+ export declare function peekSkillDocument(fs: FileSystem, skillMdPath: string): Promise<{
38
+ name?: string;
39
+ description?: string;
40
+ version?: string;
41
+ }>;
42
+ //# sourceMappingURL=package-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-loader.d.ts","sourceRoot":"","sources":["../../src/application/package-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,WAAW,EAEjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AASpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C;AAED,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AACxD,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAKtC;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,UAAU,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAgCxB;AAkGD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACrB,GACL,SAAS,WAAW,EAAE,CAsFxB;AAwID,8FAA8F;AAC9F,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,UAAU,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAQpE"}
@@ -0,0 +1,320 @@
1
+ import { AgentSkillsError, ErrorCode } from "../domain/errors.js";
2
+ import { DEFAULT_PACKAGE_KIND, MANIFEST_FILENAME, SKILL_ENTRYPOINT, entrypointFor, parseManifest, } from "../domain/manifest.js";
3
+ import { buildSkillPackage, encodeText, } from "../domain/skill-package.js";
4
+ import { normalize, toPosix } from "../domain/posix-path.js";
5
+ import { documentDescription, documentName, parseSkillDocument, stringifySkillDocument, } from "../domain/skill-document.js";
6
+ import { parseVersion } from "../domain/version.js";
7
+ export const DEFAULT_MAX_TOTAL_BYTES = 32 * 1024 * 1024;
8
+ export const DEFAULT_MAX_FILES = 2000;
9
+ /** Directories never shipped in a package, regardless of what `files` says. */
10
+ const ALWAYS_EXCLUDED = new Set(['.git', 'node_modules', '.senior-skills', '.DS_Store']);
11
+ /**
12
+ * Reads a skill package from a directory on disk.
13
+ *
14
+ * Shared by `validate`, `publish`, `create --check` and the local/git registries, so the
15
+ * definition of "what is in a package" exists once.
16
+ */
17
+ export async function loadPackageFromDirectory(fs, directory, options = {}) {
18
+ const root = fs.resolve(directory);
19
+ if (!(await fs.exists(root))) {
20
+ throw new AgentSkillsError(ErrorCode.INVALID_PACKAGE, `No such directory: ${directory}`, {
21
+ hints: ['Pass the path to a skill package directory (the one containing SKILL.md)'],
22
+ data: { directory },
23
+ });
24
+ }
25
+ const manifestPath = fs.join(root, MANIFEST_FILENAME);
26
+ if (!(await fs.exists(manifestPath))) {
27
+ throw new AgentSkillsError(ErrorCode.INVALID_PACKAGE, `${directory} is not a skill package: no ${MANIFEST_FILENAME}`, {
28
+ hints: [
29
+ `A package has ${MANIFEST_FILENAME} and its entrypoint (${SKILL_ENTRYPOINT} or ${entrypointFor('command')}) at its root`,
30
+ 'senior-skills create <name> to scaffold one',
31
+ ],
32
+ data: { directory },
33
+ });
34
+ }
35
+ const parsed = parseManifest(await fs.readTextFile(manifestPath), {
36
+ source: manifestPath,
37
+ ...(options.strict === undefined ? {} : { strict: options.strict }),
38
+ });
39
+ const files = await collectFiles(fs, root, parsed.manifest, options);
40
+ return { pkg: buildSkillPackage(parsed.manifest, files), directory: root, issues: parsed.issues };
41
+ }
42
+ async function collectFiles(fs, root, manifest, options) {
43
+ const maxFiles = options.maxFiles ?? DEFAULT_MAX_FILES;
44
+ const maxBytes = options.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES;
45
+ const collected = new Map();
46
+ let totalBytes = 0;
47
+ const addFile = async (absolute, relative) => {
48
+ if (collected.has(relative))
49
+ return;
50
+ const stat = await fs.lstat(absolute);
51
+ if (stat.isSymbolicLink) {
52
+ // Rejected rather than followed: a symlink in a package is either an escape attempt or
53
+ // a portability bug, and neither should silently become a real file at install time.
54
+ throw new AgentSkillsError(ErrorCode.UNSAFE_PATH, `Symbolic links are not allowed in skill packages: ${relative}`, {
55
+ details: [`-> ${await fs.readlink(absolute).catch(() => '(unreadable)')}`],
56
+ hints: ['Replace the link with a real file'],
57
+ data: { path: relative },
58
+ });
59
+ }
60
+ if (!stat.isFile)
61
+ return;
62
+ totalBytes += stat.size;
63
+ if (collected.size >= maxFiles) {
64
+ throw new AgentSkillsError(ErrorCode.INVALID_PACKAGE, `Package has more than ${maxFiles} files`, { hints: ['Trim the "files" list in skill.yaml'], data: { maxFiles } });
65
+ }
66
+ if (totalBytes > maxBytes) {
67
+ throw new AgentSkillsError(ErrorCode.INVALID_PACKAGE, `Package exceeds the ${Math.round(maxBytes / 1024 / 1024)} MB limit`, { hints: ['Move large assets out of the package'], data: { maxBytes } });
68
+ }
69
+ collected.set(relative, {
70
+ path: relative,
71
+ bytes: await fs.readFile(absolute),
72
+ sourcePath: absolute,
73
+ });
74
+ };
75
+ const addTree = async (absolute, relative) => {
76
+ const stat = await fs.lstat(absolute);
77
+ if (stat.isSymbolicLink) {
78
+ throw new AgentSkillsError(ErrorCode.UNSAFE_PATH, `Symbolic links are not allowed in skill packages: ${relative}`, { data: { path: relative } });
79
+ }
80
+ if (stat.isFile) {
81
+ await addFile(absolute, relative);
82
+ return;
83
+ }
84
+ if (!stat.isDirectory)
85
+ return;
86
+ for (const entry of await fs.readDir(absolute)) {
87
+ if (ALWAYS_EXCLUDED.has(entry.name))
88
+ continue;
89
+ await addTree(fs.join(absolute, entry.name), normalize(`${relative}/${entry.name}`));
90
+ }
91
+ };
92
+ for (const declared of manifest.files) {
93
+ const relative = normalize(declared.replace(/\/+$/, ''));
94
+ if (relative === '.' || relative === '')
95
+ continue;
96
+ const absolute = fs.join(root, ...relative.split('/'));
97
+ if (!(await fs.exists(absolute))) {
98
+ // Missing declared paths are a validation finding, not a load failure, so `validate`
99
+ // can list every problem at once.
100
+ continue;
101
+ }
102
+ await addTree(absolute, relative);
103
+ }
104
+ // The manifest always ships, even if the author forgot to list it.
105
+ const manifestRelative = MANIFEST_FILENAME;
106
+ if (!collected.has(manifestRelative)) {
107
+ await addFile(fs.join(root, manifestRelative), manifestRelative);
108
+ }
109
+ return [...collected.values()];
110
+ }
111
+ /**
112
+ * Builds the initial package contents for `senior-skills create`.
113
+ * Kept here so the scaffold and the validator cannot drift apart.
114
+ */
115
+ export function scaffoldPackage(name, options = {}) {
116
+ const kind = options.kind ?? DEFAULT_PACKAGE_KIND;
117
+ const license = options.license ?? 'Apache-2.0';
118
+ const title = name
119
+ .split('-')
120
+ .map((part) => (part.length === 0 ? part : part[0].toUpperCase() + part.slice(1)))
121
+ .join(' ');
122
+ if (kind === 'command') {
123
+ return scaffoldCommand(name, title, license, options);
124
+ }
125
+ if (kind === 'workflow') {
126
+ return scaffoldWorkflow(name, title, license, options);
127
+ }
128
+ const description = options.description ??
129
+ `What ${name} covers, and when an agent should use it. Replace this with a description that names the situations this skill applies to.`;
130
+ const manifest = [
131
+ 'schemaVersion: 1',
132
+ '',
133
+ `name: ${name}`,
134
+ 'version: 0.1.0',
135
+ `description: ${JSON.stringify(description)}`,
136
+ `license: ${license}`,
137
+ ...(options.author === undefined ? [] : ['', 'authors:', ` - name: ${options.author}`]),
138
+ '',
139
+ 'keywords: []',
140
+ '',
141
+ '# Omit `compatibility` to declare the skill works with every agent.',
142
+ '# compatibility:',
143
+ '# agents:',
144
+ '# - id: claude-code',
145
+ '# - id: codex',
146
+ '',
147
+ 'files:',
148
+ ' - SKILL.md',
149
+ ' - skill.yaml',
150
+ ' - references/',
151
+ '',
152
+ 'dependencies: []',
153
+ '',
154
+ ].join('\n');
155
+ const skillDoc = stringifySkillDocument({
156
+ frontmatter: { name, description },
157
+ body: [
158
+ `# ${title}`,
159
+ '',
160
+ '## Purpose',
161
+ '',
162
+ 'One paragraph on what this skill makes the agent better at, and what it deliberately',
163
+ 'does not cover.',
164
+ '',
165
+ '## Workflow',
166
+ '',
167
+ '1. First step the agent should take.',
168
+ '2. Second step.',
169
+ '3. How to know the work is done.',
170
+ '',
171
+ '## Rules',
172
+ '',
173
+ '- A concrete rule that changes what the agent does.',
174
+ '- Another rule. Prefer specifics over generic advice.',
175
+ '',
176
+ '## References',
177
+ '',
178
+ '- [Detailed notes](references/notes.md) — read when the task needs the full detail.',
179
+ '',
180
+ ].join('\n'),
181
+ });
182
+ const notes = [
183
+ `# ${title} — reference notes`,
184
+ '',
185
+ 'Put material here that is only needed for some tasks. `SKILL.md` stays short; this file',
186
+ 'is read on demand.',
187
+ '',
188
+ ].join('\n');
189
+ return [
190
+ { path: SKILL_ENTRYPOINT, bytes: encodeText(skillDoc) },
191
+ { path: MANIFEST_FILENAME, bytes: encodeText(manifest) },
192
+ { path: 'references/notes.md', bytes: encodeText(notes) },
193
+ ];
194
+ }
195
+ /**
196
+ * A command is one file, so its scaffold is one file plus the manifest: no `references/`,
197
+ * because nothing but the entrypoint would be installed.
198
+ */
199
+ function scaffoldCommand(name, title, license, options) {
200
+ const entrypoint = entrypointFor('command');
201
+ const description = options.description ??
202
+ `What /${name} does. One line: this is what the user sees in the command list.`;
203
+ const manifest = [
204
+ 'schemaVersion: 1',
205
+ '',
206
+ `name: ${name}`,
207
+ 'kind: command',
208
+ 'version: 0.1.0',
209
+ `description: ${JSON.stringify(description)}`,
210
+ `license: ${license}`,
211
+ ...(options.author === undefined ? [] : ['', 'authors:', ` - name: ${options.author}`]),
212
+ '',
213
+ 'keywords: []',
214
+ '',
215
+ '# Codex has no user-invoked commands; declaring compatibility keeps installs honest.',
216
+ 'compatibility:',
217
+ ' agents:',
218
+ ' - id: claude-code',
219
+ '',
220
+ 'files:',
221
+ ` - ${entrypoint}`,
222
+ ' - skill.yaml',
223
+ '',
224
+ 'dependencies: []',
225
+ '',
226
+ ].join('\n');
227
+ const commandDoc = stringifySkillDocument({
228
+ frontmatter: { name, description, 'argument-hint': '[what the command takes]' },
229
+ body: [
230
+ `# ${title}`,
231
+ '',
232
+ 'The body is the prompt the agent runs when the user types the command.',
233
+ 'Write it as instructions to the agent, not as documentation for a reader.',
234
+ '',
235
+ '## Task',
236
+ '',
237
+ 'What to do with $ARGUMENTS.',
238
+ '',
239
+ '## Steps',
240
+ '',
241
+ '1. First step.',
242
+ '2. Second step.',
243
+ '3. How to know the work is done.',
244
+ '',
245
+ ].join('\n'),
246
+ });
247
+ return [
248
+ { path: entrypoint, bytes: encodeText(commandDoc) },
249
+ { path: MANIFEST_FILENAME, bytes: encodeText(manifest) },
250
+ ];
251
+ }
252
+ /**
253
+ * A workflow is a script Claude Code compiles, so the scaffold is a runnable skeleton
254
+ * rather than prose: `meta` first (it must be the first statement), then phases that match
255
+ * the titles declared in it.
256
+ */
257
+ function scaffoldWorkflow(name, title, license, options) {
258
+ const entrypoint = entrypointFor('workflow');
259
+ const description = options.description ?? `What ${name} orchestrates, in one line. Shown by search and info.`;
260
+ const manifest = [
261
+ 'schemaVersion: 1',
262
+ '',
263
+ `name: ${name}`,
264
+ 'kind: workflow',
265
+ 'version: 0.1.0',
266
+ `description: ${JSON.stringify(description)}`,
267
+ `license: ${license}`,
268
+ ...(options.author === undefined ? [] : ['', 'authors:', ` - name: ${options.author}`]),
269
+ '',
270
+ 'keywords: []',
271
+ '',
272
+ '# Only Claude Code runs workflows; declaring it keeps installs honest.',
273
+ 'compatibility:',
274
+ ' agents:',
275
+ ' - id: claude-code',
276
+ '',
277
+ 'files:',
278
+ ` - ${entrypoint}`,
279
+ ' - skill.yaml',
280
+ '',
281
+ 'dependencies: []',
282
+ '',
283
+ ].join('\n');
284
+ const script = [
285
+ 'export const meta = {',
286
+ ` name: ${JSON.stringify(name)},`,
287
+ ` description: ${JSON.stringify(description)},`,
288
+ ' phases: [',
289
+ ` { title: "Investigate", detail: ${JSON.stringify(`What ${title} gathers first.`)} },`,
290
+ ' { title: "Report" },',
291
+ ' ],',
292
+ '};',
293
+ '',
294
+ '// Phase titles are matched against meta.phases exactly.',
295
+ 'phase("Investigate");',
296
+ 'await agent({',
297
+ ` description: ${JSON.stringify(`${title}: investigate`)},`,
298
+ ' prompt: "What the sub-agent should do. $ARGUMENTS is available here.",',
299
+ '});',
300
+ '',
301
+ 'phase("Report");',
302
+ 'log("What the run produced.");',
303
+ '',
304
+ ].join('\n');
305
+ return [
306
+ { path: entrypoint, bytes: encodeText(script) },
307
+ { path: MANIFEST_FILENAME, bytes: encodeText(manifest) },
308
+ ];
309
+ }
310
+ /** Reads name/description/version out of a `SKILL.md` on disk without loading the package. */
311
+ export async function peekSkillDocument(fs, skillMdPath) {
312
+ const doc = parseSkillDocument(await fs.readTextFile(skillMdPath), toPosix(skillMdPath));
313
+ const rawVersion = doc.frontmatter['version'];
314
+ return {
315
+ ...(documentName(doc) === undefined ? {} : { name: documentName(doc) }),
316
+ ...(documentDescription(doc) === undefined ? {} : { description: documentDescription(doc) }),
317
+ ...(typeof rawVersion === 'string' ? { version: parseVersion(rawVersion, skillMdPath) } : {}),
318
+ };
319
+ }
320
+ //# sourceMappingURL=package-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-loader.js","sourceRoot":"","sources":["../../src/application/package-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { IndexSkillEntry, IndexVersionEntry } from '../domain/registry-index.ts';
2
+ import type { Hasher } from '../ports/infrastructure.ts';
3
+ import type { ApplicationContext } from './context.ts';
4
+ export interface PublishOptions {
5
+ /** Package directory. Defaults to the process cwd. */
6
+ readonly directory?: string;
7
+ /** Registry the version is destined for; used for the "already published" check. */
8
+ readonly registry?: string;
9
+ readonly dryRun?: boolean;
10
+ }
11
+ export interface PublishReport {
12
+ readonly name: string;
13
+ readonly version: string;
14
+ readonly directory: string;
15
+ readonly integrity: string;
16
+ readonly registry?: string;
17
+ /** The entry a maintainer adds to the registry index. */
18
+ readonly indexEntry: IndexVersionEntry;
19
+ /** Full skill entry, for a registry that does not yet list this name. */
20
+ readonly skillEntry: IndexSkillEntry;
21
+ readonly files: readonly string[];
22
+ readonly warnings: readonly string[];
23
+ }
24
+ /**
25
+ * `publish` is prepare-and-emit, not upload.
26
+ *
27
+ * The v1 registry is a git repository, whose write path is a pull request — a better review
28
+ * surface for "here is a new skill that will run inside your agent" than an API token. The
29
+ * command therefore does every check a server would do, then hands back the exact index
30
+ * entry to commit. `PublishTarget` exists so an HTTP registry can later take the same
31
+ * validated result and POST it.
32
+ */
33
+ export declare class PublishSkill {
34
+ private readonly ctx;
35
+ private readonly hasher;
36
+ constructor(ctx: ApplicationContext, hasher: Hasher);
37
+ execute(options?: PublishOptions): Promise<PublishReport>;
38
+ private assertVersionIsNew;
39
+ private assertDependenciesResolve;
40
+ }
41
+ //# sourceMappingURL=publish-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-skill.d.ts","sourceRoot":"","sources":["../../src/application/publish-skill.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,GAAG,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM;IAK7C,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC;YAwDrD,kBAAkB;YA4ClB,yBAAyB;CAsBxC"}
@@ -0,0 +1,112 @@
1
+ import { AgentSkillsError, ErrorCode } from "../domain/errors.js";
2
+ import { computePackageIntegrity } from "../domain/integrity.js";
3
+ import { compareVersions } from "../domain/version.js";
4
+ import { formatIssue } from "./install-skills.js";
5
+ import { validateDirectory } from "./validate-package.js";
6
+ /**
7
+ * `publish` is prepare-and-emit, not upload.
8
+ *
9
+ * The v1 registry is a git repository, whose write path is a pull request — a better review
10
+ * surface for "here is a new skill that will run inside your agent" than an API token. The
11
+ * command therefore does every check a server would do, then hands back the exact index
12
+ * entry to commit. `PublishTarget` exists so an HTTP registry can later take the same
13
+ * validated result and POST it.
14
+ */
15
+ export class PublishSkill {
16
+ ctx;
17
+ hasher;
18
+ constructor(ctx, hasher) {
19
+ this.ctx = ctx;
20
+ this.hasher = hasher;
21
+ }
22
+ async execute(options = {}) {
23
+ const directory = options.directory ?? this.ctx.env.cwd();
24
+ // Strict: unknown manifest fields are errors when publishing, because a typo that only
25
+ // warns locally becomes a permanent part of a public registry.
26
+ const validated = await validateDirectory(this.ctx, directory, { strict: true });
27
+ if (!validated.ok) {
28
+ throw new AgentSkillsError(ErrorCode.PUBLISH_REJECTED, 'Package failed validation', {
29
+ details: validated.errors.map(formatIssue),
30
+ hints: [`senior-skills validate ${directory} --strict to iterate on the problems`],
31
+ data: { directory, issues: validated.errors },
32
+ });
33
+ }
34
+ const { manifest } = validated.pkg;
35
+ const warnings = validated.warnings.map(formatIssue);
36
+ await this.assertVersionIsNew(manifest.name, manifest.version, options.registry, warnings);
37
+ await this.assertDependenciesResolve(manifest, warnings);
38
+ const integrity = computePackageIntegrity(validated.pkg, this.hasher);
39
+ if (manifest.integrity !== undefined && manifest.integrity !== integrity) {
40
+ warnings.push(`skill.yaml declares integrity ${manifest.integrity}, but the contents hash to ${integrity}; the computed value is authoritative`);
41
+ }
42
+ const indexEntry = {
43
+ version: manifest.version,
44
+ path: `skills/${manifest.name}`,
45
+ integrity,
46
+ publishedAt: this.ctx.clock.now().toISOString(),
47
+ deprecated: false,
48
+ };
49
+ return {
50
+ name: manifest.name,
51
+ version: manifest.version,
52
+ directory: validated.directory,
53
+ integrity,
54
+ ...(options.registry === undefined ? {} : { registry: options.registry }),
55
+ indexEntry,
56
+ skillEntry: {
57
+ name: manifest.name,
58
+ description: manifest.description,
59
+ keywords: manifest.keywords,
60
+ latest: manifest.version,
61
+ versions: [indexEntry],
62
+ },
63
+ files: validated.pkg.files.map((file) => file.path),
64
+ warnings,
65
+ };
66
+ }
67
+ async assertVersionIsNew(name, version, registryName, warnings) {
68
+ const registry = registryName === undefined
69
+ ? this.ctx.registry.members()[0]
70
+ : this.ctx.registry.named(registryName);
71
+ if (registry === undefined)
72
+ return;
73
+ let published;
74
+ try {
75
+ published = await registry.versions(name);
76
+ }
77
+ catch {
78
+ // A registry that cannot be reached must not block preparing a release; the
79
+ // maintainer's pull request is the real gate.
80
+ warnings.push(`Could not reach registry "${registry.name}" to check for version collisions`);
81
+ return;
82
+ }
83
+ if (published.length === 0)
84
+ return;
85
+ if (published.some((entry) => entry.version === version)) {
86
+ throw new AgentSkillsError(ErrorCode.PUBLISH_REJECTED, `${name}@${version} is already published in "${registry.name}"`, {
87
+ hints: ['Bump the version in skill.yaml (and in SKILL.md if it declares one)'],
88
+ data: { name, version, registry: registry.name },
89
+ });
90
+ }
91
+ const newest = published[0].version;
92
+ if (compareVersions(version, newest) < 0) {
93
+ warnings.push(`${version} is older than the currently published ${newest}; publishing it will not change "latest"`);
94
+ }
95
+ }
96
+ async assertDependenciesResolve(manifest, warnings) {
97
+ for (const dependency of manifest.dependencies) {
98
+ const owner = await this.ctx.registry.ownerOf(dependency.name).catch(() => undefined);
99
+ if (owner === undefined) {
100
+ throw new AgentSkillsError(ErrorCode.PUBLISH_REJECTED, `Dependency "${dependency.name}" is not published in any configured registry`, {
101
+ hints: [
102
+ 'Publish the dependency first, or make it an optionalDependency',
103
+ 'senior-skills registry list to check where the CLI is looking',
104
+ ],
105
+ data: { dependency: dependency.name },
106
+ });
107
+ }
108
+ warnings.push(`dependency ${dependency.name}@${dependency.version} resolves via "${owner}"`);
109
+ }
110
+ }
111
+ }
112
+ //# sourceMappingURL=publish-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-skill.js","sourceRoot":"","sources":["../../src/application/publish-skill.ts"],"names":[],"mappings":"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"}