@v587d/capital-generation 2.9.2 → 2.10.1

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 (57) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +8 -5
  3. package/chart-ui/package.json +1 -1
  4. package/config/client.js +8 -6
  5. package/config/client.src.cjs +74 -34
  6. package/config/index.js +8 -2
  7. package/config/package.json +1 -1
  8. package/lib/agents/selected-skills-provider.d.ts +29 -10
  9. package/lib/agents/selected-skills-provider.js +262 -139
  10. package/lib/agents/settled-wake.d.ts +43 -0
  11. package/lib/agents/settled-wake.js +81 -0
  12. package/lib/agents/skill-usage.d.ts +22 -0
  13. package/lib/agents/skill-usage.js +92 -0
  14. package/lib/agents/wait-for-agents.d.ts +79 -0
  15. package/lib/agents/wait-for-agents.js +256 -0
  16. package/lib/capital-settings.d.ts +12 -1
  17. package/lib/capital-settings.js +23 -3
  18. package/lib/chart/artifact-ref.d.ts +4 -1
  19. package/lib/chart/artifact-ref.js +2 -1
  20. package/lib/chart/delivery.d.ts +15 -1
  21. package/lib/chart/delivery.js +17 -8
  22. package/lib/chart/events.d.ts +1 -1
  23. package/lib/chart/html.js +16 -0
  24. package/lib/chart/present-tool.js +52 -3
  25. package/lib/chart/tool.js +63 -9
  26. package/lib/data-collector/store.d.ts +1 -0
  27. package/lib/data-collector/store.js +2 -2
  28. package/lib/index.d.ts +6 -3
  29. package/lib/index.js +10 -19
  30. package/lib/orchestration-entry.d.ts +11 -0
  31. package/lib/orchestration-entry.js +6 -0
  32. package/lib/present-entry.js +26 -5
  33. package/lib/root-extras-entry.d.ts +2 -5
  34. package/lib/root-extras-entry.js +1 -3
  35. package/lib/selected-skills-entry.d.ts +14 -0
  36. package/lib/selected-skills-entry.js +43 -0
  37. package/lib/web-retriever/local-fetch.d.ts +1 -1
  38. package/lib/web-retriever/local-fetch.js +1 -1
  39. package/lib/web-retriever/wind-client.d.ts +1 -1
  40. package/lib/web-retriever/wind-client.js +1 -1
  41. package/package.json +15 -2
  42. package/preset/capital-generation/README.md +3 -3
  43. package/preset/capital-generation/agent.patch.yml +43 -20
  44. package/preset/capital-generation/skills/capital-chart-protocol/SKILL.md +3 -2
  45. package/preset/capital-generation/skills/capital-data-query/SKILL.md +32 -0
  46. package/preset/capital-generation/skills/capital-equity-research/SKILL.md +5 -0
  47. package/preset/capital-generation/skills/capital-event-impact/SKILL.md +3 -0
  48. package/preset/capital-generation/skills/capital-orchestration/SKILL.md +8 -10
  49. package/preset/capital-generation/skills/capital-portfolio-review/SKILL.md +3 -0
  50. package/preset/capital-generation/skills/capital-visualization-protocol/SKILL.md +7 -1
  51. package/preset/capital-generation/skills/capital-web-evidence/SKILL.md +1 -0
  52. package/preset/capital-generation/skills/capital-web-protocol/SKILL.md +3 -0
  53. package/selected-skills/README.md +5 -4
  54. package/selected-skills/ROUTING.md +88 -0
  55. package/selected-skills/catalog.js +32 -121
  56. package/selected-skills/routing.js +1036 -0
  57. package/watchlist/package.json +1 -1
@@ -9,9 +9,9 @@ const {
9
9
  Modal,
10
10
  writeClipboard,
11
11
  IconRightUpOutlineRegular,
12
- IconWarningTriangleOutlineRegular,
13
12
  } = require('@deepseek-ai/dsh-client-ui-primitives')
