@orthacms/copilot-server 0.0.0-reserve.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 (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/index.d.ts +24 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +48 -0
  6. package/dist/lib/chat/application/appliers-registrar.d.ts +16 -0
  7. package/dist/lib/chat/application/appliers-registrar.d.ts.map +1 -0
  8. package/dist/lib/chat/application/appliers-registrar.js +50 -0
  9. package/dist/lib/chat/application/capability-profile.service.d.ts +43 -0
  10. package/dist/lib/chat/application/capability-profile.service.d.ts.map +1 -0
  11. package/dist/lib/chat/application/capability-profile.service.js +75 -0
  12. package/dist/lib/chat/application/content-type-summary.service.d.ts +32 -0
  13. package/dist/lib/chat/application/content-type-summary.service.d.ts.map +1 -0
  14. package/dist/lib/chat/application/content-type-summary.service.js +64 -0
  15. package/dist/lib/chat/application/decide-proposal.service.d.ts +80 -0
  16. package/dist/lib/chat/application/decide-proposal.service.d.ts.map +1 -0
  17. package/dist/lib/chat/application/decide-proposal.service.js +112 -0
  18. package/dist/lib/chat/application/dto/create-run.dto.d.ts +138 -0
  19. package/dist/lib/chat/application/dto/create-run.dto.d.ts.map +1 -0
  20. package/dist/lib/chat/application/dto/create-run.dto.js +253 -0
  21. package/dist/lib/chat/application/dto/decide-tool-permission.dto.d.ts +20 -0
  22. package/dist/lib/chat/application/dto/decide-tool-permission.dto.d.ts.map +1 -0
  23. package/dist/lib/chat/application/dto/decide-tool-permission.dto.js +44 -0
  24. package/dist/lib/chat/application/dto/extend-tool-permission.dto.d.ts +18 -0
  25. package/dist/lib/chat/application/dto/extend-tool-permission.dto.d.ts.map +1 -0
  26. package/dist/lib/chat/application/dto/extend-tool-permission.dto.js +33 -0
  27. package/dist/lib/chat/application/dto/list-conversations-query.dto.d.ts +18 -0
  28. package/dist/lib/chat/application/dto/list-conversations-query.dto.d.ts.map +1 -0
  29. package/dist/lib/chat/application/dto/list-conversations-query.dto.js +39 -0
  30. package/dist/lib/chat/application/dto/list-proposals-query.dto.d.ts +15 -0
  31. package/dist/lib/chat/application/dto/list-proposals-query.dto.d.ts.map +1 -0
  32. package/dist/lib/chat/application/dto/list-proposals-query.dto.js +41 -0
  33. package/dist/lib/chat/application/dto/update-conversation.dto.d.ts +68 -0
  34. package/dist/lib/chat/application/dto/update-conversation.dto.d.ts.map +1 -0
  35. package/dist/lib/chat/application/dto/update-conversation.dto.js +115 -0
  36. package/dist/lib/chat/application/proposal-applier.registry.d.ts +27 -0
  37. package/dist/lib/chat/application/proposal-applier.registry.d.ts.map +1 -0
  38. package/dist/lib/chat/application/proposal-applier.registry.js +62 -0
  39. package/dist/lib/chat/application/run-engine.service.d.ts +243 -0
  40. package/dist/lib/chat/application/run-engine.service.d.ts.map +1 -0
  41. package/dist/lib/chat/application/run-engine.service.js +1058 -0
  42. package/dist/lib/chat/application/summarize-tool-output.d.ts +15 -0
  43. package/dist/lib/chat/application/summarize-tool-output.d.ts.map +1 -0
  44. package/dist/lib/chat/application/summarize-tool-output.js +61 -0
  45. package/dist/lib/chat/application/system-prompt.d.ts +81 -0
  46. package/dist/lib/chat/application/system-prompt.d.ts.map +1 -0
  47. package/dist/lib/chat/application/system-prompt.js +477 -0
  48. package/dist/lib/chat/application/tool-permission.broker.d.ts +118 -0
  49. package/dist/lib/chat/application/tool-permission.broker.d.ts.map +1 -0
  50. package/dist/lib/chat/application/tool-permission.broker.js +221 -0
  51. package/dist/lib/chat/http/controllers/create-run.controller.d.ts +30 -0
  52. package/dist/lib/chat/http/controllers/create-run.controller.d.ts.map +1 -0
  53. package/dist/lib/chat/http/controllers/create-run.controller.js +159 -0
  54. package/dist/lib/chat/http/controllers/get-conversation.controller.d.ts +22 -0
  55. package/dist/lib/chat/http/controllers/get-conversation.controller.d.ts.map +1 -0
  56. package/dist/lib/chat/http/controllers/get-conversation.controller.js +50 -0
  57. package/dist/lib/chat/http/controllers/list-conversations.controller.d.ts +20 -0
  58. package/dist/lib/chat/http/controllers/list-conversations.controller.d.ts.map +1 -0
  59. package/dist/lib/chat/http/controllers/list-conversations.controller.js +47 -0
  60. package/dist/lib/chat/http/controllers/list-models.controller.d.ts +35 -0
  61. package/dist/lib/chat/http/controllers/list-models.controller.d.ts.map +1 -0
  62. package/dist/lib/chat/http/controllers/list-models.controller.js +48 -0
  63. package/dist/lib/chat/http/controllers/proposals.controller.d.ts +43 -0
  64. package/dist/lib/chat/http/controllers/proposals.controller.d.ts.map +1 -0
  65. package/dist/lib/chat/http/controllers/proposals.controller.js +98 -0
  66. package/dist/lib/chat/http/controllers/tool-permission.controller.d.ts +57 -0
  67. package/dist/lib/chat/http/controllers/tool-permission.controller.d.ts.map +1 -0
  68. package/dist/lib/chat/http/controllers/tool-permission.controller.js +116 -0
  69. package/dist/lib/chat/http/controllers/update-conversation.controller.d.ts +37 -0
  70. package/dist/lib/chat/http/controllers/update-conversation.controller.d.ts.map +1 -0
  71. package/dist/lib/chat/http/controllers/update-conversation.controller.js +108 -0
  72. package/dist/lib/chat/http/sse-stream.d.ts +41 -0
  73. package/dist/lib/chat/http/sse-stream.d.ts.map +1 -0
  74. package/dist/lib/chat/http/sse-stream.js +95 -0
  75. package/dist/lib/chat/infrastructure/persistence/conversation.repository.d.ts +159 -0
  76. package/dist/lib/chat/infrastructure/persistence/conversation.repository.d.ts.map +1 -0
  77. package/dist/lib/chat/infrastructure/persistence/conversation.repository.js +249 -0
  78. package/dist/lib/chat/infrastructure/persistence/derive-title.d.ts +13 -0
  79. package/dist/lib/chat/infrastructure/persistence/derive-title.d.ts.map +1 -0
  80. package/dist/lib/chat/infrastructure/persistence/derive-title.js +35 -0
  81. package/dist/lib/chat/infrastructure/persistence/proposal.repository.d.ts +86 -0
  82. package/dist/lib/chat/infrastructure/persistence/proposal.repository.d.ts.map +1 -0
  83. package/dist/lib/chat/infrastructure/persistence/proposal.repository.js +152 -0
  84. package/dist/lib/chat/infrastructure/schema/conversations.d.ts +189 -0
  85. package/dist/lib/chat/infrastructure/schema/conversations.d.ts.map +1 -0
  86. package/dist/lib/chat/infrastructure/schema/conversations.js +100 -0
  87. package/dist/lib/chat/infrastructure/schema/external-refs.d.ts +67 -0
  88. package/dist/lib/chat/infrastructure/schema/external-refs.d.ts.map +1 -0
  89. package/dist/lib/chat/infrastructure/schema/external-refs.js +28 -0
  90. package/dist/lib/chat/infrastructure/schema/index.d.ts +5 -0
  91. package/dist/lib/chat/infrastructure/schema/index.d.ts.map +1 -0
  92. package/dist/lib/chat/infrastructure/schema/index.js +12 -0
  93. package/dist/lib/chat/infrastructure/schema/messages.d.ts +264 -0
  94. package/dist/lib/chat/infrastructure/schema/messages.d.ts.map +1 -0
  95. package/dist/lib/chat/infrastructure/schema/messages.js +96 -0
  96. package/dist/lib/chat/infrastructure/schema/proposals.d.ts +328 -0
  97. package/dist/lib/chat/infrastructure/schema/proposals.d.ts.map +1 -0
  98. package/dist/lib/chat/infrastructure/schema/proposals.js +87 -0
  99. package/dist/lib/chat/infrastructure/schema/tool-calls.d.ts +203 -0
  100. package/dist/lib/chat/infrastructure/schema/tool-calls.d.ts.map +1 -0
  101. package/dist/lib/chat/infrastructure/schema/tool-calls.js +50 -0
  102. package/dist/lib/copilot.module.d.ts +30 -0
  103. package/dist/lib/copilot.module.d.ts.map +1 -0
  104. package/dist/lib/copilot.module.js +146 -0
  105. package/dist/lib/copilot.tokens.d.ts +34 -0
  106. package/dist/lib/copilot.tokens.d.ts.map +1 -0
  107. package/dist/lib/copilot.tokens.js +38 -0
  108. package/dist/lib/infrastructure/model-registry.d.ts +22 -0
  109. package/dist/lib/infrastructure/model-registry.d.ts.map +1 -0
  110. package/dist/lib/infrastructure/model-registry.js +54 -0
  111. package/dist/lib/skills/application/dto/create-skill.dto.d.ts +36 -0
  112. package/dist/lib/skills/application/dto/create-skill.dto.d.ts.map +1 -0
  113. package/dist/lib/skills/application/dto/create-skill.dto.js +106 -0
  114. package/dist/lib/skills/application/dto/update-skill.dto.d.ts +28 -0
  115. package/dist/lib/skills/application/dto/update-skill.dto.d.ts.map +1 -0
  116. package/dist/lib/skills/application/dto/update-skill.dto.js +96 -0
  117. package/dist/lib/skills/application/skill-catalog.service.d.ts +97 -0
  118. package/dist/lib/skills/application/skill-catalog.service.d.ts.map +1 -0
  119. package/dist/lib/skills/application/skill-catalog.service.js +157 -0
  120. package/dist/lib/skills/http/controllers/list-skills.controller.d.ts +19 -0
  121. package/dist/lib/skills/http/controllers/list-skills.controller.d.ts.map +1 -0
  122. package/dist/lib/skills/http/controllers/list-skills.controller.js +50 -0
  123. package/dist/lib/skills/http/controllers/manage-skills.controller.d.ts +64 -0
  124. package/dist/lib/skills/http/controllers/manage-skills.controller.d.ts.map +1 -0
  125. package/dist/lib/skills/http/controllers/manage-skills.controller.js +182 -0
  126. package/dist/lib/skills/infrastructure/persistence/skill.repository.d.ts +78 -0
  127. package/dist/lib/skills/infrastructure/persistence/skill.repository.d.ts.map +1 -0
  128. package/dist/lib/skills/infrastructure/persistence/skill.repository.js +116 -0
  129. package/dist/lib/skills/infrastructure/schema/index.d.ts +2 -0
  130. package/dist/lib/skills/infrastructure/schema/index.d.ts.map +1 -0
  131. package/dist/lib/skills/infrastructure/schema/index.js +6 -0
  132. package/dist/lib/skills/infrastructure/schema/skills.d.ts +212 -0
  133. package/dist/lib/skills/infrastructure/schema/skills.d.ts.map +1 -0
  134. package/dist/lib/skills/infrastructure/schema/skills.js +78 -0
  135. package/dist/lib/types/copilot-config.d.ts +55 -0
  136. package/dist/lib/types/copilot-config.d.ts.map +1 -0
  137. package/dist/lib/types/copilot-config.js +2 -0
  138. package/dist/lib/utils/copilot-plugin.d.ts +66 -0
  139. package/dist/lib/utils/copilot-plugin.d.ts.map +1 -0
  140. package/dist/lib/utils/copilot-plugin.js +87 -0
  141. package/migrations/0000_copilot_chat.sql +48 -0
  142. package/migrations/0001_proposals.sql +34 -0
  143. package/migrations/0002_drop_workspace_policies.sql +1 -0
  144. package/migrations/0003_conversation_allowed_tools.sql +1 -0
  145. package/migrations/0004_message_attachments.sql +1 -0
  146. package/migrations/0005_skills.sql +19 -0
  147. package/migrations/0006_conversation_model_choice.sql +1 -0
  148. package/migrations/meta/0000_snapshot.json +390 -0
  149. package/migrations/meta/0001_snapshot.json +657 -0
  150. package/migrations/meta/0002_snapshot.json +610 -0
  151. package/migrations/meta/0003_snapshot.json +617 -0
  152. package/migrations/meta/0004_snapshot.json +623 -0
  153. package/migrations/meta/0005_snapshot.json +771 -0
  154. package/migrations/meta/0006_snapshot.json +777 -0
  155. package/migrations/meta/_journal.json +55 -0
  156. package/package.json +46 -0
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildModelRegistry = buildModelRegistry;
4
+ const copilot_domain_1 = require("@orthacms/copilot-domain");
5
+ /**
6
+ * Builds an immutable {@link ModelRegistry} over the host's provider list.
7
+ * Bound to `MODEL_REGISTRY` at the composition root; the resolver returns a
8
+ * name, the core looks the provider up here.
9
+ *
10
+ * Registration order is preserved, so {@link ModelRegistry.catalogue} renders
11
+ * in the order the operator wrote — the first entry reads as the house default.
12
+ *
13
+ * @throws When a name is blank or registered twice. A list can express both,
14
+ * unlike a map, so the guard has to be explicit — and silently dropping one
15
+ * of two same-named providers would route runs to a backend nobody chose.
16
+ */
17
+ function buildModelRegistry(registrations) {
18
+ // Snapshot into a **null-prototype** object so a later mutation of the
19
+ // host's list can't reroute a run mid-flight, and a lookup of
20
+ // `constructor`/`toString` misses instead of resolving something off
21
+ // `Object.prototype` that is not a provider.
22
+ const entries = Object.create(null);
23
+ const order = [];
24
+ for (const { name, provider } of registrations) {
25
+ if (!name.trim()) {
26
+ throw new Error('Every copilot model provider needs a non-empty name — it is what a run, and a resolver, refer to it by.');
27
+ }
28
+ if (Object.prototype.hasOwnProperty.call(entries, name)) {
29
+ throw new Error(`Duplicate copilot model provider name "${name}". Names must be unique across the provider list.`);
30
+ }
31
+ entries[name] = provider;
32
+ order.push(name);
33
+ }
34
+ return {
35
+ get(name) {
36
+ const provider = entries[name];
37
+ if (!provider) {
38
+ throw new copilot_domain_1.UnknownModelProviderError(name, [...order]);
39
+ }
40
+ return provider;
41
+ },
42
+ has(name) {
43
+ return Object.prototype.hasOwnProperty.call(entries, name);
44
+ },
45
+ names() {
46
+ return [...order];
47
+ },
48
+ catalogue() {
49
+ return order.flatMap((name) => entries[name]
50
+ .models()
51
+ .map((model) => ({ provider: name, model })));
52
+ }
53
+ };
54
+ }
@@ -0,0 +1,36 @@
1
+ import { type SkillMode } from '@orthacms/copilot-domain';
2
+ /** The two modes, as a value the strict pipe can check against. */
3
+ export declare const SKILL_MODES: readonly SkillMode[];
4
+ /**
5
+ * Body of `POST /api/copilot/skills`.
6
+ *
7
+ * The bounds come from `@orthacms/copilot-domain` rather than being repeated
8
+ * here, because the same numbers govern the host's boot-time validation of
9
+ * code-defined skills — one set of limits, whichever way a skill was written.
10
+ */
11
+ export declare class CreateSkillDto {
12
+ /**
13
+ * Machine name. Refused if the workspace, or a code-defined skill, already
14
+ * holds it — a name resolves to exactly one body or the model's
15
+ * instructions become a matter of row order.
16
+ */
17
+ name: string;
18
+ /** What a person reads in the picker and on a chip. */
19
+ title: string;
20
+ /**
21
+ * When to use it, written for the model — and **required**. It is the only
22
+ * thing in the prompt for a skill nobody has attached, so a skill without
23
+ * one exists but can never be found.
24
+ */
25
+ description: string;
26
+ /**
27
+ * The body — prompt text, not content. Bounded because it is spent from the
28
+ * same context window the conversation and the tool results come out of.
29
+ */
30
+ instructions: string;
31
+ /** `always` puts it in force on every run in the workspace. */
32
+ mode?: SkillMode;
33
+ /** Defaults to on. */
34
+ enabled?: boolean;
35
+ }
36
+ //# sourceMappingURL=create-skill.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-skill.dto.d.ts","sourceRoot":"","sources":["../../../../../src/lib/skills/application/dto/create-skill.dto.ts"],"names":[],"mappings":"AAWA,OAAO,EAMH,KAAK,SAAS,EACjB,MAAM,0BAA0B,CAAC;AAElC,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAAyB,CAAC;AAQtE;;;;;;GAMG;AACH,qBAAa,cAAc;IACvB;;;;OAIG;IAcH,IAAI,EAAG,MAAM,CAAC;IAEd,uDAAuD;IAUvD,KAAK,EAAG,MAAM,CAAC;IAEf;;;;OAIG;IAUH,WAAW,EAAG,MAAM,CAAC;IAErB;;;OAGG;IAQH,YAAY,EAAG,MAAM,CAAC;IAEtB,+DAA+D;IAI/D,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB,sBAAsB;IAItB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateSkillDto = exports.SKILL_MODES = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const swagger_1 = require("@nestjs/swagger");
6
+ const class_transformer_1 = require("class-transformer");
7
+ const class_validator_1 = require("class-validator");
8
+ const copilot_domain_1 = require("@orthacms/copilot-domain");
9
+ /** The two modes, as a value the strict pipe can check against. */
10
+ exports.SKILL_MODES = ['manual', 'always'];
11
+ /** Trims a string value during transformation, before the validators run. */
12
+ const trimmed = () => (0, class_transformer_1.Transform)(({ value }) => typeof value === 'string' ? value.trim() : value);
13
+ /**
14
+ * Body of `POST /api/copilot/skills`.
15
+ *
16
+ * The bounds come from `@orthacms/copilot-domain` rather than being repeated
17
+ * here, because the same numbers govern the host's boot-time validation of
18
+ * code-defined skills — one set of limits, whichever way a skill was written.
19
+ */
20
+ class CreateSkillDto {
21
+ /**
22
+ * Machine name. Refused if the workspace, or a code-defined skill, already
23
+ * holds it — a name resolves to exactly one body or the model's
24
+ * instructions become a matter of row order.
25
+ */
26
+ name;
27
+ /** What a person reads in the picker and on a chip. */
28
+ title;
29
+ /**
30
+ * When to use it, written for the model — and **required**. It is the only
31
+ * thing in the prompt for a skill nobody has attached, so a skill without
32
+ * one exists but can never be found.
33
+ */
34
+ description;
35
+ /**
36
+ * The body — prompt text, not content. Bounded because it is spent from the
37
+ * same context window the conversation and the tool results come out of.
38
+ */
39
+ instructions;
40
+ /** `always` puts it in force on every run in the workspace. */
41
+ mode;
42
+ /** Defaults to on. */
43
+ enabled;
44
+ }
45
+ exports.CreateSkillDto = CreateSkillDto;
46
+ tslib_1.__decorate([
47
+ (0, swagger_1.ApiProperty)({
48
+ type: String,
49
+ maxLength: copilot_domain_1.MAX_SKILL_NAME_LENGTH,
50
+ pattern: copilot_domain_1.SKILL_NAME_PATTERN.source,
51
+ example: 'house-style'
52
+ }),
53
+ trimmed(),
54
+ (0, class_validator_1.IsString)(),
55
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_NAME_LENGTH),
56
+ (0, class_validator_1.Matches)(copilot_domain_1.SKILL_NAME_PATTERN, {
57
+ message: 'name must be lowercase letters, digits and hyphens, e.g. "house-style"'
58
+ }),
59
+ tslib_1.__metadata("design:type", String)
60
+ ], CreateSkillDto.prototype, "name", void 0);
61
+ tslib_1.__decorate([
62
+ (0, swagger_1.ApiProperty)({
63
+ type: String,
64
+ maxLength: copilot_domain_1.MAX_SKILL_TITLE_LENGTH,
65
+ example: 'House style'
66
+ }),
67
+ trimmed(),
68
+ (0, class_validator_1.IsString)(),
69
+ (0, class_validator_1.MinLength)(1),
70
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_TITLE_LENGTH),
71
+ tslib_1.__metadata("design:type", String)
72
+ ], CreateSkillDto.prototype, "title", void 0);
73
+ tslib_1.__decorate([
74
+ (0, swagger_1.ApiProperty)({
75
+ type: String,
76
+ maxLength: copilot_domain_1.MAX_SKILL_DESCRIPTION_LENGTH,
77
+ example: 'How we write product copy: sentence case, second person.'
78
+ }),
79
+ trimmed(),
80
+ (0, class_validator_1.IsString)(),
81
+ (0, class_validator_1.MinLength)(1),
82
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_DESCRIPTION_LENGTH),
83
+ tslib_1.__metadata("design:type", String)
84
+ ], CreateSkillDto.prototype, "description", void 0);
85
+ tslib_1.__decorate([
86
+ (0, swagger_1.ApiProperty)({
87
+ type: String,
88
+ maxLength: copilot_domain_1.MAX_SKILL_INSTRUCTIONS_LENGTH
89
+ }),
90
+ (0, class_validator_1.IsString)(),
91
+ (0, class_validator_1.MinLength)(1),
92
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_INSTRUCTIONS_LENGTH),
93
+ tslib_1.__metadata("design:type", String)
94
+ ], CreateSkillDto.prototype, "instructions", void 0);
95
+ tslib_1.__decorate([
96
+ (0, swagger_1.ApiPropertyOptional)({ enum: exports.SKILL_MODES, default: 'manual' }),
97
+ (0, class_validator_1.IsOptional)(),
98
+ (0, class_validator_1.IsIn)(exports.SKILL_MODES),
99
+ tslib_1.__metadata("design:type", String)
100
+ ], CreateSkillDto.prototype, "mode", void 0);
101
+ tslib_1.__decorate([
102
+ (0, swagger_1.ApiPropertyOptional)({ type: Boolean, default: true }),
103
+ (0, class_validator_1.IsOptional)(),
104
+ (0, class_validator_1.IsBoolean)(),
105
+ tslib_1.__metadata("design:type", Boolean)
106
+ ], CreateSkillDto.prototype, "enabled", void 0);
@@ -0,0 +1,28 @@
1
+ import { type SkillMode } from '@orthacms/copilot-domain';
2
+ /**
3
+ * Body of `PATCH /api/copilot/skills/:id`.
4
+ *
5
+ * A **patch**: every property is optional and only the ones present are
6
+ * written. The controller rejects an empty body — answering 200 to it would
7
+ * report success for a write that never happened.
8
+ *
9
+ * Not `PartialType(CreateSkillDto)`: the generated class would inherit whatever
10
+ * `CreateSkillDto` grows later, and this endpoint deliberately does not accept
11
+ * everything a create does (there is no `workspaceId` to move a skill between
12
+ * workspaces with, and there never should be).
13
+ */
14
+ export declare class UpdateSkillDto {
15
+ /** Rename. Refused if the new name is taken, by either source. */
16
+ name?: string;
17
+ /** New display title. */
18
+ title?: string;
19
+ /** New description. */
20
+ description?: string;
21
+ /** New body. */
22
+ instructions?: string;
23
+ /** Switch between always-on and attach-to-use. */
24
+ mode?: SkillMode;
25
+ /** Turn the skill off without deleting it. */
26
+ enabled?: boolean;
27
+ }
28
+ //# sourceMappingURL=update-skill.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-skill.dto.d.ts","sourceRoot":"","sources":["../../../../../src/lib/skills/application/dto/update-skill.dto.ts"],"names":[],"mappings":"AAWA,OAAO,EAMH,KAAK,SAAS,EACjB,MAAM,0BAA0B,CAAC;AAQlC;;;;;;;;;;;GAWG;AACH,qBAAa,cAAc;IACvB,kEAAkE;IAclE,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,yBAAyB;IAOzB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,uBAAuB;IAUvB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,gBAAgB;IAShB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,kDAAkD;IAIlD,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB,8CAA8C;IAI9C,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UpdateSkillDto = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const swagger_1 = require("@nestjs/swagger");
6
+ const class_transformer_1 = require("class-transformer");
7
+ const class_validator_1 = require("class-validator");
8
+ const copilot_domain_1 = require("@orthacms/copilot-domain");
9
+ const create_skill_dto_1 = require("./create-skill.dto");
10
+ const trimmed = () => (0, class_transformer_1.Transform)(({ value }) => typeof value === 'string' ? value.trim() : value);
11
+ /**
12
+ * Body of `PATCH /api/copilot/skills/:id`.
13
+ *
14
+ * A **patch**: every property is optional and only the ones present are
15
+ * written. The controller rejects an empty body — answering 200 to it would
16
+ * report success for a write that never happened.
17
+ *
18
+ * Not `PartialType(CreateSkillDto)`: the generated class would inherit whatever
19
+ * `CreateSkillDto` grows later, and this endpoint deliberately does not accept
20
+ * everything a create does (there is no `workspaceId` to move a skill between
21
+ * workspaces with, and there never should be).
22
+ */
23
+ class UpdateSkillDto {
24
+ /** Rename. Refused if the new name is taken, by either source. */
25
+ name;
26
+ /** New display title. */
27
+ title;
28
+ /** New description. */
29
+ description;
30
+ /** New body. */
31
+ instructions;
32
+ /** Switch between always-on and attach-to-use. */
33
+ mode;
34
+ /** Turn the skill off without deleting it. */
35
+ enabled;
36
+ }
37
+ exports.UpdateSkillDto = UpdateSkillDto;
38
+ tslib_1.__decorate([
39
+ (0, swagger_1.ApiPropertyOptional)({
40
+ type: String,
41
+ maxLength: copilot_domain_1.MAX_SKILL_NAME_LENGTH,
42
+ pattern: copilot_domain_1.SKILL_NAME_PATTERN.source
43
+ }),
44
+ (0, class_validator_1.IsOptional)(),
45
+ trimmed(),
46
+ (0, class_validator_1.IsString)(),
47
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_NAME_LENGTH),
48
+ (0, class_validator_1.Matches)(copilot_domain_1.SKILL_NAME_PATTERN, {
49
+ message: 'name must be lowercase letters, digits and hyphens, e.g. "house-style"'
50
+ }),
51
+ tslib_1.__metadata("design:type", String)
52
+ ], UpdateSkillDto.prototype, "name", void 0);
53
+ tslib_1.__decorate([
54
+ (0, swagger_1.ApiPropertyOptional)({ type: String, maxLength: copilot_domain_1.MAX_SKILL_TITLE_LENGTH }),
55
+ (0, class_validator_1.IsOptional)(),
56
+ trimmed(),
57
+ (0, class_validator_1.IsString)(),
58
+ (0, class_validator_1.MinLength)(1),
59
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_TITLE_LENGTH),
60
+ tslib_1.__metadata("design:type", String)
61
+ ], UpdateSkillDto.prototype, "title", void 0);
62
+ tslib_1.__decorate([
63
+ (0, swagger_1.ApiPropertyOptional)({
64
+ type: String,
65
+ maxLength: copilot_domain_1.MAX_SKILL_DESCRIPTION_LENGTH
66
+ }),
67
+ (0, class_validator_1.IsOptional)(),
68
+ trimmed(),
69
+ (0, class_validator_1.IsString)(),
70
+ (0, class_validator_1.MinLength)(1),
71
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_DESCRIPTION_LENGTH),
72
+ tslib_1.__metadata("design:type", String)
73
+ ], UpdateSkillDto.prototype, "description", void 0);
74
+ tslib_1.__decorate([
75
+ (0, swagger_1.ApiPropertyOptional)({
76
+ type: String,
77
+ maxLength: copilot_domain_1.MAX_SKILL_INSTRUCTIONS_LENGTH
78
+ }),
79
+ (0, class_validator_1.IsOptional)(),
80
+ (0, class_validator_1.IsString)(),
81
+ (0, class_validator_1.MinLength)(1),
82
+ (0, class_validator_1.MaxLength)(copilot_domain_1.MAX_SKILL_INSTRUCTIONS_LENGTH),
83
+ tslib_1.__metadata("design:type", String)
84
+ ], UpdateSkillDto.prototype, "instructions", void 0);
85
+ tslib_1.__decorate([
86
+ (0, swagger_1.ApiPropertyOptional)({ enum: create_skill_dto_1.SKILL_MODES }),
87
+ (0, class_validator_1.IsOptional)(),
88
+ (0, class_validator_1.IsIn)(create_skill_dto_1.SKILL_MODES),
89
+ tslib_1.__metadata("design:type", String)
90
+ ], UpdateSkillDto.prototype, "mode", void 0);
91
+ tslib_1.__decorate([
92
+ (0, swagger_1.ApiPropertyOptional)({ type: Boolean }),
93
+ (0, class_validator_1.IsOptional)(),
94
+ (0, class_validator_1.IsBoolean)(),
95
+ tslib_1.__metadata("design:type", Boolean)
96
+ ], UpdateSkillDto.prototype, "enabled", void 0);
@@ -0,0 +1,97 @@
1
+ import { type Skill, type SkillRegistry } from '@orthacms/copilot-domain';
2
+ import { SkillRepository } from '../infrastructure/persistence/skill.repository';
3
+ /**
4
+ * A skill as the picker and the manage page render it — **never** carrying
5
+ * `instructions`.
6
+ *
7
+ * The body is withheld from the list on purpose. Everyone with `copilot:use`
8
+ * can read this route, and while a skill's text is not a secret, it is also not
9
+ * something a picker needs: shipping it would put an 8 000-character body per
10
+ * skill into a request the composer makes on every mount. The manage page,
11
+ * which does need it, reads one skill at a time behind
12
+ * `copilot:skills:manage`.
13
+ */
14
+ export interface SkillSummary {
15
+ /** Row id for a CMS skill; `null` for a code-defined one, which has none. */
16
+ id: string | null;
17
+ name: string;
18
+ title: string;
19
+ description: string;
20
+ mode: Skill['mode'];
21
+ source: Skill['source'];
22
+ /** Always true in the run catalogue; the manage list shows both. */
23
+ enabled: boolean;
24
+ /**
25
+ * Whether this deployment lets the skill be edited here. False for code
26
+ * skills, so the manage page can render them read-only rather than
27
+ * offering a form whose save is refused.
28
+ */
29
+ editable: boolean;
30
+ }
31
+ /** Thrown when a run names skills that do not resolve in its workspace. */
32
+ export declare class SkillResolutionError extends Error {
33
+ constructor(message: string);
34
+ }
35
+ /**
36
+ * The one place the two sources of skills become one catalogue.
37
+ *
38
+ * Code skills come from the registry the host built at boot; CMS skills come
39
+ * from this workspace's rows. `mergeSkills` decides collisions (code wins), and
40
+ * everything downstream — the picker, the prompt, the run resolver — reads the
41
+ * merged view rather than either source.
42
+ */
43
+ export declare class SkillCatalogService {
44
+ private readonly registry;
45
+ private readonly repository;
46
+ constructor(registry: SkillRegistry, repository: SkillRepository);
47
+ /**
48
+ * Every skill a run in this workspace could use: the deployment's code
49
+ * skills plus the workspace's **enabled** rows.
50
+ */
51
+ available(workspaceId: string): Promise<Skill[]>;
52
+ /** The picker's view — the available catalogue, without the bodies. */
53
+ catalogue(workspaceId: string): Promise<SkillSummary[]>;
54
+ /**
55
+ * The manage page's view — code skills (read-only) and **every** CMS row,
56
+ * disabled ones included.
57
+ *
58
+ * A shadowed row is still listed, because the manage page is the only place
59
+ * anyone could discover that a deploy has taken its name over; hiding it
60
+ * would leave an admin editing a skill that silently never runs.
61
+ */
62
+ manageList(workspaceId: string): Promise<SkillSummary[]>;
63
+ /** Whether a name is already taken in this workspace, by either source. */
64
+ nameTaken(name: string, workspaceId: string, exceptId?: string): Promise<'code' | 'cms' | null>;
65
+ /**
66
+ * What one run needs to know about skills: everything the workspace offers,
67
+ * and the subset in force.
68
+ *
69
+ * Both together in one call because the prompt needs both and they come
70
+ * from the same query — the bodies of the active ones, and one line each
71
+ * for the rest so the model can recommend one it was not given.
72
+ */
73
+ resolveRunSkills(workspaceId: string, requested: readonly string[]): Promise<{
74
+ available: Skill[];
75
+ inForce: Skill[];
76
+ }>;
77
+ /**
78
+ * The skills one run actually runs with: the workspace's always-on skills,
79
+ * then the ones the person attached, de-duplicated.
80
+ *
81
+ * **Always-on first.** They are the workspace's standing instructions and
82
+ * an attached skill is the specific request on top of them, so the specific
83
+ * one reads last — closest to the message, which is where a model resolves
84
+ * a conflict in its favour.
85
+ *
86
+ * @throws {SkillResolutionError} When a requested name does not resolve.
87
+ * The message names a **count**, never which name: this resolver is
88
+ * workspace-scoped, so "belongs to another workspace" and "was just
89
+ * deleted" are indistinguishable here, and saying which would turn the one
90
+ * place a caller picks names into an oracle for other workspaces' skills.
91
+ * Same rule the attachment resolver follows.
92
+ */
93
+ resolveForRun(workspaceId: string, requested: readonly string[]): Promise<Skill[]>;
94
+ /** The pure half of {@link resolveForRun}, over an already-loaded catalogue. */
95
+ private selectInForce;
96
+ }
97
+ //# sourceMappingURL=skill-catalog.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-catalog.service.d.ts","sourceRoot":"","sources":["../../../../src/lib/skills/application/skill-catalog.service.ts"],"names":[],"mappings":"AACA,OAAO,EAEH,KAAK,KAAK,EACV,KAAK,aAAa,EACrB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACH,eAAe,EAElB,MAAM,gDAAgD,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IACzB,6EAA6E;IAC7E,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxB,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,2EAA2E;AAC3E,qBAAa,oBAAqB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI9B;AAED;;;;;;;GAOG;AACH,qBACa,mBAAmB;IAGxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,QAAQ,EAAE,aAAa,EACvB,UAAU,EAAE,eAAe;IAGhD;;;OAGG;IACG,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAKtD,uEAAuE;IACjE,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAQ7D;;;;;;;OAOG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAmB9D,2EAA2E;IACrE,SAAS,CACX,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;IAWjC;;;;;;;OAOG;IACG,gBAAgB,CAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC;QAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QAAC,OAAO,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IAQpD;;;;;;;;;;;;;;;OAeG;IACG,aAAa,CACf,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,KAAK,EAAE,CAAC;IAInB,gFAAgF;IAChF,OAAO,CAAC,aAAa;CA+BxB"}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SkillCatalogService = exports.SkillResolutionError = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const copilot_domain_1 = require("@orthacms/copilot-domain");
7
+ const copilot_tokens_1 = require("../../copilot.tokens");
8
+ const skill_repository_1 = require("../infrastructure/persistence/skill.repository");
9
+ /** Thrown when a run names skills that do not resolve in its workspace. */
10
+ class SkillResolutionError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = 'SkillResolutionError';
14
+ }
15
+ }
16
+ exports.SkillResolutionError = SkillResolutionError;
17
+ /**
18
+ * The one place the two sources of skills become one catalogue.
19
+ *
20
+ * Code skills come from the registry the host built at boot; CMS skills come
21
+ * from this workspace's rows. `mergeSkills` decides collisions (code wins), and
22
+ * everything downstream — the picker, the prompt, the run resolver — reads the
23
+ * merged view rather than either source.
24
+ */
25
+ let SkillCatalogService = class SkillCatalogService {
26
+ registry;
27
+ repository;
28
+ constructor(registry, repository) {
29
+ this.registry = registry;
30
+ this.repository = repository;
31
+ }
32
+ /**
33
+ * Every skill a run in this workspace could use: the deployment's code
34
+ * skills plus the workspace's **enabled** rows.
35
+ */
36
+ async available(workspaceId) {
37
+ const rows = await this.repository.list(workspaceId, true);
38
+ return (0, copilot_domain_1.mergeSkills)(this.registry.all(), rows);
39
+ }
40
+ /** The picker's view — the available catalogue, without the bodies. */
41
+ async catalogue(workspaceId) {
42
+ const rows = await this.repository.list(workspaceId, true);
43
+ const byName = new Map(rows.map((row) => [row.name, row]));
44
+ return (0, copilot_domain_1.mergeSkills)(this.registry.all(), rows).map((skill) => toSummary(skill, byName.get(skill.name) ?? null, true));
45
+ }
46
+ /**
47
+ * The manage page's view — code skills (read-only) and **every** CMS row,
48
+ * disabled ones included.
49
+ *
50
+ * A shadowed row is still listed, because the manage page is the only place
51
+ * anyone could discover that a deploy has taken its name over; hiding it
52
+ * would leave an admin editing a skill that silently never runs.
53
+ */
54
+ async manageList(workspaceId) {
55
+ const rows = await this.repository.list(workspaceId);
56
+ const shadowed = new Set(rows
57
+ .filter((row) => this.registry.has(row.name))
58
+ .map((row) => row.name));
59
+ return [
60
+ ...this.registry.all().map((skill) => toSummary(skill, null, true)),
61
+ ...rows.map((row) => ({
62
+ ...toSummary(row, row, row.enabled),
63
+ // A shadowed row can be edited (renaming it is the fix) but is
64
+ // reported as not enabled, because it is not: the code skill
65
+ // holds the name and this row never reaches a run.
66
+ enabled: row.enabled && !shadowed.has(row.name)
67
+ }))
68
+ ];
69
+ }
70
+ /** Whether a name is already taken in this workspace, by either source. */
71
+ async nameTaken(name, workspaceId, exceptId) {
72
+ if (this.registry.has(name)) {
73
+ return 'code';
74
+ }
75
+ const existing = await this.repository.findByName(name, workspaceId);
76
+ if (existing && existing.id !== exceptId) {
77
+ return 'cms';
78
+ }
79
+ return null;
80
+ }
81
+ /**
82
+ * What one run needs to know about skills: everything the workspace offers,
83
+ * and the subset in force.
84
+ *
85
+ * Both together in one call because the prompt needs both and they come
86
+ * from the same query — the bodies of the active ones, and one line each
87
+ * for the rest so the model can recommend one it was not given.
88
+ */
89
+ async resolveRunSkills(workspaceId, requested) {
90
+ const available = await this.available(workspaceId);
91
+ return {
92
+ available,
93
+ inForce: this.selectInForce(available, requested)
94
+ };
95
+ }
96
+ /**
97
+ * The skills one run actually runs with: the workspace's always-on skills,
98
+ * then the ones the person attached, de-duplicated.
99
+ *
100
+ * **Always-on first.** They are the workspace's standing instructions and
101
+ * an attached skill is the specific request on top of them, so the specific
102
+ * one reads last — closest to the message, which is where a model resolves
103
+ * a conflict in its favour.
104
+ *
105
+ * @throws {SkillResolutionError} When a requested name does not resolve.
106
+ * The message names a **count**, never which name: this resolver is
107
+ * workspace-scoped, so "belongs to another workspace" and "was just
108
+ * deleted" are indistinguishable here, and saying which would turn the one
109
+ * place a caller picks names into an oracle for other workspaces' skills.
110
+ * Same rule the attachment resolver follows.
111
+ */
112
+ async resolveForRun(workspaceId, requested) {
113
+ return this.selectInForce(await this.available(workspaceId), requested);
114
+ }
115
+ /** The pure half of {@link resolveForRun}, over an already-loaded catalogue. */
116
+ selectInForce(available, requested) {
117
+ const always = available.filter((skill) => skill.mode === 'always');
118
+ if (requested.length === 0) {
119
+ return always;
120
+ }
121
+ const byName = new Map(available.map((skill) => [skill.name, skill]));
122
+ const unique = [...new Set(requested)];
123
+ const attached = unique
124
+ .map((name) => byName.get(name))
125
+ .filter((skill) => skill !== undefined);
126
+ if (attached.length !== unique.length) {
127
+ const missing = unique.length - attached.length;
128
+ throw new SkillResolutionError(missing === 1
129
+ ? 'One of the selected skills is no longer available.'
130
+ : `${missing} of the selected skills are no longer available.`);
131
+ }
132
+ const seen = new Set(always.map((skill) => skill.name));
133
+ return [
134
+ ...always,
135
+ ...attached.filter((skill) => !seen.has(skill.name))
136
+ ];
137
+ }
138
+ };
139
+ exports.SkillCatalogService = SkillCatalogService;
140
+ exports.SkillCatalogService = SkillCatalogService = tslib_1.__decorate([
141
+ (0, common_1.Injectable)(),
142
+ tslib_1.__param(0, (0, common_1.Inject)(copilot_tokens_1.COPILOT_SKILL_REGISTRY)),
143
+ tslib_1.__metadata("design:paramtypes", [Object, skill_repository_1.SkillRepository])
144
+ ], SkillCatalogService);
145
+ /** The list view of a skill, with its row id when it has one. */
146
+ function toSummary(skill, row, enabled) {
147
+ return {
148
+ id: row?.id ?? null,
149
+ name: skill.name,
150
+ title: skill.title,
151
+ description: skill.description,
152
+ mode: skill.mode,
153
+ source: skill.source,
154
+ enabled,
155
+ editable: skill.source === 'cms'
156
+ };
157
+ }
@@ -0,0 +1,19 @@
1
+ import { SkillCatalogService, type SkillSummary } from '../../application/skill-catalog.service';
2
+ /**
3
+ * `GET /api/copilot/skills` — the catalogue the composer's picker renders.
4
+ *
5
+ * Gated on `copilot:use`, not on the manage permission: everybody who can chat
6
+ * can attach a skill, and a picker that showed nothing to a contributor would
7
+ * make the feature invisible to the people it is mostly for. What it does
8
+ * **not** carry is `instructions` — see `SkillSummary` for why.
9
+ *
10
+ * `WorkspaceGuard` because the catalogue differs per workspace: code skills are
11
+ * deployment-wide, CMS skills are not, and serving the union to an unvalidated
12
+ * workspace id would leak one workspace's editorial guidance to another.
13
+ */
14
+ export declare class ListSkillsController {
15
+ private readonly catalog;
16
+ constructor(catalog: SkillCatalogService);
17
+ list(workspaceId: string): Promise<SkillSummary[]>;
18
+ }
19
+ //# sourceMappingURL=list-skills.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-skills.controller.d.ts","sourceRoot":"","sources":["../../../../../src/lib/skills/http/controllers/list-skills.controller.ts"],"names":[],"mappings":"AAQA,OAAO,EACH,mBAAmB,EACnB,KAAK,YAAY,EACpB,MAAM,yCAAyC,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,qBAGa,oBAAoB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,mBAAmB;IAUnD,IAAI,CACc,WAAW,EAAE,MAAM,GACxC,OAAO,CAAC,YAAY,EAAE,CAAC;CAG7B"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListSkillsController = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const swagger_1 = require("@nestjs/swagger");
7
+ const identity_server_1 = require("@orthacms/identity-server");
8
+ const workspaces_server_1 = require("@orthacms/workspaces-server");
9
+ const skill_catalog_service_1 = require("../../application/skill-catalog.service");
10
+ /**
11
+ * `GET /api/copilot/skills` — the catalogue the composer's picker renders.
12
+ *
13
+ * Gated on `copilot:use`, not on the manage permission: everybody who can chat
14
+ * can attach a skill, and a picker that showed nothing to a contributor would
15
+ * make the feature invisible to the people it is mostly for. What it does
16
+ * **not** carry is `instructions` — see `SkillSummary` for why.
17
+ *
18
+ * `WorkspaceGuard` because the catalogue differs per workspace: code skills are
19
+ * deployment-wide, CMS skills are not, and serving the union to an unvalidated
20
+ * workspace id would leak one workspace's editorial guidance to another.
21
+ */
22
+ let ListSkillsController = class ListSkillsController {
23
+ catalog;
24
+ constructor(catalog) {
25
+ this.catalog = catalog;
26
+ }
27
+ async list(workspaceId) {
28
+ return this.catalog.catalogue(workspaceId);
29
+ }
30
+ };
31
+ exports.ListSkillsController = ListSkillsController;
32
+ tslib_1.__decorate([
33
+ (0, common_1.Get)('skills'),
34
+ (0, swagger_1.ApiOperation)({
35
+ summary: 'List the skills available in this workspace',
36
+ description: 'Code-defined skills first, then the workspace’s own enabled ones. ' +
37
+ 'Instruction bodies are not included.'
38
+ }),
39
+ (0, swagger_1.ApiResponse)({ status: 200, description: 'The available skills.' }),
40
+ tslib_1.__param(0, (0, workspaces_server_1.CurrentWorkspace)()),
41
+ tslib_1.__metadata("design:type", Function),
42
+ tslib_1.__metadata("design:paramtypes", [String]),
43
+ tslib_1.__metadata("design:returntype", Promise)
44
+ ], ListSkillsController.prototype, "list", null);
45
+ exports.ListSkillsController = ListSkillsController = tslib_1.__decorate([
46
+ (0, common_1.UseGuards)(identity_server_1.PermissionsGuard, workspaces_server_1.WorkspaceGuard),
47
+ (0, identity_server_1.RequirePermissions)(identity_server_1.PERMISSIONS.COPILOT_USE),
48
+ (0, common_1.Controller)('copilot'),
49
+ tslib_1.__metadata("design:paramtypes", [skill_catalog_service_1.SkillCatalogService])
50
+ ], ListSkillsController);