@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,34 @@
1
+ import type { InstallScope } from '../domain/agent.ts';
2
+ import type { UninstallResult } from '../ports/installation.ts';
3
+ import type { ApplicationContext } from './context.ts';
4
+ export interface RemoveOptions {
5
+ readonly names: readonly string[];
6
+ readonly scope: InstallScope;
7
+ readonly agents?: readonly string[];
8
+ readonly projectRoot?: string;
9
+ readonly startDir?: string;
10
+ /** Delete files whose content no longer matches the receipt. */
11
+ readonly force?: boolean;
12
+ readonly dryRun?: boolean;
13
+ }
14
+ export interface RemoveReport {
15
+ readonly results: readonly UninstallResult[];
16
+ readonly warnings: readonly string[];
17
+ readonly scope: InstallScope;
18
+ readonly projectRoot?: string;
19
+ readonly dryRun: boolean;
20
+ readonly lockfileUpdated: boolean;
21
+ }
22
+ /**
23
+ * Uninstall.
24
+ *
25
+ * The rule that shapes this service: never delete a file the tool did not install. The
26
+ * installer enforces it from the receipt; this service's job is to fail loudly when a name
27
+ * is not installed anywhere, rather than reporting a cheerful no-op.
28
+ */
29
+ export declare class RemoveSkills {
30
+ private readonly ctx;
31
+ constructor(ctx: ApplicationContext);
32
+ execute(options: RemoveOptions): Promise<RemoveReport>;
33
+ }
34
+ //# sourceMappingURL=remove-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-skills.d.ts","sourceRoot":"","sources":["../../src/application/remove-skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;gBAE7B,GAAG,EAAE,kBAAkB;IAI7B,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CAyF7D"}
@@ -0,0 +1,95 @@
1
+ import { AgentSkillsError, ErrorCode } from "../domain/errors.js";
2
+ import { withoutSkill } from "../domain/lockfile.js";
3
+ import { parseSkillRef } from "../domain/skill-ref.js";
4
+ import { selectAgents } from "./agent-selection.js";
5
+ import { readLockfile, writeLockfile } from "./workspace.js";
6
+ /**
7
+ * Uninstall.
8
+ *
9
+ * The rule that shapes this service: never delete a file the tool did not install. The
10
+ * installer enforces it from the receipt; this service's job is to fail loudly when a name
11
+ * is not installed anywhere, rather than reporting a cheerful no-op.
12
+ */
13
+ export class RemoveSkills {
14
+ ctx;
15
+ constructor(ctx) {
16
+ this.ctx = ctx;
17
+ }
18
+ async execute(options) {
19
+ if (options.names.length === 0) {
20
+ throw new AgentSkillsError(ErrorCode.USAGE, 'No skills given', {
21
+ hints: ['senior-skills uninstall java-performance'],
22
+ });
23
+ }
24
+ const names = options.names.map((raw) => parseSkillRef(raw).name);
25
+ const selection = await selectAgents(this.ctx, {
26
+ scope: options.scope,
27
+ ...(options.agents === undefined ? {} : { agents: options.agents }),
28
+ ...(options.projectRoot === undefined ? {} : { projectRoot: options.projectRoot }),
29
+ ...(options.startDir === undefined ? {} : { startDir: options.startDir }),
30
+ });
31
+ const results = [];
32
+ const warnings = [];
33
+ for (const name of names) {
34
+ let removedSomewhere = false;
35
+ for (const target of selection.targets) {
36
+ const installed = await this.ctx.installer.read(target, name);
37
+ if (installed === undefined)
38
+ continue;
39
+ if (installed.unmanaged) {
40
+ warnings.push(`${name} exists in ${target.root} but was not installed by senior-skills; left untouched`);
41
+ continue;
42
+ }
43
+ const adapter = this.ctx.agents.find(target.agentId);
44
+ const result = await this.ctx.installer.uninstall({
45
+ name,
46
+ adapter,
47
+ target,
48
+ force: options.force === true,
49
+ dryRun: options.dryRun === true,
50
+ });
51
+ results.push(result);
52
+ removedSomewhere = true;
53
+ for (const preserved of result.preserved) {
54
+ warnings.push(`${name}: kept modified file ${preserved} (use --force to delete it)`);
55
+ }
56
+ }
57
+ if (!removedSomewhere) {
58
+ throw new AgentSkillsError(ErrorCode.NOT_INSTALLED, `"${name}" is not installed`, {
59
+ details: [
60
+ '',
61
+ 'Looked in:',
62
+ ...selection.targets.map((target) => ` ${target.displayName} (${target.scope}): ${target.root}`),
63
+ ],
64
+ hints: ['senior-skills list to see what is installed'],
65
+ data: { name },
66
+ });
67
+ }
68
+ }
69
+ let lockfileUpdated = false;
70
+ if (options.scope === 'project' &&
71
+ selection.projectRoot !== undefined &&
72
+ options.dryRun !== true) {
73
+ let lock = await readLockfile(this.ctx.fs, selection.projectRoot);
74
+ const before = Object.keys(lock.skills).length;
75
+ for (const name of names)
76
+ lock = withoutSkill(lock, name);
77
+ if (Object.keys(lock.skills).length !== before) {
78
+ await writeLockfile(this.ctx.fs, selection.projectRoot, {
79
+ ...lock,
80
+ generatedWith: this.ctx.toolVersion,
81
+ });
82
+ lockfileUpdated = true;
83
+ }
84
+ }
85
+ return {
86
+ results,
87
+ warnings,
88
+ scope: options.scope,
89
+ ...(selection.projectRoot === undefined ? {} : { projectRoot: selection.projectRoot }),
90
+ dryRun: options.dryRun === true,
91
+ lockfileUpdated,
92
+ };
93
+ }
94
+ }
95
+ //# sourceMappingURL=remove-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-skills.js","sourceRoot":"","sources":["../../src/application/remove-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { IndexVersionEntry } from '../domain/registry-index.ts';
2
+ import type { SkillManifest } from '../domain/manifest.ts';
3
+ import type { ResolutionSource } from '../domain/resolver.ts';
4
+ import type { SemanticVersion } from '../domain/version.ts';
5
+ import type { FederatedRegistry } from '../ports/skill-registry.ts';
6
+ /**
7
+ * Bridges the federated registry to the resolver.
8
+ *
9
+ * The resolver deliberately knows nothing about precedence or registry kinds; it asks for
10
+ * versions and gets back the registry that owned the answer, which is what ends up pinned
11
+ * in `skills.lock`.
12
+ */
13
+ export declare class FederationResolutionSource implements ResolutionSource {
14
+ private readonly federation;
15
+ /** From `--registry`: restricts every lookup to one configured registry. */
16
+ private readonly restrictTo?;
17
+ constructor(federation: FederatedRegistry, restrictTo?: string);
18
+ listVersions(name: string, registry?: string): Promise<{
19
+ registry: string;
20
+ versions: readonly IndexVersionEntry[];
21
+ }>;
22
+ loadManifest(name: string, version: SemanticVersion, registry: string): Promise<SkillManifest>;
23
+ private require;
24
+ }
25
+ //# sourceMappingURL=resolution-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution-source.d.ts","sourceRoot":"","sources":["../../src/application/resolution-source.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,4BAA4B,CAAC;AAEnF;;;;;;GAMG;AACH,qBAAa,0BAA2B,YAAW,gBAAgB;IACjE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;gBAEzB,UAAU,EAAE,iBAAiB,EAAE,UAAU,CAAC,EAAE,MAAM;IAKxD,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;KAAE,CAAC;IAelE,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC;IAIzB,OAAO,CAAC,OAAO;CAahB"}
@@ -0,0 +1,60 @@
1
+ import { AgentSkillsError, ErrorCode } from "../domain/errors.js";
2
+ /**
3
+ * Bridges the federated registry to the resolver.
4
+ *
5
+ * The resolver deliberately knows nothing about precedence or registry kinds; it asks for
6
+ * versions and gets back the registry that owned the answer, which is what ends up pinned
7
+ * in `skills.lock`.
8
+ */
9
+ export class FederationResolutionSource {
10
+ federation;
11
+ /** From `--registry`: restricts every lookup to one configured registry. */
12
+ restrictTo;
13
+ constructor(federation, restrictTo) {
14
+ this.federation = federation;
15
+ this.restrictTo = restrictTo;
16
+ }
17
+ async listVersions(name, registry) {
18
+ const requested = registry ?? this.restrictTo;
19
+ if (requested !== undefined) {
20
+ const target = this.require(requested);
21
+ const versions = await target.versions(name);
22
+ if (versions.length === 0)
23
+ throw notFound(name, requested);
24
+ return { registry: requested, versions };
25
+ }
26
+ const owner = await this.federation.ownerOf(name);
27
+ if (owner === undefined)
28
+ throw notFound(name);
29
+ return { registry: owner, versions: await this.require(owner).versions(name) };
30
+ }
31
+ async loadManifest(name, version, registry) {
32
+ return this.require(registry).manifest(name, version);
33
+ }
34
+ require(name) {
35
+ const registry = this.federation.named(name);
36
+ if (registry !== undefined)
37
+ return registry;
38
+ throw new AgentSkillsError(ErrorCode.REGISTRY_NOT_FOUND, `No registry named "${name}"`, {
39
+ details: [
40
+ '',
41
+ 'Configured registries:',
42
+ ...this.federation.members().map((member) => ` ${member.name} (${member.kind})`),
43
+ ],
44
+ hints: ['senior-skills registry list', 'senior-skills registry add <name> <url>'],
45
+ data: { requested: name },
46
+ });
47
+ }
48
+ }
49
+ function notFound(name, registry) {
50
+ return new AgentSkillsError(ErrorCode.SKILL_NOT_FOUND, registry === undefined
51
+ ? `Skill "${name}" was not found in any configured registry`
52
+ : `Skill "${name}" was not found in registry "${registry}"`, {
53
+ hints: [
54
+ `senior-skills search ${name} to look for a similar name`,
55
+ 'senior-skills registry list to see where the CLI is looking',
56
+ ],
57
+ data: { name, ...(registry === undefined ? {} : { registry }) },
58
+ });
59
+ }
60
+ //# sourceMappingURL=resolution-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution-source.js","sourceRoot":"","sources":["../../src/application/resolution-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAOlE;;;;;;GAMG;AACH,MAAM,OAAO,0BAA0B;IACpB,UAAU,CAAoB;IAC/C,4EAA4E;IAC3D,UAAU,CAAU;IAErC,YAAY,UAA6B,EAAE,UAAmB;QAC5D,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,IAAY,EACZ,QAAiB;QAEjB,MAAM,SAAS,GAAG,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC;QAE9C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAC3D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QAC3C,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,IAAY,EACZ,OAAwB,EACxB,QAAgB;QAEhB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAEO,OAAO,CAAC,IAAY;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,EAAE,sBAAsB,IAAI,GAAG,EAAE;YACtF,OAAO,EAAE;gBACP,EAAE;gBACF,wBAAwB;gBACxB,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,IAAI,GAAG,CAAC;aACnF;YACD,KAAK,EAAE,CAAC,6BAA6B,EAAE,yCAAyC,CAAC;YACjF,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,QAAiB;IAC/C,OAAO,IAAI,gBAAgB,CACzB,SAAS,CAAC,eAAe,EACzB,QAAQ,KAAK,SAAS;QACpB,CAAC,CAAC,UAAU,IAAI,4CAA4C;QAC5D,CAAC,CAAC,UAAU,IAAI,gCAAgC,QAAQ,GAAG,EAC7D;QACE,KAAK,EAAE;YACL,wBAAwB,IAAI,+BAA+B;YAC3D,+DAA+D;SAChE;QACD,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;KAChE,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type ResolvedSkill, type ResolutionResult, type ResolutionSource, type ResolveOptions } from '../domain/resolver.ts';
2
+ import { type SkillRef } from '../domain/skill-ref.ts';
3
+ /** Installation provenance, separate from the domain's dependency graph. */
4
+ export interface InstallResolvedSkill extends ResolvedSkill {
5
+ /** Explicitly requested skills whose selected manifests suggest this package. */
6
+ readonly suggestedBy?: readonly string[];
7
+ }
8
+ interface InstallationResolution extends ResolutionResult {
9
+ readonly order: readonly InstallResolvedSkill[];
10
+ }
11
+ /**
12
+ * Expand only the selected manifests of the original requests. Suggestions become additional
13
+ * resolution roots, never dependency edges; their own suggestions are not traversed.
14
+ */
15
+ export declare function resolveSuggestions(source: ResolutionSource, refs: readonly SkillRef[], options: ResolveOptions, suggestedVersionRanges?: Readonly<Record<string, string>>): Promise<InstallationResolution>;
16
+ export {};
17
+ //# sourceMappingURL=resolve-suggestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-suggestions.d.ts","sourceRoot":"","sources":["../../src/application/resolve-suggestions.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEtE,4EAA4E;AAC5E,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,iFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,UAAU,sBAAuB,SAAQ,gBAAgB;IACvD,QAAQ,CAAC,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACjD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,SAAS,QAAQ,EAAE,EACzB,OAAO,EAAE,cAAc,EACvB,sBAAsB,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAC5D,OAAO,CAAC,sBAAsB,CAAC,CA2EjC"}
@@ -0,0 +1,77 @@
1
+ import { AgentSkillsError } from "../domain/errors.js";
2
+ import { Resolver, } from "../domain/resolver.js";
3
+ import { parseSkillRef } from "../domain/skill-ref.js";
4
+ /**
5
+ * Expand only the selected manifests of the original requests. Suggestions become additional
6
+ * resolution roots, never dependency edges; their own suggestions are not traversed.
7
+ */
8
+ export async function resolveSuggestions(source, refs, options, suggestedVersionRanges = {}) {
9
+ const resolver = new Resolver(source);
10
+ const initial = await resolver.resolve(refs, options);
11
+ const directNames = new Set(refs.map((ref) => ref.name));
12
+ const roots = initial.order.filter((skill) => directNames.has(skill.name));
13
+ const suggestedBy = new Map();
14
+ for (const root of roots) {
15
+ for (const name of root.manifest.suggests) {
16
+ const origins = suggestedBy.get(name) ?? new Set();
17
+ origins.add(root.name);
18
+ suggestedBy.set(name, origins);
19
+ }
20
+ }
21
+ if (suggestedBy.size === 0)
22
+ return initial;
23
+ // Exact qualified roots preserve the manifests from which suggestions were read. A
24
+ // companion constraint may conflict with a root, but must never silently replace it.
25
+ const expanded = roots.map((root) => parseSkillRef(`${root.registry}:${root.name}@${root.version}`));
26
+ const pinned = { ...options.pinned };
27
+ for (const root of roots)
28
+ delete pinned[root.name];
29
+ for (const name of [...suggestedBy.keys()].sort()) {
30
+ if (directNames.has(name))
31
+ continue;
32
+ const range = suggestedVersionRanges[name] ?? pinned[name];
33
+ expanded.push(parseSkillRef(range === undefined ? name : `${name}@${range}`));
34
+ // Its root constraint now enforces the pin/range. Keep manifest dependency ranges
35
+ // intact, particularly when update deliberately moves beyond a previous lock pin.
36
+ delete pinned[name];
37
+ }
38
+ let resolved;
39
+ try {
40
+ resolved = await resolver.resolve(expanded, { ...options, pinned });
41
+ }
42
+ catch (cause) {
43
+ if (!(cause instanceof AgentSkillsError))
44
+ throw cause;
45
+ const suggestions = [...suggestedBy].map(([name, origins]) => ({
46
+ name,
47
+ suggestedBy: [...origins].sort(),
48
+ }));
49
+ throw new AgentSkillsError(cause.code, cause.message, {
50
+ cause,
51
+ details: [
52
+ ...cause.details,
53
+ 'Requested suggestions:',
54
+ ...suggestions.map(({ name, suggestedBy: origins }) => ` ${name} suggested by ${origins.join(', ')}`),
55
+ ],
56
+ hints: cause.hints,
57
+ data: { ...cause.data, suggestions },
58
+ });
59
+ }
60
+ return {
61
+ warnings: [...new Set([...initial.warnings, ...resolved.warnings])],
62
+ order: resolved.order.map((skill) => ({
63
+ ...skill,
64
+ direct: directNames.has(skill.name),
65
+ ...(suggestedBy.has(skill.name)
66
+ ? { suggestedBy: [...suggestedBy.get(skill.name)].sort() }
67
+ : {}),
68
+ // Derive ownership from the complete graph: a later constraint can refer to an
69
+ // already selected version without causing the resolver to choose it again.
70
+ requiredBy: resolved.order
71
+ .filter((owner) => [...owner.manifest.dependencies, ...owner.manifest.optionalDependencies].some((dependency) => dependency.name === skill.name))
72
+ .map((owner) => `${owner.name}@${owner.version}`)
73
+ .sort(),
74
+ })),
75
+ };
76
+ }
77
+ //# sourceMappingURL=resolve-suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-suggestions.js","sourceRoot":"","sources":["../../src/application/resolve-suggestions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { IndexVersionEntry } from '../domain/registry-index.ts';
2
+ import type { SkillManifest } from '../domain/manifest.ts';
3
+ import type { InstalledSkill } from '../ports/installation.ts';
4
+ import type { SkillSummary } from '../ports/skill-registry.ts';
5
+ import type { ApplicationContext } from './context.ts';
6
+ export interface SearchOptions {
7
+ readonly query: string;
8
+ readonly registry?: string;
9
+ readonly limit?: number;
10
+ }
11
+ export declare class SearchSkills {
12
+ private readonly ctx;
13
+ constructor(ctx: ApplicationContext);
14
+ execute(options: SearchOptions): Promise<readonly SkillSummary[]>;
15
+ }
16
+ export interface SkillInfo {
17
+ readonly name: string;
18
+ readonly registry: string;
19
+ readonly manifest: SkillManifest;
20
+ readonly versions: readonly IndexVersionEntry[];
21
+ readonly latest: IndexVersionEntry;
22
+ /** Where this skill is currently installed, across every agent and scope. */
23
+ readonly installed: readonly InstalledSkill[];
24
+ }
25
+ /**
26
+ * `info` answers "what is this and do I have it?" in one call, which is why it joins registry
27
+ * metadata with local install state rather than making the user run two commands.
28
+ */
29
+ export declare class DescribeSkill {
30
+ private readonly ctx;
31
+ constructor(ctx: ApplicationContext);
32
+ execute(rawRef: string, options?: {
33
+ readonly registry?: string;
34
+ }): Promise<SkillInfo>;
35
+ }
36
+ //# sourceMappingURL=search-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-skills.d.ts","sourceRoot":"","sources":["../../src/application/search-skills.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;gBAE7B,GAAG,EAAE,kBAAkB;IAI7B,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;CA0BxE;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;CAC/C;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;gBAE7B,GAAG,EAAE,kBAAkB;IAI7B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,CAAC;CA+DhG"}
@@ -0,0 +1,78 @@
1
+ import { AgentSkillsError, ErrorCode } from "../domain/errors.js";
2
+ import { parseSkillRef } from "../domain/skill-ref.js";
3
+ import { ListInstalled } from "./list-installed.js";
4
+ export class SearchSkills {
5
+ ctx;
6
+ constructor(ctx) {
7
+ this.ctx = ctx;
8
+ }
9
+ async execute(options) {
10
+ const source = options.registry === undefined
11
+ ? this.ctx.registry
12
+ : this.ctx.registry.named(options.registry);
13
+ if (source === undefined) {
14
+ throw new AgentSkillsError(ErrorCode.REGISTRY_NOT_FOUND, `No registry named "${options.registry}"`, {
15
+ details: [
16
+ '',
17
+ 'Configured registries:',
18
+ ...this.ctx.registry.members().map((member) => ` ${member.name} (${member.kind})`),
19
+ ],
20
+ hints: ['senior-skills registry list'],
21
+ });
22
+ }
23
+ return source.search({
24
+ text: options.query,
25
+ ...(options.limit === undefined ? {} : { limit: options.limit }),
26
+ });
27
+ }
28
+ }
29
+ /**
30
+ * `info` answers "what is this and do I have it?" in one call, which is why it joins registry
31
+ * metadata with local install state rather than making the user run two commands.
32
+ */
33
+ export class DescribeSkill {
34
+ ctx;
35
+ constructor(ctx) {
36
+ this.ctx = ctx;
37
+ }
38
+ async execute(rawRef, options = {}) {
39
+ const ref = parseSkillRef(rawRef);
40
+ const registryName = ref.registry ?? options.registry ?? (await this.ctx.registry.ownerOf(ref.name));
41
+ if (registryName === undefined) {
42
+ throw new AgentSkillsError(ErrorCode.SKILL_NOT_FOUND, `Skill "${ref.name}" was not found in any configured registry`, {
43
+ hints: [`senior-skills search ${ref.name}`, 'senior-skills registry list'],
44
+ data: { name: ref.name },
45
+ });
46
+ }
47
+ const registry = this.ctx.registry.named(registryName);
48
+ if (registry === undefined) {
49
+ throw new AgentSkillsError(ErrorCode.REGISTRY_NOT_FOUND, `No registry named "${registryName}"`);
50
+ }
51
+ const versions = await registry.versions(ref.name);
52
+ if (versions.length === 0) {
53
+ throw new AgentSkillsError(ErrorCode.SKILL_NOT_FOUND, `Skill "${ref.name}" was not found in registry "${registryName}"`, { hints: [`senior-skills search ${ref.name}`], data: { name: ref.name } });
54
+ }
55
+ const selected = ref.range === undefined || ref.range === 'latest'
56
+ ? (versions.find((entry) => !entry.deprecated) ?? versions[0])
57
+ : versions.find((entry) => entry.version === ref.range);
58
+ if (selected === undefined) {
59
+ throw new AgentSkillsError(ErrorCode.VERSION_NOT_FOUND, `${ref.name}@${ref.range} was not found`, {
60
+ details: ['', `Published versions: ${versions.map((entry) => entry.version).join(', ')}`],
61
+ data: { name: ref.name, range: ref.range },
62
+ });
63
+ }
64
+ const list = await new ListInstalled(this.ctx).execute({});
65
+ const installed = list.entries
66
+ .flatMap((entry) => entry.skills)
67
+ .filter((skill) => skill.name === ref.name);
68
+ return {
69
+ name: ref.name,
70
+ registry: registryName,
71
+ manifest: await registry.manifest(ref.name, selected.version),
72
+ versions,
73
+ latest: selected,
74
+ installed,
75
+ };
76
+ }
77
+ }
78
+ //# sourceMappingURL=search-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-skills.js","sourceRoot":"","sources":["../../src/application/search-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { InstallScope } from '../domain/agent.ts';
2
+ import { type SemanticVersion, type VersionBump } from '../domain/version.ts';
3
+ import type { InstallResult } from '../ports/installation.ts';
4
+ import type { ApplicationContext } from './context.ts';
5
+ import { type InstallReport } from './install-skills.ts';
6
+ export interface UpdateOptions {
7
+ /** Empty means "everything installed in this scope". */
8
+ readonly names: readonly string[];
9
+ readonly scope: InstallScope;
10
+ readonly agents?: readonly string[];
11
+ readonly projectRoot?: string;
12
+ readonly startDir?: string;
13
+ readonly registry?: string;
14
+ readonly dryRun?: boolean;
15
+ /**
16
+ * Allow a major-version jump. Without it, update stays within the current major, which is
17
+ * the behaviour people expect from `update` as opposed to `install <name>@latest`.
18
+ */
19
+ readonly major?: boolean;
20
+ readonly force?: boolean;
21
+ /** Include direct suggestions of explicitly named update targets for this invocation. */
22
+ readonly withSuggests?: boolean;
23
+ }
24
+ export interface UpdateChange {
25
+ readonly name: string;
26
+ readonly from: SemanticVersion;
27
+ readonly to: SemanticVersion;
28
+ readonly bump: VersionBump;
29
+ }
30
+ export interface UpdateReport {
31
+ readonly changes: readonly UpdateChange[];
32
+ readonly additions: readonly UpdateAddition[];
33
+ readonly unchanged: readonly string[];
34
+ readonly install: InstallReport;
35
+ }
36
+ export interface UpdateAddition {
37
+ readonly name: string;
38
+ readonly version: SemanticVersion;
39
+ readonly suggestedBy: readonly string[];
40
+ /** New destinations, or empty for a new package skipped everywhere. Dry runs describe the plan. */
41
+ readonly results: readonly InstallResult[];
42
+ }
43
+ /**
44
+ * Update: detect current → resolve newest compatible → install atomically → report the diff.
45
+ *
46
+ * Implemented on top of {@link InstallSkills} rather than beside it. The install pipeline
47
+ * already does fetch/verify/validate/atomic-commit correctly; duplicating it here would mean
48
+ * two places to keep safe.
49
+ */
50
+ export declare class UpdateSkills {
51
+ private readonly ctx;
52
+ constructor(ctx: ApplicationContext);
53
+ execute(options: UpdateOptions): Promise<UpdateReport>;
54
+ }
55
+ //# sourceMappingURL=update-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-skills.d.ts","sourceRoot":"","sources":["../../src/application/update-skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAkB,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAExE,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,yFAAyF;IACzF,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,EAAE,EAAE,eAAe,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,mGAAmG;IACnG,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;gBAE7B,GAAG,EAAE,kBAAkB;IAI7B,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CAkH7D"}