14
- const { SELECTED_SKILL_CATALOG, SELECTED_SKILL_TAG_LABELS, SELECTED_SKILLS_MAX_ENABLED } = require('../selected-skills/catalog.js')
13
+ const { SELECTED_SKILL_CATALOG, SELECTED_SKILL_TAG_LABELS } = require('../selected-skills/catalog.js')
14
+ const { SELECTED_SKILL_ROLES, SELECTED_SKILL_ROUTING } = require('../selected-skills/routing.js')
15
15
 
16
16
  /**
17
17
  * Two different strings: `ENTRY_ID` is the settings namespace (= profile entry
@@ -81,12 +81,14 @@ const zh = {
81
81
  paddleocrLabel: 'PaddleOCR 文档解析 Token',
82
82
  paddleocrHint: '配置 Token 后自动解析 PDF、图片。保存后新自动模式会话生效。',
83
83
  selectedSkillsTitle: '精选 Skills',
84
+ selectedSkillsModeLabel: '自动选择方法',
85
+ selectedSkillsModeHint: '开启后按角色开放该角色全部方法,由模型按触发条件选择;下方勾选只在手动模式生效。',
86
+ selectedSkillsModeShort: '自动',
84
87
  selectedSkillsFilterLabel: '按能力筛选',
85
88
  selectedSkillsEmpty: '没有匹配这个标签的 Skill。',
86
- // Cap blocks adding only; existing selections keep working (runtime does not truncate).
87
- // Reason lives on the warning icon's title / aria-label; {count} is appended in code.
88
- selectedSkillsCapTooltip: 'Skill已达上限 ({count})。',
89
- selectedSkillsCopyName: '复制技能名',
89
+ selectedSkillsRoles: '角色:',
90
+ selectedSkillsWhen: '何时使用:',
91
+ selectedSkillsCopyName: '复制 /技能名',
90
92
  selectedSkillsCopied: '已复制',
91
93
  selectedSkillsDetail: '详情',
92
94
  selectedSkillsDetailClose: '关闭',
@@ -125,10 +127,14 @@ const en = {
125
127
  paddleocrLabel: 'PaddleOCR document token',
126
128
  paddleocrHint: 'Configure the token to parse PDFs and images automatically. Takes effect in new Auto mode sessions.',
127
129
  selectedSkillsTitle: 'Selected Skills',
130
+ selectedSkillsModeLabel: 'Pick methods automatically',
131
+ selectedSkillsModeHint: 'When on, every method owned by a role is exposed and the model picks by trigger; the switches below apply to Manual mode only.',
132
+ selectedSkillsModeShort: 'Auto',
128
133
  selectedSkillsFilterLabel: 'Filter by capability',
129
134
  selectedSkillsEmpty: 'No skills match this tag.',
130
- selectedSkillsCapTooltip: 'Skill limit reached ({count}).',
131
- selectedSkillsCopyName: 'Copy skill name',
135
+ selectedSkillsRoles: 'Roles: ',
136
+ selectedSkillsWhen: 'Use when: ',
137
+ selectedSkillsCopyName: 'Copy /name',
132
138
  selectedSkillsCopied: 'Copied',
133
139
  selectedSkillsDetail: 'Details',
134
140
  selectedSkillsDetailClose: 'Close',
@@ -215,12 +221,14 @@ function installStyles() {
215
221
  .capital-config-doc-link { display: inline-flex; align-items: center; gap: 3px; color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 20px; white-space: nowrap; text-decoration: none; }
216
222
  .capital-config-doc-link:hover { color: var(--dsw-alias-brand-primary); text-decoration: underline; }
217
223
  .capital-config-doc-link:focus-visible { border-radius: 3px; outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-brand-primary)); outline-offset: 2px; }
224
+ .capital-config-selected-mode { margin-bottom: 12px; }
218
225
  .capital-config-switch-row { align-items: center; gap: 12px; display: flex; }
219
226
  .capital-config-switch-text { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 4px; }
220
227
  .capital-config-switch-label { color: var(--dsw-alias-label-primary); font-size: 13px; font-weight: 500; line-height: 20px; }
221
228
  .capital-config-hint { margin: 0; color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; }
222
- /* --dsw-alias-label-error is undefined in the theme, so state tokens only. */
223
- .capital-config-skill-cap-icon { display: inline-flex; align-items: center; flex: none; padding: 2px; margin: -2px; color: var(--dsw-alias-state-warn-primary); cursor: help; }
229
+ .capital-config-skill-roles { display: flex; flex-wrap: wrap; gap: 4px; }
230
+ .capital-config-skill-role { padding: 1px 5px; border-radius: 4px; border: 0.5px solid var(--dsw-alias-border-l1); color: var(--dsw-alias-label-secondary); font-size: 11px; line-height: 16px; }
231
+ .capital-config-skill-when { margin: 0; color: var(--dsw-alias-label-tertiary); font-size: 11.5px; line-height: 17px; }
224
232
  .capital-config-write-failed { margin: 0; color: var(--dsw-alias-state-error-primary); font-size: 12px; line-height: 18px; }
