@cat-factory/app 0.123.0 → 0.124.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.
- package/app/components/layout/AccountSkillSettings.vue +21 -0
- package/app/components/pipeline/PipelineBuilder.vue +48 -0
- package/app/components/settings/AccountSettingsPanel.vue +15 -0
- package/app/components/skills/SkillLibraryManager.vue +337 -0
- package/app/composables/api/context.ts +2 -0
- package/app/composables/api/skills.ts +48 -0
- package/app/composables/useApi.ts +4 -1
- package/app/stores/pipelines.ts +19 -0
- package/app/stores/skillLibrary.ts +153 -0
- package/app/stores/skills.spec.ts +60 -0
- package/app/stores/skills.ts +22 -0
- package/app/stores/workspace.ts +4 -0
- package/app/types/domain.ts +1 -0
- package/app/types/skills.ts +18 -0
- package/i18n/locales/de.json +55 -2
- package/i18n/locales/en.json +55 -2
- package/i18n/locales/es.json +55 -2
- package/i18n/locales/fr.json +55 -2
- package/i18n/locales/he.json +55 -2
- package/i18n/locales/it.json +55 -2
- package/i18n/locales/ja.json +55 -2
- package/i18n/locales/pl.json +55 -2
- package/i18n/locales/tr.json +55 -2
- package/i18n/locales/uk.json +55 -2
- package/package.json +2 -2
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import type {
|
|
4
|
+
AccountSkill,
|
|
5
|
+
LinkSkillSourceInput,
|
|
6
|
+
SkillSource,
|
|
7
|
+
SkillSyncResult,
|
|
8
|
+
} from '~/types/domain'
|
|
9
|
+
import { useSingleFlightProbe } from '~/composables/useSingleFlightProbe'
|
|
10
|
+
import { useSkillsStore } from '~/stores/skills'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The repo-sourced Claude Skills library for one account (docs/initiatives/repo-skills.md),
|
|
14
|
+
* used by the account-settings management surface. Holds the account's synced skill catalog
|
|
15
|
+
* (full detail) and its linked repo sources, and drives link / sync / status / unlink. Skills
|
|
16
|
+
* are a single account tier (no workspace tier), so — unlike the fragment library — there is no
|
|
17
|
+
* owner-kind axis; the store is keyed purely by account id.
|
|
18
|
+
*
|
|
19
|
+
* `available` mirrors the backend's opt-in gate: a 503 from the catalog probe means the feature
|
|
20
|
+
* is off and the UI hides its panel. `sourcesAvailable` is the finer gate — the catalog read
|
|
21
|
+
* works, but linking/syncing repo sources needs the GitHub integration, whose absence 503s only
|
|
22
|
+
* the `skill-sources/*` routes.
|
|
23
|
+
*
|
|
24
|
+
* After any mutation that changes the catalog, the updated summaries are pushed into the
|
|
25
|
+
* snapshot-hydrated {@link useSkillsStore} so the pipeline builder's picker reflects the change
|
|
26
|
+
* immediately, without a full board refresh.
|
|
27
|
+
*/
|
|
28
|
+
function skillLibrarySetup(resolveAccountId: () => string | null) {
|
|
29
|
+
const api = useApi()
|
|
30
|
+
|
|
31
|
+
/** null = not probed yet; true/false = library on/off (the catalog read). */
|
|
32
|
+
const available = ref<boolean | null>(null)
|
|
33
|
+
/** false when the GitHub integration is off (catalog works; source linking/syncing does not). */
|
|
34
|
+
const sourcesAvailable = ref(true)
|
|
35
|
+
/** The account's synced skills (full detail — instructions + resource manifest). */
|
|
36
|
+
const catalog = ref<AccountSkill[]>([])
|
|
37
|
+
/** Linked repo sources of skill folders. */
|
|
38
|
+
const sources = ref<SkillSource[]>([])
|
|
39
|
+
/** Per-source "changes available" flag from the last status check. */
|
|
40
|
+
const sourceChanges = ref<Record<string, boolean>>({})
|
|
41
|
+
const loading = ref(false)
|
|
42
|
+
|
|
43
|
+
function requireAccountId(): string {
|
|
44
|
+
const id = resolveAccountId()
|
|
45
|
+
if (!id) throw new Error('No skill-library account')
|
|
46
|
+
return id
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Mirror the full catalog into the snapshot picker store as lightweight summaries. */
|
|
50
|
+
function syncPicker() {
|
|
51
|
+
useSkillsStore().hydrate(
|
|
52
|
+
catalog.value.map((s) => ({ id: s.id, name: s.name, description: s.description })),
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Probe the feature + load this account's catalog and sources. */
|
|
57
|
+
async function runProbe() {
|
|
58
|
+
const id = resolveAccountId()
|
|
59
|
+
if (!id) return
|
|
60
|
+
try {
|
|
61
|
+
catalog.value = await api.listAccountSkills(id)
|
|
62
|
+
available.value = true
|
|
63
|
+
syncPicker()
|
|
64
|
+
} catch {
|
|
65
|
+
available.value = false
|
|
66
|
+
catalog.value = []
|
|
67
|
+
sources.value = []
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
// Sources need the GitHub integration; a 503 here just hides the linking UI (the catalog
|
|
71
|
+
// read above already succeeded, so the feature itself is on).
|
|
72
|
+
try {
|
|
73
|
+
sources.value = await api.listSkillSources(id)
|
|
74
|
+
sourcesAvailable.value = true
|
|
75
|
+
} catch {
|
|
76
|
+
sources.value = []
|
|
77
|
+
sourcesAvailable.value = false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Single-flight the probe keyed on the account id, so the panel-open fan-out loads once.
|
|
81
|
+
const { probe, ensureProbed } = useSingleFlightProbe(runProbe, () => resolveAccountId())
|
|
82
|
+
|
|
83
|
+
async function reloadCatalog() {
|
|
84
|
+
catalog.value = await api.listAccountSkills(requireAccountId())
|
|
85
|
+
syncPicker()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function reloadSources() {
|
|
89
|
+
sources.value = await api.listSkillSources(requireAccountId())
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function linkSource(input: LinkSkillSourceInput): Promise<SkillSource> {
|
|
93
|
+
const source = await api.linkSkillSource(requireAccountId(), input)
|
|
94
|
+
sources.value = [source, ...sources.value]
|
|
95
|
+
// Auto-sync the freshly-linked source so its skills land in the catalog immediately.
|
|
96
|
+
await syncSourceRaw(source.id)
|
|
97
|
+
return source
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function unlinkSource(sourceId: string) {
|
|
101
|
+
await api.unlinkSkillSource(requireAccountId(), sourceId)
|
|
102
|
+
sources.value = sources.value.filter((s) => s.id !== sourceId)
|
|
103
|
+
delete sourceChanges.value[sourceId]
|
|
104
|
+
await reloadCatalog()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** The bare sync used both by the row action and the auto-sync after link. */
|
|
108
|
+
async function syncSourceRaw(sourceId: string): Promise<SkillSyncResult> {
|
|
109
|
+
const result = await api.syncSkillSource(requireAccountId(), sourceId)
|
|
110
|
+
delete sourceChanges.value[sourceId]
|
|
111
|
+
await Promise.all([reloadSources(), reloadCatalog()])
|
|
112
|
+
return result
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function syncSource(sourceId: string): Promise<SkillSyncResult> {
|
|
116
|
+
loading.value = true
|
|
117
|
+
try {
|
|
118
|
+
return await syncSourceRaw(sourceId)
|
|
119
|
+
} finally {
|
|
120
|
+
loading.value = false
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Lightweight commit-version "check for changes" for a source; caches the flag. */
|
|
125
|
+
async function checkSource(sourceId: string) {
|
|
126
|
+
const status = await api.skillSourceStatus(requireAccountId(), sourceId)
|
|
127
|
+
sourceChanges.value = { ...sourceChanges.value, [sourceId]: status.changed }
|
|
128
|
+
return status
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
available,
|
|
133
|
+
sourcesAvailable,
|
|
134
|
+
catalog,
|
|
135
|
+
sources,
|
|
136
|
+
sourceChanges,
|
|
137
|
+
loading,
|
|
138
|
+
probe,
|
|
139
|
+
ensureProbed,
|
|
140
|
+
linkSource,
|
|
141
|
+
unlinkSource,
|
|
142
|
+
syncSource,
|
|
143
|
+
checkSource,
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* An account-keyed skill-library store (one isolated instance per account), used by the
|
|
149
|
+
* account-settings Skills tab.
|
|
150
|
+
*/
|
|
151
|
+
export function useSkillLibrary(accountId: string) {
|
|
152
|
+
return defineStore(`skillLibrary:${accountId}`, () => skillLibrarySetup(() => accountId))()
|
|
153
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { useSkillsStore } from '~/stores/skills'
|
|
3
|
+
import { usePipelinesStore } from '~/stores/pipelines'
|
|
4
|
+
import type { SkillSummary } from '~/types/domain'
|
|
5
|
+
|
|
6
|
+
const summary = (id: string, name = id): SkillSummary => ({ id, name, description: `${name} desc` })
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The skill picker spans two stores: the snapshot-hydrated `useSkillsStore` (the catalog the
|
|
10
|
+
* builder's `USelect` binds against) and the per-step `skillId` helpers on `usePipelinesStore`.
|
|
11
|
+
* These pin the behaviours the builder relies on (docs/initiatives/repo-skills.md slice 3).
|
|
12
|
+
*/
|
|
13
|
+
describe('skills picker store — snapshot-hydrated catalog', () => {
|
|
14
|
+
it('hydrate is a straight replace (a later hydrate does not merge with the earlier one)', () => {
|
|
15
|
+
const skills = useSkillsStore()
|
|
16
|
+
expect(skills.catalog).toEqual([])
|
|
17
|
+
|
|
18
|
+
skills.hydrate([summary('sk_a'), summary('sk_b')])
|
|
19
|
+
expect(skills.catalog.map((s) => s.id)).toEqual(['sk_a', 'sk_b'])
|
|
20
|
+
|
|
21
|
+
// A resync (or a board switch) replaces the whole list — no stale ids linger.
|
|
22
|
+
skills.hydrate([summary('sk_c')])
|
|
23
|
+
expect(skills.catalog.map((s) => s.id)).toEqual(['sk_c'])
|
|
24
|
+
|
|
25
|
+
// An empty hydrate (feature off / account with no skills) clears it.
|
|
26
|
+
skills.hydrate([])
|
|
27
|
+
expect(skills.catalog).toEqual([])
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
describe('pipelines store — per-step skill picker helpers', () => {
|
|
32
|
+
it('sets, reads and clears a draft skill step’s skillId', () => {
|
|
33
|
+
const pipelines = usePipelinesStore()
|
|
34
|
+
pipelines.addToDraft('skill')
|
|
35
|
+
expect(pipelines.draftSkillId(0)).toBeUndefined()
|
|
36
|
+
|
|
37
|
+
pipelines.setDraftSkillId(0, 'sk_1')
|
|
38
|
+
expect(pipelines.draftSkillId(0)).toBe('sk_1')
|
|
39
|
+
expect(pipelines.draftStepOptions[0]).toEqual({ skillId: 'sk_1' })
|
|
40
|
+
|
|
41
|
+
// Clearing drops the field and, with the bag now empty, normalizes the entry back to null.
|
|
42
|
+
pipelines.setDraftSkillId(0, undefined)
|
|
43
|
+
expect(pipelines.draftSkillId(0)).toBeUndefined()
|
|
44
|
+
expect(pipelines.draftStepOptions[0]).toBeNull()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('merges into the options bag rather than clobbering other per-step options', () => {
|
|
48
|
+
const pipelines = usePipelinesStore()
|
|
49
|
+
pipelines.addToDraft('skill')
|
|
50
|
+
// Seed a co-existing option (as a requirements-review opt-out would).
|
|
51
|
+
pipelines.draftStepOptions[0] = { autoRecommend: false }
|
|
52
|
+
|
|
53
|
+
pipelines.setDraftSkillId(0, 'sk_1')
|
|
54
|
+
expect(pipelines.draftStepOptions[0]).toEqual({ autoRecommend: false, skillId: 'sk_1' })
|
|
55
|
+
|
|
56
|
+
// Clearing only the skill leaves the other option (bag not empty ⇒ entry survives).
|
|
57
|
+
pipelines.setDraftSkillId(0, undefined)
|
|
58
|
+
expect(pipelines.draftStepOptions[0]).toEqual({ autoRecommend: false })
|
|
59
|
+
})
|
|
60
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import type { SkillSummary } from '~/types/domain'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The account's repo-sourced Claude Skills catalog (docs/initiatives/repo-skills.md slice 3),
|
|
7
|
+
* hydrated from the workspace snapshot as lightweight `{ id, name, description }` summaries.
|
|
8
|
+
* Drives the pipeline builder's per-step skill picker: a `skill` step binds its
|
|
9
|
+
* `stepOptions.skillId` to one of these. Skills live in ONE tier (the account, shared across its
|
|
10
|
+
* workspaces), so a snapshot hydrate is a straight replace — no per-board reset needed. The
|
|
11
|
+
* account-settings management surface owns the full catalog + sources; it pushes its updated
|
|
12
|
+
* summaries back here after a sync so the picker stays in step without a board reload.
|
|
13
|
+
*/
|
|
14
|
+
export const useSkillsStore = defineStore('skills', () => {
|
|
15
|
+
const catalog = ref<SkillSummary[]>([])
|
|
16
|
+
|
|
17
|
+
function hydrate(list: SkillSummary[]) {
|
|
18
|
+
catalog.value = list
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return { catalog, hydrate }
|
|
22
|
+
})
|
package/app/stores/workspace.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { useRecurringPipelinesStore } from '~/stores/recurringPipelines'
|
|
|
24
24
|
import { useInitiativesStore } from '~/stores/initiative'
|
|
25
25
|
import { useServicesStore } from '~/stores/services'
|
|
26
26
|
import { useAgentsStore } from '~/stores/agents'
|
|
27
|
+
import { useSkillsStore } from '~/stores/skills'
|
|
27
28
|
import { useTrackerStore } from '~/stores/tracker'
|
|
28
29
|
import { useRequirementsStore } from '~/stores/requirements'
|
|
29
30
|
import { useClarityStore } from '~/stores/clarity'
|
|
@@ -151,6 +152,9 @@ export const useWorkspaceStore = defineStore(
|
|
|
151
152
|
// Merge the deployment's registered custom agent kinds into the palette catalog so a
|
|
152
153
|
// proprietary kind renders as a first-class block + result view (idempotent on reload).
|
|
153
154
|
useAgentsStore().registerCustomKinds(snapshot.customAgentKinds ?? [])
|
|
155
|
+
// The account's repo-sourced Claude Skills catalog (shared across its workspaces), so the
|
|
156
|
+
// pipeline builder's per-step skill picker has its options. A straight replace.
|
|
157
|
+
useSkillsStore().hydrate(snapshot.skills ?? [])
|
|
154
158
|
// Seed the connect form's backend-kind selectors (built-in + any custom backend a
|
|
155
159
|
// deployment registered), so a programmatically-registered env/runner backend is a
|
|
156
160
|
// first-class connect option instead of a hardcoded manifest/kubernetes list.
|
package/app/types/domain.ts
CHANGED
|
@@ -133,6 +133,7 @@ export interface AuthUser {
|
|
|
133
133
|
export type * from './execution'
|
|
134
134
|
export type * from './models'
|
|
135
135
|
export type * from './fragments'
|
|
136
|
+
export type * from './skills'
|
|
136
137
|
export type * from './documents'
|
|
137
138
|
export type * from './tasks'
|
|
138
139
|
export type * from './bootstrap'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Repo-sourced Claude Skills library (docs/initiatives/repo-skills.md). Mirrors
|
|
3
|
+
// the `@cat-factory/contracts` skill-library schemas: the account skill catalog
|
|
4
|
+
// (shared across the account's workspaces), the repo sources that feed it, and the
|
|
5
|
+
// lightweight per-skill summary carried in the workspace snapshot for the picker.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
//
|
|
8
|
+
// All wire shapes are sourced from @cat-factory/contracts (single source of truth).
|
|
9
|
+
|
|
10
|
+
export type {
|
|
11
|
+
SkillResource,
|
|
12
|
+
AccountSkill,
|
|
13
|
+
SkillSource,
|
|
14
|
+
SkillSummary,
|
|
15
|
+
LinkSkillSourceInput,
|
|
16
|
+
SkillSyncResult,
|
|
17
|
+
SkillSourceStatus,
|
|
18
|
+
} from '@cat-factory/contracts'
|
package/i18n/locales/de.json
CHANGED
|
@@ -50,7 +50,8 @@
|
|
|
50
50
|
"noAccount": "Kein Konto ausgewählt.",
|
|
51
51
|
"tabs": {
|
|
52
52
|
"team": "Team & Zugriff",
|
|
53
|
-
"fragments": "Kontextfragmente"
|
|
53
|
+
"fragments": "Kontextfragmente",
|
|
54
|
+
"skills": "Skills"
|
|
54
55
|
}
|
|
55
56
|
},
|
|
56
57
|
"infrastructure": {
|
|
@@ -1963,6 +1964,9 @@
|
|
|
1963
1964
|
"label": "Vorlagen & Beispiele"
|
|
1964
1965
|
}
|
|
1965
1966
|
}
|
|
1967
|
+
},
|
|
1968
|
+
"accountSkills": {
|
|
1969
|
+
"intro": "Verknüpfe Repositorys, in denen dein Team Claude Skills erstellt (ein SKILL.md-Ordner plus Ressourcendateien). Synchronisierte Skills landen im Katalog dieses Kontos, der von allen Boards geteilt wird, und der Skill-Schritt einer Pipeline führt einen davon für eine Aufgabe aus."
|
|
1966
1970
|
}
|
|
1967
1971
|
},
|
|
1968
1972
|
"board": {
|
|
@@ -3117,7 +3121,11 @@
|
|
|
3117
3121
|
"cloned": "\"{name}\" geklont — bearbeite jetzt \"{copy}\"",
|
|
3118
3122
|
"cloneFailed": "Pipeline konnte nicht geklont werden",
|
|
3119
3123
|
"updateFailed": "Pipeline konnte nicht aktualisiert werden"
|
|
3120
|
-
}
|
|
3124
|
+
},
|
|
3125
|
+
"skillPlaceholder": "Skill auswählen",
|
|
3126
|
+
"skillNoneAvailable": "Keine Skills verfügbar. Verknüpfe eine Skill-Quelle in den Kontoeinstellungen.",
|
|
3127
|
+
"skillMissing": "Dieser Skill ist nicht mehr im Katalog; wähle einen anderen.",
|
|
3128
|
+
"skillNeedsPick": "Ein Skill-Schritt braucht einen ausgewählten Skill, bevor du speichern kannst."
|
|
3121
3129
|
},
|
|
3122
3130
|
"progress": {
|
|
3123
3131
|
"status": {
|
|
@@ -4881,5 +4889,50 @@
|
|
|
4881
4889
|
"count": "{attempts} von {max}",
|
|
4882
4890
|
"footer": "Die Schleife wird wiederholt, bis der Validierungsbefehl erfolgreich ist oder das Iterationsbudget aufgebraucht ist."
|
|
4883
4891
|
}
|
|
4892
|
+
},
|
|
4893
|
+
"skills": {
|
|
4894
|
+
"unavailable": "Die Claude-Skills-Bibliothek ist für diese Bereitstellung nicht aktiviert.",
|
|
4895
|
+
"catalog": {
|
|
4896
|
+
"title": "Synchronisierte Skills",
|
|
4897
|
+
"empty": "Noch keine Skills synchronisiert. Verknüpfe unten eine Repo-Quelle, um ihre Skill-Ordner zu importieren.",
|
|
4898
|
+
"resources": "{count} Ressourcen",
|
|
4899
|
+
"pinned": "fixiert auf {commit}"
|
|
4900
|
+
},
|
|
4901
|
+
"sources": {
|
|
4902
|
+
"title": "Repo-Quellen",
|
|
4903
|
+
"empty": "Keine verknüpften Skill-Quellen. Verknüpfe unten ein Repo-Verzeichnis mit Skill-Ordnern.",
|
|
4904
|
+
"linkTitle": "Skill-Quelle verknüpfen",
|
|
4905
|
+
"link": "Verknüpfen & synchronisieren",
|
|
4906
|
+
"metaSynced": "synchronisiert {date} · Ref {ref}",
|
|
4907
|
+
"metaNever": "nie synchronisiert · Ref {ref}",
|
|
4908
|
+
"changes": "Änderungen",
|
|
4909
|
+
"check": "Auf Änderungen prüfen",
|
|
4910
|
+
"sync": "Neu synchronisieren",
|
|
4911
|
+
"unlink": "Trennen",
|
|
4912
|
+
"browseHint": "Durchsuche das Repository und wähle das Verzeichnis mit den Skill-Ordnern (oder verknüpfe das ganze Repo).",
|
|
4913
|
+
"selectedDir": "Verzeichnis:",
|
|
4914
|
+
"wholeRepo": "Gesamtes Repository (Wurzel).",
|
|
4915
|
+
"ownerPlaceholder": "Eigentümer",
|
|
4916
|
+
"repoPlaceholder": "Repo",
|
|
4917
|
+
"dirPlaceholder": "Verzeichnispfad (z. B. .claude/skills)",
|
|
4918
|
+
"refPlaceholder": "Ref (Standard HEAD)",
|
|
4919
|
+
"githubRequired": "Zum Verknüpfen einer Skill-Quelle ist die GitHub-Integration erforderlich. Verbinde sie zuerst auf einem Board."
|
|
4920
|
+
},
|
|
4921
|
+
"confirmUnlinkSource": {
|
|
4922
|
+
"title": "Diese Quelle trennen?",
|
|
4923
|
+
"body": "\"{repo}\" und die davon synchronisierten Skills werden entfernt. Du kannst sie später erneut verknüpfen.",
|
|
4924
|
+
"confirm": "Trennen"
|
|
4925
|
+
},
|
|
4926
|
+
"toast": {
|
|
4927
|
+
"sourceLinked": "Quelle verknüpft & synchronisiert",
|
|
4928
|
+
"linkSourceFailed": "Quelle konnte nicht verknüpft werden",
|
|
4929
|
+
"synced": "Synchronisiert: {updated} aktualisiert, {removed} entfernt",
|
|
4930
|
+
"syncFailed": "Quelle konnte nicht synchronisiert werden",
|
|
4931
|
+
"changesAvailable": "Änderungen verfügbar",
|
|
4932
|
+
"upToDate": "Aktuell",
|
|
4933
|
+
"checkSourceFailed": "Quelle konnte nicht geprüft werden",
|
|
4934
|
+
"sourceUnlinked": "Quelle getrennt",
|
|
4935
|
+
"unlinkSourceFailed": "Quelle konnte nicht getrennt werden"
|
|
4936
|
+
}
|
|
4884
4937
|
}
|
|
4885
4938
|
}
|
package/i18n/locales/en.json
CHANGED
|
@@ -1935,6 +1935,9 @@
|
|
|
1935
1935
|
"label": "Templates & examples"
|
|
1936
1936
|
}
|
|
1937
1937
|
}
|
|
1938
|
+
},
|
|
1939
|
+
"accountSkills": {
|
|
1940
|
+
"intro": "Link repos where your team authors Claude Skills (a SKILL.md folder plus resource files). Synced skills join this account's catalog, shared by every board, and a pipeline's Skill step runs one against a task."
|
|
1938
1941
|
}
|
|
1939
1942
|
},
|
|
1940
1943
|
"settings": {
|
|
@@ -1988,7 +1991,8 @@
|
|
|
1988
1991
|
"noAccount": "No account selected.",
|
|
1989
1992
|
"tabs": {
|
|
1990
1993
|
"team": "Team & access",
|
|
1991
|
-
"fragments": "Context fragments"
|
|
1994
|
+
"fragments": "Context fragments",
|
|
1995
|
+
"skills": "Skills"
|
|
1992
1996
|
}
|
|
1993
1997
|
},
|
|
1994
1998
|
"infrastructure": {
|
|
@@ -3473,7 +3477,11 @@
|
|
|
3473
3477
|
"cloned": "Cloned \"{name}\" — now editing \"{copy}\"",
|
|
3474
3478
|
"cloneFailed": "Could not clone pipeline",
|
|
3475
3479
|
"updateFailed": "Could not update pipeline"
|
|
3476
|
-
}
|
|
3480
|
+
},
|
|
3481
|
+
"skillPlaceholder": "Select a skill",
|
|
3482
|
+
"skillNoneAvailable": "No skills available. Link a skill source in account settings.",
|
|
3483
|
+
"skillMissing": "This skill is no longer in the catalog; pick another.",
|
|
3484
|
+
"skillNeedsPick": "A Skill step needs a skill selected before you can save."
|
|
3477
3485
|
},
|
|
3478
3486
|
"progress": {
|
|
3479
3487
|
"status": {
|
|
@@ -5007,5 +5015,50 @@
|
|
|
5007
5015
|
"count": "{attempts} of {max}",
|
|
5008
5016
|
"footer": "The loop retries until the validation command passes or the iteration budget is spent."
|
|
5009
5017
|
}
|
|
5018
|
+
},
|
|
5019
|
+
"skills": {
|
|
5020
|
+
"unavailable": "The Claude Skills library isn't enabled for this deployment.",
|
|
5021
|
+
"catalog": {
|
|
5022
|
+
"title": "Synced skills",
|
|
5023
|
+
"empty": "No skills synced yet. Link a repo source below to import its skill folders.",
|
|
5024
|
+
"resources": "{count} resources",
|
|
5025
|
+
"pinned": "pinned {commit}"
|
|
5026
|
+
},
|
|
5027
|
+
"sources": {
|
|
5028
|
+
"title": "Repo sources",
|
|
5029
|
+
"empty": "No linked skill sources. Link a repo directory of skill folders below.",
|
|
5030
|
+
"linkTitle": "Link a skill source",
|
|
5031
|
+
"link": "Link & sync",
|
|
5032
|
+
"metaSynced": "synced {date} · ref {ref}",
|
|
5033
|
+
"metaNever": "never synced · ref {ref}",
|
|
5034
|
+
"changes": "Changes",
|
|
5035
|
+
"check": "Check for changes",
|
|
5036
|
+
"sync": "Resync",
|
|
5037
|
+
"unlink": "Unlink",
|
|
5038
|
+
"browseHint": "Browse the repo and pick the directory of skill folders (or link the whole repo).",
|
|
5039
|
+
"selectedDir": "Directory:",
|
|
5040
|
+
"wholeRepo": "Whole repository (root).",
|
|
5041
|
+
"ownerPlaceholder": "owner",
|
|
5042
|
+
"repoPlaceholder": "repo",
|
|
5043
|
+
"dirPlaceholder": "dir path (e.g. .claude/skills)",
|
|
5044
|
+
"refPlaceholder": "ref (default HEAD)",
|
|
5045
|
+
"githubRequired": "Linking a skill source requires the GitHub integration. Connect it on a board first."
|
|
5046
|
+
},
|
|
5047
|
+
"confirmUnlinkSource": {
|
|
5048
|
+
"title": "Unlink this source?",
|
|
5049
|
+
"body": "\"{repo}\" and the skills it synced will be removed. You can re-link it later.",
|
|
5050
|
+
"confirm": "Unlink"
|
|
5051
|
+
},
|
|
5052
|
+
"toast": {
|
|
5053
|
+
"sourceLinked": "Source linked & synced",
|
|
5054
|
+
"linkSourceFailed": "Could not link source",
|
|
5055
|
+
"synced": "Synced: {updated} updated, {removed} removed",
|
|
5056
|
+
"syncFailed": "Could not sync source",
|
|
5057
|
+
"changesAvailable": "Changes available",
|
|
5058
|
+
"upToDate": "Up to date",
|
|
5059
|
+
"checkSourceFailed": "Could not check source",
|
|
5060
|
+
"sourceUnlinked": "Source unlinked",
|
|
5061
|
+
"unlinkSourceFailed": "Could not unlink source"
|
|
5062
|
+
}
|
|
5010
5063
|
}
|
|
5011
5064
|
}
|
package/i18n/locales/es.json
CHANGED
|
@@ -1875,6 +1875,9 @@
|
|
|
1875
1875
|
"deselect": "Deseleccionar / cerrar el inspector",
|
|
1876
1876
|
"deleteBlock": "Eliminar el bloque seleccionado",
|
|
1877
1877
|
"help": "Mostrar esta ayuda"
|
|
1878
|
+
},
|
|
1879
|
+
"accountSkills": {
|
|
1880
|
+
"intro": "Vincula repositorios donde tu equipo crea Claude Skills (una carpeta SKILL.md más archivos de recursos). Las habilidades sincronizadas se añaden al catálogo de esta cuenta, compartido por todos los tableros, y el paso Skill de una tubería ejecuta una sobre una tarea."
|
|
1878
1881
|
}
|
|
1879
1882
|
},
|
|
1880
1883
|
"settings": {
|
|
@@ -1928,7 +1931,8 @@
|
|
|
1928
1931
|
"noAccount": "Ninguna cuenta seleccionada.",
|
|
1929
1932
|
"tabs": {
|
|
1930
1933
|
"team": "Equipo y acceso",
|
|
1931
|
-
"fragments": "Fragmentos de contexto"
|
|
1934
|
+
"fragments": "Fragmentos de contexto",
|
|
1935
|
+
"skills": "Habilidades"
|
|
1932
1936
|
}
|
|
1933
1937
|
},
|
|
1934
1938
|
"providerConnection": {
|
|
@@ -3377,7 +3381,11 @@
|
|
|
3377
3381
|
"confirmDeletePipeline": {
|
|
3378
3382
|
"title": "¿Eliminar este pipeline?",
|
|
3379
3383
|
"body": "Se eliminará \"{name}\". Esta acción no se puede deshacer."
|
|
3380
|
-
}
|
|
3384
|
+
},
|
|
3385
|
+
"skillPlaceholder": "Selecciona una habilidad",
|
|
3386
|
+
"skillNoneAvailable": "No hay habilidades disponibles. Vincula una fuente de habilidades en la configuración de la cuenta.",
|
|
3387
|
+
"skillMissing": "Esta habilidad ya no está en el catálogo; elige otra.",
|
|
3388
|
+
"skillNeedsPick": "Un paso Skill necesita una habilidad seleccionada antes de poder guardar."
|
|
3381
3389
|
},
|
|
3382
3390
|
"progress": {
|
|
3383
3391
|
"status": {
|
|
@@ -4869,5 +4877,50 @@
|
|
|
4869
4877
|
"count": "{attempts} de {max}",
|
|
4870
4878
|
"footer": "El bucle se repite hasta que el comando de validación pasa o se agota el presupuesto de iteraciones."
|
|
4871
4879
|
}
|
|
4880
|
+
},
|
|
4881
|
+
"skills": {
|
|
4882
|
+
"unavailable": "La biblioteca de Claude Skills no está habilitada en este despliegue.",
|
|
4883
|
+
"catalog": {
|
|
4884
|
+
"title": "Habilidades sincronizadas",
|
|
4885
|
+
"empty": "Aún no hay habilidades sincronizadas. Vincula una fuente de repositorio abajo para importar sus carpetas de habilidades.",
|
|
4886
|
+
"resources": "{count} recursos",
|
|
4887
|
+
"pinned": "fijada en {commit}"
|
|
4888
|
+
},
|
|
4889
|
+
"sources": {
|
|
4890
|
+
"title": "Fuentes de repositorio",
|
|
4891
|
+
"empty": "No hay fuentes de habilidades vinculadas. Vincula abajo un directorio de repositorio con carpetas de habilidades.",
|
|
4892
|
+
"linkTitle": "Vincular una fuente de habilidades",
|
|
4893
|
+
"link": "Vincular y sincronizar",
|
|
4894
|
+
"metaSynced": "sincronizada {date} · ref {ref}",
|
|
4895
|
+
"metaNever": "nunca sincronizada · ref {ref}",
|
|
4896
|
+
"changes": "Cambios",
|
|
4897
|
+
"check": "Buscar cambios",
|
|
4898
|
+
"sync": "Resincronizar",
|
|
4899
|
+
"unlink": "Desvincular",
|
|
4900
|
+
"browseHint": "Explora el repositorio y elige el directorio de carpetas de habilidades (o vincula todo el repo).",
|
|
4901
|
+
"selectedDir": "Directorio:",
|
|
4902
|
+
"wholeRepo": "Repositorio completo (raíz).",
|
|
4903
|
+
"ownerPlaceholder": "propietario",
|
|
4904
|
+
"repoPlaceholder": "repo",
|
|
4905
|
+
"dirPlaceholder": "ruta del directorio (p. ej. .claude/skills)",
|
|
4906
|
+
"refPlaceholder": "ref (por defecto HEAD)",
|
|
4907
|
+
"githubRequired": "Vincular una fuente de habilidades requiere la integración de GitHub. Conéctala primero en un tablero."
|
|
4908
|
+
},
|
|
4909
|
+
"confirmUnlinkSource": {
|
|
4910
|
+
"title": "¿Desvincular esta fuente?",
|
|
4911
|
+
"body": "\"{repo}\" y las habilidades que sincronizó se eliminarán. Puedes volver a vincularla más tarde.",
|
|
4912
|
+
"confirm": "Desvincular"
|
|
4913
|
+
},
|
|
4914
|
+
"toast": {
|
|
4915
|
+
"sourceLinked": "Fuente vinculada y sincronizada",
|
|
4916
|
+
"linkSourceFailed": "No se pudo vincular la fuente",
|
|
4917
|
+
"synced": "Sincronizado: {updated} actualizadas, {removed} eliminadas",
|
|
4918
|
+
"syncFailed": "No se pudo sincronizar la fuente",
|
|
4919
|
+
"changesAvailable": "Cambios disponibles",
|
|
4920
|
+
"upToDate": "Actualizado",
|
|
4921
|
+
"checkSourceFailed": "No se pudo comprobar la fuente",
|
|
4922
|
+
"sourceUnlinked": "Fuente desvinculada",
|
|
4923
|
+
"unlinkSourceFailed": "No se pudo desvincular la fuente"
|
|
4924
|
+
}
|
|
4872
4925
|
}
|
|
4873
4926
|
}
|
package/i18n/locales/fr.json
CHANGED
|
@@ -1875,6 +1875,9 @@
|
|
|
1875
1875
|
"deselect": "Désélectionner / fermer l'inspecteur",
|
|
1876
1876
|
"deleteBlock": "Supprimer le bloc sélectionné",
|
|
1877
1877
|
"help": "Afficher cet aide-mémoire"
|
|
1878
|
+
},
|
|
1879
|
+
"accountSkills": {
|
|
1880
|
+
"intro": "Reliez les dépôts où votre équipe crée des Claude Skills (un dossier SKILL.md plus des fichiers de ressources). Les compétences synchronisées rejoignent le catalogue de ce compte, partagé par tous les tableaux, et l'étape Skill d'un pipeline en exécute une sur une tâche."
|
|
1878
1881
|
}
|
|
1879
1882
|
},
|
|
1880
1883
|
"settings": {
|
|
@@ -1928,7 +1931,8 @@
|
|
|
1928
1931
|
"noAccount": "Aucun compte sélectionné.",
|
|
1929
1932
|
"tabs": {
|
|
1930
1933
|
"team": "Équipe et accès",
|
|
1931
|
-
"fragments": "Fragments de contexte"
|
|
1934
|
+
"fragments": "Fragments de contexte",
|
|
1935
|
+
"skills": "Compétences"
|
|
1932
1936
|
}
|
|
1933
1937
|
},
|
|
1934
1938
|
"providerConnection": {
|
|
@@ -3377,7 +3381,11 @@
|
|
|
3377
3381
|
"confirmDeletePipeline": {
|
|
3378
3382
|
"title": "Supprimer ce pipeline ?",
|
|
3379
3383
|
"body": "\"{name}\" sera supprimé. Cette action est irréversible."
|
|
3380
|
-
}
|
|
3384
|
+
},
|
|
3385
|
+
"skillPlaceholder": "Sélectionner une compétence",
|
|
3386
|
+
"skillNoneAvailable": "Aucune compétence disponible. Reliez une source de compétences dans les paramètres du compte.",
|
|
3387
|
+
"skillMissing": "Cette compétence n'est plus dans le catalogue ; choisissez-en une autre.",
|
|
3388
|
+
"skillNeedsPick": "Une étape Skill a besoin d'une compétence sélectionnée avant de pouvoir enregistrer."
|
|
3381
3389
|
},
|
|
3382
3390
|
"progress": {
|
|
3383
3391
|
"status": {
|
|
@@ -4869,5 +4877,50 @@
|
|
|
4869
4877
|
"count": "{attempts} sur {max}",
|
|
4870
4878
|
"footer": "La boucle réessaie jusqu'à ce que la commande de validation réussisse ou que le budget d'itérations soit épuisé."
|
|
4871
4879
|
}
|
|
4880
|
+
},
|
|
4881
|
+
"skills": {
|
|
4882
|
+
"unavailable": "La bibliothèque Claude Skills n'est pas activée pour ce déploiement.",
|
|
4883
|
+
"catalog": {
|
|
4884
|
+
"title": "Compétences synchronisées",
|
|
4885
|
+
"empty": "Aucune compétence synchronisée pour l'instant. Reliez une source de dépôt ci-dessous pour importer ses dossiers de compétences.",
|
|
4886
|
+
"resources": "{count} ressources",
|
|
4887
|
+
"pinned": "épinglée sur {commit}"
|
|
4888
|
+
},
|
|
4889
|
+
"sources": {
|
|
4890
|
+
"title": "Sources de dépôt",
|
|
4891
|
+
"empty": "Aucune source de compétences reliée. Reliez ci-dessous un répertoire de dépôt contenant des dossiers de compétences.",
|
|
4892
|
+
"linkTitle": "Relier une source de compétences",
|
|
4893
|
+
"link": "Relier et synchroniser",
|
|
4894
|
+
"metaSynced": "synchronisée {date} · réf {ref}",
|
|
4895
|
+
"metaNever": "jamais synchronisée · réf {ref}",
|
|
4896
|
+
"changes": "Modifications",
|
|
4897
|
+
"check": "Vérifier les modifications",
|
|
4898
|
+
"sync": "Resynchroniser",
|
|
4899
|
+
"unlink": "Dissocier",
|
|
4900
|
+
"browseHint": "Parcourez le dépôt et choisissez le répertoire des dossiers de compétences (ou reliez tout le dépôt).",
|
|
4901
|
+
"selectedDir": "Répertoire :",
|
|
4902
|
+
"wholeRepo": "Dépôt entier (racine).",
|
|
4903
|
+
"ownerPlaceholder": "propriétaire",
|
|
4904
|
+
"repoPlaceholder": "dépôt",
|
|
4905
|
+
"dirPlaceholder": "chemin du répertoire (p. ex. .claude/skills)",
|
|
4906
|
+
"refPlaceholder": "réf (HEAD par défaut)",
|
|
4907
|
+
"githubRequired": "Relier une source de compétences nécessite l'intégration GitHub. Connectez-la d'abord sur un tableau."
|
|
4908
|
+
},
|
|
4909
|
+
"confirmUnlinkSource": {
|
|
4910
|
+
"title": "Dissocier cette source ?",
|
|
4911
|
+
"body": "\"{repo}\" et les compétences qu'elle a synchronisées seront supprimées. Vous pourrez la relier de nouveau plus tard.",
|
|
4912
|
+
"confirm": "Dissocier"
|
|
4913
|
+
},
|
|
4914
|
+
"toast": {
|
|
4915
|
+
"sourceLinked": "Source reliée et synchronisée",
|
|
4916
|
+
"linkSourceFailed": "Impossible de relier la source",
|
|
4917
|
+
"synced": "Synchronisé : {updated} mises à jour, {removed} supprimées",
|
|
4918
|
+
"syncFailed": "Impossible de synchroniser la source",
|
|
4919
|
+
"changesAvailable": "Modifications disponibles",
|
|
4920
|
+
"upToDate": "À jour",
|
|
4921
|
+
"checkSourceFailed": "Impossible de vérifier la source",
|
|
4922
|
+
"sourceUnlinked": "Source dissociée",
|
|
4923
|
+
"unlinkSourceFailed": "Impossible de dissocier la source"
|
|
4924
|
+
}
|
|
4872
4925
|
}
|
|
4873
4926
|
}
|