225
233
  /* Own inline-flex group so the host's wrapping never splits the two links. */
226
234
  .capital-config-plugin-links { flex: none; align-items: center; gap: 2px; display: inline-flex; }
@@ -241,6 +249,8 @@ class CapitalCardController {
241
249
  this.localFetchFailed = false
242
250
  this.selectedSkillWriting = new Set()
243
251
  this.selectedSkillFailed = new Set()
252
+ this.selectedSkillsModeWriting = false
253
+ this.selectedSkillsModeFailed = false
244
254
  // Row count is external: null = unknown, never 0; fetch only after the card is shown.
245
255
  this.bundleRows = null
246
256
  this.rowsRequested = false
@@ -285,6 +295,11 @@ class CapitalCardController {
285
295
  writing: this.selectedSkillWriting.has(field),
286
296
  failed: this.selectedSkillFailed.has(field),
287
297
  }])),
298
+ selectedSkillsMode: {
299
+ auto: snapshot.value?.selectedSkillsMode === 'auto',
300
+ writing: this.selectedSkillsModeWriting,
301
+ failed: this.selectedSkillsModeFailed,
302
+ },
288
303
  // `count === null` means unknown, not zero: the card decides whether to draw it.
289
304
  components: { count: this.bundleRows },
290
305
  }
@@ -362,6 +377,24 @@ class CapitalCardController {
362
377
  this.store.set(this.projection())
363
378
  }
364
379
 
380
+ async toggleSelectedSkillsMode(auto) {
381
+ if (this.selectedSkillsModeWriting) return
382
+ const snapshot = this.scope.getSnapshot()
383
+ if (snapshot.status !== 'ready' || !snapshot.writable) return
384
+ this.selectedSkillsModeWriting = true
385
+ this.selectedSkillsModeFailed = false
386
+ this.store.set(this.projection())
387
+ try {
388
+ await this.scope.mutate([{ op: 'set', path: ['selectedSkillsMode'], value: auto ? 'auto' : 'manual' }])
389
+ } catch {
390
+ // The landed check below reports the failure.
391
+ }
392
+ this.selectedSkillsModeWriting = false
393
+ const landed = (this.scope.getSnapshot().value?.selectedSkillsMode === 'auto') === auto
394
+ if (!landed) this.selectedSkillsModeFailed = true
395
+ this.store.set(this.projection())
396
+ }
397
+
365
398
  async toggleSelectedSkill(field, value) {
366
399
  if (!SELECTED_SKILL_FIELDS.includes(field) || this.selectedSkillWriting.has(field)) return
367
400
  const snapshot = this.scope.getSnapshot()
@@ -421,6 +454,7 @@ class CapitalCardController {
421
454
  ...this.model.actions(),
422
455
  toggleLocalFetch: (value) => this.toggleLocalFetch(value),
423
456
  toggleSelectedSkill: (field, value) => this.toggleSelectedSkill(field, value),
457
+ toggleSelectedSkillsMode: (auto) => this.toggleSelectedSkillsMode(auto),
424
458
  ensureBundleRows: () => this.ensureBundleRows(),
425
459
  }
426
460
  }
@@ -505,7 +539,7 @@ function loadSkillDoc(name) {
505
539
 
506
540
  const COPIED_FLASH_MS = 1600
507
541
 
508
- function SelectedSkillRow({ entry, state, disabled, capReached = false, capTooltip, onChange, t }) {
542
+ function SelectedSkillRow({ entry, state, copyable, disabled, onChange, t }) {
509
543
  const locale = skillLocale()
510
544
  const label = entry.label[locale]
511
545
  const repositoryUrl = `https://github.com/${entry.owner}/${entry.repository}`
@@ -517,7 +551,7 @@ function SelectedSkillRow({ entry, state, disabled, capReached = false, capToolt
517
551
  if (copyTimer.current !== null) clearTimeout(copyTimer.current)
518
552
  }, [])
519
553
  const copyName = async () => {
520
- const accepted = await writeClipboard(entry.name)
554
+ const accepted = await writeClipboard(`/${entry.name}`)
521
555
  // Do not flip the label if the clipboard rejected it.
522
556
  if (!accepted) return
523
557
  setCopied(true)
@@ -550,8 +584,8 @@ function SelectedSkillRow({ entry, state, disabled, capReached = false, capToolt
550
584
  h('div', { className: 'capital-config-skill-heading' },
551
585
  h('span', { className: 'capital-config-title' }, label),
552
586
  h('div', { className: 'capital-config-skill-actions' },
553
- // Copy name only on enabled rows; details has no gate.
554
- state?.on === true ? h('button', {
587
+ // Manual: only enabled rows. Auto: the role owns every method, so copying any name is meaningful.
588
+ copyable === true ? h('button', {
555
589
  type: 'button',
556
590
  className: 'capital-config-skill-action',
557
591
  title: `${t('selectedSkillsCopyName')}: ${entry.name}`,
@@ -583,6 +617,9 @@ function SelectedSkillRow({ entry, state, disabled, capReached = false, capToolt
583
617
  ),
584
618
  ),
585
619
  h('p', { className: 'capital-config-skill-description' }, entry.description[locale]),
620
+ h('p', { className: 'capital-config-skill-when' }, `${t('selectedSkillsWhen')}${SELECTED_SKILL_ROUTING[entry.name]?.useWhen?.[locale] ?? ''}`),
621
+ entry.roles?.length ? h('div', { className: 'capital-config-skill-roles' }, entry.roles.map((role) =>
622
+ h('span', { key: role, className: 'capital-config-skill-role' }, SELECTED_SKILL_ROLES[role]?.[locale] ?? role))) : null,
586
623
  h('a', {
587
624
  className: 'capital-config-skill-repo',
588
625
  href: repositoryUrl,
@@ -593,19 +630,10 @@ function SelectedSkillRow({ entry, state, disabled, capReached = false, capToolt
593
630
  h('div', { className: 'capital-config-skill-tags' }, entry.tags.map((tag) =>
594
631
  h('span', { key: tag, className: 'capital-config-skill-tag' }, SELECTED_SKILL_TAG_LABELS[locale][tag] ?? tag))),
595
632
  ),
596
- // Capped rows: reason on the icon before the switch; the icon ignores custom
597
- // props, so title / role sit on its wrapper.
598
- capReached && state?.on !== true ? h('span', {
599
- className: 'capital-config-skill-cap-icon',
600
- title: capTooltip,
601
- role: 'img',
602
- 'aria-label': capTooltip,
603
- }, h(IconWarningTriangleOutlineRegular, { size: 14 })) : null,
604
633
  h(Switch, {
605
634
  label,
606
635
  checked: state?.on === true,
607
- // Cap blocks adding only: an enabled row can always be turned off.
608
- disabled: disabled || state?.writing === true || (capReached && state?.on !== true),
636
+ disabled: disabled || state?.writing === true,
609
637
  onChange,
610
638
  }),
611
639
  ),
@@ -623,6 +651,7 @@ function CapitalCard(props) {
623
651
  const t = props.t
624
652
  const state = props.useCapitalCard((snapshot) => snapshot)
625
653
  const disabled = !state.writable
654
+ const autoMode = state.selectedSkillsMode?.auto === true
626
655
  const locale = skillLocale()
627
656
  const [tab, setTab] = useState('sources')
628
657
  const [tagFilter, setTagFilter] = useState('all')
@@ -679,6 +708,21 @@ function CapitalCard(props) {
679
708
  ),
680
709
  state.localFetch?.failed ? h('p', { role: 'status', className: 'capital-config-write-failed' }, t('saveFailed')) : null,
681
710
  )
711
+ const modeSection = h('div', { className: 'capital-config-field capital-config-selected-mode' },
712
+ h('div', { className: 'capital-config-switch-row' },
713
+ h('div', { className: 'capital-config-switch-text' },
714
+ h('span', { className: 'capital-config-switch-label' }, t('selectedSkillsModeLabel')),
715
+ h('p', { className: 'capital-config-hint' }, t('selectedSkillsModeHint')),
716
+ ),
717
+ h(Switch, {
718
+ label: t('selectedSkillsModeLabel'),
719
+ checked: autoMode,
720
+ disabled: disabled || state.saving || state.selectedSkillsMode?.writing === true,
721
+ onChange: props.toggleSelectedSkillsMode,
722
+ }),
723
+ ),
724
+ state.selectedSkillsMode?.failed ? h('p', { role: 'status', className: 'capital-config-write-failed' }, t('saveFailed')) : null,
725
+ )
682
726
  const tagLabels = SELECTED_SKILL_TAG_LABELS[locale]
683
727
  const skillsFilter = h('div', { className: 'capital-config-selected-filter', role: 'group', 'aria-label': t('selectedSkillsFilterLabel') },
684
728
  ...tags.map((tag) => h('button', {
@@ -689,22 +733,17 @@ function CapitalCard(props) {
689
733
  onClick: () => setTagFilter(tag),
690
734
  }, tagLabels[tag] ?? tag, h('span', { className: 'capital-config-selected-filter-count' }, String(tagCounts.get(tag))))),
691
735
  )
692
- // Live count for the tab and cap. The cap is edit-time only: existing selections keep working.
736
+ // No cap: the user builds the set; the role prompt caps only how many it lists.
693
737
  const enabledSkills = SELECTED_SKILL_CATALOG.filter(
694
738
  (entry) => state.selectedSkills?.[entry.key]?.on === true,
695
739
  ).length
696
- const capReached = enabledSkills >= SELECTED_SKILLS_MAX_ENABLED
697
- // Build the shared tooltip once; per-row drift would show different numbers.
698
- const capTooltip = t('selectedSkillsCapTooltip')
699
- .replace('{count}', `${enabledSkills}/${SELECTED_SKILLS_MAX_ENABLED}`)
700
740
  const skillRows = visibleSkills.length > 0
701
741
  ? visibleSkills.map((entry) => h(SelectedSkillRow, {
702
742
  key: entry.key,
703
- entry,
743
+ entry: { ...entry, roles: SELECTED_SKILL_ROUTING[entry.name]?.roles ?? [] },
704
744
  state: state.selectedSkills?.[entry.key],
705
- disabled: disabled || state.saving,
706
- capReached,
707
- capTooltip,
745
+ copyable: autoMode || state.selectedSkills?.[entry.key]?.on === true,
746
+ disabled: disabled || state.saving || autoMode,
708
747
  onChange: (value) => props.toggleSelectedSkill(entry.key, value),
709
748
  t,
710
749
  }))
@@ -714,7 +753,7 @@ function CapitalCard(props) {
714
753
  const options = [
715
754
  // A dirty draft while Save is off-screen must be announced on the tab.
716
755
  { value: 'sources', label: state.dirty ? t('titleUnsaved') : t('title') },
717
- { value: 'skills', label: `${t('selectedSkillsTitle')} ${enabledSkills}/${SELECTED_SKILL_CATALOG.length}` },
756
+ { value: 'skills', label: `${t('selectedSkillsTitle')} ${autoMode ? t('selectedSkillsModeShort') : `${enabledSkills}/${SELECTED_SKILL_CATALOG.length}`}` },
718
757
  { value: 'components', label: withCount(t('componentsTitle'), state.components?.count) },
719
758
  ]
720
759
  const panel = (value, children) => h('section', {
@@ -742,6 +781,7 @@ function CapitalCard(props) {
742
781
  }),
743
782
  panel('sources', [form, localFetchSection]),
744
783
  panel('skills', [
784
+ modeSection,
745
785
  h('div', { className: 'capital-config-selected-layout' },
746
786
  skillsFilter,
747
787
  h('div', { className: 'capital-config-selected-list' }, ...skillRows),
package/config/index.js CHANGED
@@ -59,15 +59,21 @@ const PaddleOcrSchema = z.object({
59
59
 
60
60
  const SelectedSkillsShape = Object.fromEntries(SELECTED_SKILL_CATALOG.map((entry) => [
61
61
  entry.key,
62
- z.boolean().default(false).volatile().description(`Enable ${entry.name} for the Auto mode root Agent (experimental; default off)`),
62
+ z.boolean().default(false).volatile().description(`Enable ${entry.name} for the Capital role(s) that own it (experimental; default off)`),
63
63
  ]))
64
64
  const SelectedSkillsSchema = z.object(SelectedSkillsShape)
65
65
 
66
66
  const SELECTED_SKILL_DEFAULTS = Object.fromEntries(SELECTED_SKILL_CATALOG.map((entry) => [entry.key, false]))
67
67
 
68
+ const SelectedSkillsModeSchema = z.union(['manual', 'auto'])
69
+ .default('manual')
70
+ .volatile()
71
+ .description('manual = 只用用户勾选;auto = 按角色开放全部方法,运行期忽略勾选')
72
+
68
73
  export const Config = z.object({
69
74
  customPersona: z.string().default('').volatile().description('自动模式附加人设文本'),
70
- selectedSkills: SelectedSkillsSchema.default(SELECTED_SKILL_DEFAULTS).description('Explicitly selected community experiments; default off and visible only to the Auto mode root Agent'),
75
+ selectedSkillsMode: SelectedSkillsModeSchema,
76
+ selectedSkills: SelectedSkillsSchema.default(SELECTED_SKILL_DEFAULTS).description('Explicitly selected community methods; default off, each visible only to the Capital role(s) that own it'),
71
77
  fuyaoCredentialRef: z.string().default('FUYAO_API_KEY').volatile().description('Fuyao credentials 引用名'),
72
78
  ftshareCredentialRef: z.string().default('FTSHARE_API_KEY').volatile().description('FTShare(非凸科技)credentials 引用名'),
73
79
  retriever: z.object({
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v587d/config",
3
- "version": "2.9.2",
3
+ "version": "2.10.1",
4
4
  "description": "自动模式的取数凭据与偏好配置行:卡片坐在 @v587d/capital-generation 插件主页的「配置」段,点这一行本身没有表单。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,24 +1,39 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  import type { SkillProviderControl } from '@deepseek-ai/dsh-skill';
3
3
  import { FileSystemSkillProvider } from '@deepseek-ai/dsh-skill-filesystem';
4
- import { type PolicyContext } from './root-tool-policy.js';
4
+ import { type AgentLike, type PolicyContext } from './root-tool-policy.js';
5
5
  export type SelectedSkillStatus = 'experimental' | 'watchlist';
6
6
  export type SelectedSkillCatalogEntry = {
7
7
  key: string;
8
8
  name: string;
9
+ label: {
10
+ zh: string;
11
+ en: string;
12
+ };
13
+ repository: string;
9
14
  status: SelectedSkillStatus;
10
15
  tags: readonly string[];
11
16
  };
12
17
  export declare const SELECTED_SKILL_CATALOG: readonly SelectedSkillCatalogEntry[];
13
- export type SelectedSkillKey = typeof SELECTED_SKILL_CATALOG[number]['key'];
14
- export type SelectedSkillSelection = Partial<Record<SelectedSkillKey, boolean>>;
18
+ /** Roles a preset row may declare. data_collector / visualization have no method set. */
19
+ export declare const SELECTED_SKILL_ENTRY_ROLES: readonly ["main", "data_junior", "web_retriever", "data_analyst", "data_collector", "visualization_specialist"];
20
+ export type SelectedSkillRole = typeof SELECTED_SKILL_ENTRY_ROLES[number];
21
+ export type SelectedSkillSelection = Partial<Record<string, boolean>>;
15
22
  export type SelectedSkillSelectionSource = SelectedSkillSelection | (() => SelectedSkillSelection);
16
- type RuntimeSummary = {
17
- name: string;
18
- description: string;
23
+ export type SelectedSkillsMode = 'auto' | 'manual';
24
+ /** Mode + manual switches. `auto` exposes every method the role owns and ignores the switches. */
25
+ export type SelectedSkillAccess = SelectedSkillSelectionSource | {
26
+ selection: SelectedSkillSelectionSource;
27
+ mode: SelectedSkillsMode | (() => SelectedSkillsMode);
19
28
  };
20
- /** Sole index renderer; descriptions use runtime frontmatter (what the model sees), not card summaries. */
21
- export declare function renderTaskSkillIndex(taskId: string, summaries: readonly RuntimeSummary[]): string | undefined;
29
+ /** Names this role may load, independent of the user's switches. One filter lives in routing.js. */
30
+ export declare function selectedSkillNamesForRole(role: SelectedSkillRole): Set<string>;
31
+ /** Enabled names for one role, read at call time (settings are a live preference). */
32
+ export declare function enabledSelectedSkillNames(role: SelectedSkillRole, selection: SelectedSkillSelection): Set<string>;
33
+ export declare function readSelectedSkillSelection(source: SelectedSkillSelectionSource): SelectedSkillSelection;
34
+ export declare function readSelectedSkillsMode(access: SelectedSkillAccess): SelectedSkillsMode;
35
+ /** Names the role may load right now: auto = the whole role set; manual = switches only. */
36
+ export declare function availableSelectedSkillNames(role: SelectedSkillRole, access: SelectedSkillAccess): Set<string>;
22
37
  type FileSystemSkillConfig = {
23
38
  providerName: string;
24
39
  includeDefaultRoots: false;
@@ -27,6 +42,10 @@ type FileSystemSkillConfig = {
27
42
  };
28
43
  type FileSystemSkillSource = Pick<FileSystemSkillProvider, 'list' | 'get' | 'dispose'>;
29
44
  type FileSystemSkillFactory = (ctx: Context, control: SkillProviderControl, config: FileSystemSkillConfig) => FileSystemSkillSource;
30
- /** Registers selected community experiments on the Capital root Agent only. */
31
- export declare function registerRootSelectedSkills(ctx: PolicyContext, selection: SelectedSkillSelectionSource, createFilesystemProvider?: FileSystemSkillFactory): void;
45
+ /** Read-time router for one role: only cards whose snapshot actually exists are promised to the model. */
46
+ export declare function selectedSkillEntriesForRole(role: SelectedSkillRole, access: SelectedSkillAccess): SelectedSkillCatalogEntry[];
47
+ /** Role prompt: a short, imperative router. No upstream prose and no variable interpolation. */
48
+ export declare function renderSelectedSkillsBrief(role: SelectedSkillRole, access: SelectedSkillAccess, agent?: AgentLike): string;
49
+ /** Registers the role-scoped method catalog on the configured Capital preset Agent only. */
50
+ export declare function registerSelectedSkills(ctx: PolicyContext, role: SelectedSkillRole, access: SelectedSkillAccess, createFilesystemProvider?: FileSystemSkillFactory): void;
32
51
  export {};