@cat-factory/app 0.91.0 → 0.92.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/documents/DocumentTemplatesModal.vue +253 -0
- package/app/components/layout/IntegrationsHub.vue +12 -1
- package/app/composables/api/documents.ts +23 -1
- package/app/pages/index.vue +4 -0
- package/app/stores/documents.ts +64 -0
- package/app/stores/ui.ts +13 -0
- package/app/types/documents.ts +1 -0
- package/i18n/locales/en.json +27 -1
- package/i18n/locales/es.json +23 -0
- package/i18n/locales/fr.json +23 -0
- package/i18n/locales/he.json +31 -2
- package/i18n/locales/ja.json +27 -1
- package/i18n/locales/pl.json +23 -0
- package/i18n/locales/tr.json +27 -1
- package/i18n/locales/uk.json +23 -0
- package/package.json +2 -2
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { DOC_KINDS } from '~/types/domain'
|
|
3
|
+
import type { DocKind, DocumentLinkRole, SourceDocument } from '~/types/domain'
|
|
4
|
+
import IntegrationBackTitle from '~/components/layout/IntegrationBackTitle.vue'
|
|
5
|
+
|
|
6
|
+
// Manage the workspace's per-DocKind TEMPLATE (singular) + EXEMPLAR (multi) document links (WS1).
|
|
7
|
+
// A kind can be pointed at one of the workspace's already-imported documents so its parsed
|
|
8
|
+
// sections override the built-in skeleton (template) and the author agents study it (exemplar).
|
|
9
|
+
// Reuses the same imported-document corpus as context linking — no new fetch surface.
|
|
10
|
+
const { t } = useI18n()
|
|
11
|
+
const ui = useUiStore()
|
|
12
|
+
const documents = useDocumentsStore()
|
|
13
|
+
const toast = useToast()
|
|
14
|
+
|
|
15
|
+
const open = computed({
|
|
16
|
+
get: () => ui.documentTemplates,
|
|
17
|
+
set: (v: boolean) => {
|
|
18
|
+
if (!v) ui.closeDocumentTemplates()
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
const back = useIntegrationBack(open)
|
|
22
|
+
|
|
23
|
+
const kind = ref<DocKind>('prd')
|
|
24
|
+
const busy = ref(false)
|
|
25
|
+
/** The imported document (`source:externalId`) selected in the "add" picker. */
|
|
26
|
+
const pick = ref<string | undefined>(undefined)
|
|
27
|
+
|
|
28
|
+
watch(
|
|
29
|
+
open,
|
|
30
|
+
(isOpen) => {
|
|
31
|
+
if (isOpen) {
|
|
32
|
+
pick.value = undefined
|
|
33
|
+
// Surface a load failure instead of silently rendering an empty panel (which would invite
|
|
34
|
+
// re-linking over links that still exist server-side).
|
|
35
|
+
Promise.all([documents.loadDocuments(), documents.loadRoleLinks()]).catch((e) => {
|
|
36
|
+
toast.add({
|
|
37
|
+
title: t('documents.templates.loadFailed'),
|
|
38
|
+
description: e instanceof Error ? e.message : String(e),
|
|
39
|
+
icon: 'i-lucide-triangle-alert',
|
|
40
|
+
color: 'error',
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{ immediate: true },
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
const template = computed(() => documents.templateFor(kind.value))
|
|
49
|
+
const exemplars = computed(() => documents.exemplarsFor(kind.value))
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Imported documents the picker offers. A document row carries at most ONE (role, docKind) tag, so
|
|
53
|
+
* a doc already linked as any template/exemplar is excluded — re-linking it here would silently
|
|
54
|
+
* overwrite (and drop) its existing tag. Remove the existing link first to re-point it.
|
|
55
|
+
*/
|
|
56
|
+
const docItems = computed(() => {
|
|
57
|
+
const tagged = new Set(documents.roleLinks.map((d) => `${d.source}:${d.externalId}`))
|
|
58
|
+
return documents.documents
|
|
59
|
+
.filter((d) => !tagged.has(`${d.source}:${d.externalId}`))
|
|
60
|
+
.map((d) => ({ label: d.title, value: `${d.source}:${d.externalId}` }))
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
function findDoc(key: string): SourceDocument | undefined {
|
|
64
|
+
return documents.documents.find((d) => `${d.source}:${d.externalId}` === key)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function link(role: DocumentLinkRole) {
|
|
68
|
+
const doc = pick.value ? findDoc(pick.value) : undefined
|
|
69
|
+
if (!doc) return
|
|
70
|
+
busy.value = true
|
|
71
|
+
try {
|
|
72
|
+
await documents.linkForKind(doc.source, doc.externalId, role, kind.value)
|
|
73
|
+
pick.value = undefined
|
|
74
|
+
} catch (e) {
|
|
75
|
+
toast.add({
|
|
76
|
+
title: t('documents.templates.linkFailed'),
|
|
77
|
+
description: e instanceof Error ? e.message : String(e),
|
|
78
|
+
icon: 'i-lucide-triangle-alert',
|
|
79
|
+
color: 'error',
|
|
80
|
+
})
|
|
81
|
+
} finally {
|
|
82
|
+
busy.value = false
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function unlink(doc: SourceDocument) {
|
|
87
|
+
busy.value = true
|
|
88
|
+
try {
|
|
89
|
+
await documents.unlinkForKind(doc.source, doc.externalId)
|
|
90
|
+
} catch (e) {
|
|
91
|
+
toast.add({
|
|
92
|
+
title: t('documents.templates.linkFailed'),
|
|
93
|
+
description: e instanceof Error ? e.message : String(e),
|
|
94
|
+
icon: 'i-lucide-triangle-alert',
|
|
95
|
+
color: 'error',
|
|
96
|
+
})
|
|
97
|
+
} finally {
|
|
98
|
+
busy.value = false
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<template>
|
|
104
|
+
<UModal v-model:open="open" :title="t('documents.templates.title')">
|
|
105
|
+
<template #title>
|
|
106
|
+
<IntegrationBackTitle :title="t('documents.templates.title')" @back="back" />
|
|
107
|
+
</template>
|
|
108
|
+
<template #body>
|
|
109
|
+
<div class="space-y-4">
|
|
110
|
+
<p class="text-xs text-slate-400">{{ t('documents.templates.intro') }}</p>
|
|
111
|
+
|
|
112
|
+
<!-- No imported documents yet: a template/exemplar must be an imported document. -->
|
|
113
|
+
<div v-if="!documents.documents.length" class="space-y-3 text-center">
|
|
114
|
+
<UIcon name="i-lucide-file-plus" class="mx-auto h-8 w-8 text-slate-500" />
|
|
115
|
+
<p class="text-sm text-slate-400">{{ t('documents.templates.importFirst') }}</p>
|
|
116
|
+
<UButton
|
|
117
|
+
color="primary"
|
|
118
|
+
variant="soft"
|
|
119
|
+
icon="i-lucide-file-down"
|
|
120
|
+
@click="ui.openDocumentImport(null)"
|
|
121
|
+
>
|
|
122
|
+
{{ t('documents.templates.importButton') }}
|
|
123
|
+
</UButton>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<template v-else>
|
|
127
|
+
<UFormField :label="t('documents.templates.kindLabel')">
|
|
128
|
+
<div class="flex flex-wrap gap-1">
|
|
129
|
+
<UButton
|
|
130
|
+
v-for="k in DOC_KINDS"
|
|
131
|
+
:key="k"
|
|
132
|
+
:color="kind === k ? 'primary' : 'neutral'"
|
|
133
|
+
:variant="kind === k ? 'soft' : 'ghost'"
|
|
134
|
+
size="xs"
|
|
135
|
+
class="uppercase"
|
|
136
|
+
@click="kind = k"
|
|
137
|
+
>
|
|
138
|
+
{{ k }}
|
|
139
|
+
</UButton>
|
|
140
|
+
</div>
|
|
141
|
+
</UFormField>
|
|
142
|
+
|
|
143
|
+
<!-- Template (singular per kind) ------------------------------------ -->
|
|
144
|
+
<section class="rounded-lg border border-slate-800 bg-slate-900/50 p-3">
|
|
145
|
+
<h3 class="text-[11px] font-semibold uppercase tracking-wide text-slate-400">
|
|
146
|
+
{{ t('documents.templates.templateHeading') }}
|
|
147
|
+
</h3>
|
|
148
|
+
<p class="mt-0.5 text-xs text-slate-500">
|
|
149
|
+
{{ t('documents.templates.templateHint', { kind }) }}
|
|
150
|
+
</p>
|
|
151
|
+
<div
|
|
152
|
+
v-if="template"
|
|
153
|
+
class="mt-2 flex items-center justify-between gap-2 rounded-md bg-slate-900/70 px-3 py-2"
|
|
154
|
+
>
|
|
155
|
+
<a
|
|
156
|
+
:href="template.url"
|
|
157
|
+
target="_blank"
|
|
158
|
+
rel="noopener"
|
|
159
|
+
class="truncate text-sm font-medium text-white hover:underline"
|
|
160
|
+
>
|
|
161
|
+
{{ template.title }}
|
|
162
|
+
</a>
|
|
163
|
+
<UButton
|
|
164
|
+
color="neutral"
|
|
165
|
+
variant="ghost"
|
|
166
|
+
size="xs"
|
|
167
|
+
icon="i-lucide-x"
|
|
168
|
+
:loading="busy"
|
|
169
|
+
@click="unlink(template)"
|
|
170
|
+
>
|
|
171
|
+
{{ t('documents.templates.remove') }}
|
|
172
|
+
</UButton>
|
|
173
|
+
</div>
|
|
174
|
+
<p v-else class="mt-2 text-xs text-slate-500">
|
|
175
|
+
{{ t('documents.templates.templateEmpty') }}
|
|
176
|
+
</p>
|
|
177
|
+
</section>
|
|
178
|
+
|
|
179
|
+
<!-- Exemplars (multi per kind) -------------------------------------- -->
|
|
180
|
+
<section class="rounded-lg border border-slate-800 bg-slate-900/50 p-3">
|
|
181
|
+
<h3 class="text-[11px] font-semibold uppercase tracking-wide text-slate-400">
|
|
182
|
+
{{ t('documents.templates.exemplarsHeading') }}
|
|
183
|
+
</h3>
|
|
184
|
+
<p class="mt-0.5 text-xs text-slate-500">
|
|
185
|
+
{{ t('documents.templates.exemplarsHint') }}
|
|
186
|
+
</p>
|
|
187
|
+
<div v-if="exemplars.length" class="mt-2 space-y-1.5">
|
|
188
|
+
<div
|
|
189
|
+
v-for="doc in exemplars"
|
|
190
|
+
:key="`${doc.source}:${doc.externalId}`"
|
|
191
|
+
class="flex items-center justify-between gap-2 rounded-md bg-slate-900/70 px-3 py-2"
|
|
192
|
+
>
|
|
193
|
+
<a
|
|
194
|
+
:href="doc.url"
|
|
195
|
+
target="_blank"
|
|
196
|
+
rel="noopener"
|
|
197
|
+
class="truncate text-sm font-medium text-white hover:underline"
|
|
198
|
+
>
|
|
199
|
+
{{ doc.title }}
|
|
200
|
+
</a>
|
|
201
|
+
<UButton
|
|
202
|
+
color="neutral"
|
|
203
|
+
variant="ghost"
|
|
204
|
+
size="xs"
|
|
205
|
+
icon="i-lucide-x"
|
|
206
|
+
:loading="busy"
|
|
207
|
+
@click="unlink(doc)"
|
|
208
|
+
>
|
|
209
|
+
{{ t('documents.templates.remove') }}
|
|
210
|
+
</UButton>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
<p v-else class="mt-2 text-xs text-slate-500">
|
|
214
|
+
{{ t('documents.templates.exemplarsEmpty') }}
|
|
215
|
+
</p>
|
|
216
|
+
</section>
|
|
217
|
+
|
|
218
|
+
<!-- Picker: choose an imported document, then set as template or add as example. -->
|
|
219
|
+
<div class="flex items-end gap-2">
|
|
220
|
+
<UFormField :label="t('documents.templates.pickLabel')" class="flex-1">
|
|
221
|
+
<USelect
|
|
222
|
+
v-model="pick"
|
|
223
|
+
:items="docItems"
|
|
224
|
+
:placeholder="t('documents.templates.pickPlaceholder')"
|
|
225
|
+
class="w-full"
|
|
226
|
+
/>
|
|
227
|
+
</UFormField>
|
|
228
|
+
<UButton
|
|
229
|
+
color="primary"
|
|
230
|
+
variant="soft"
|
|
231
|
+
icon="i-lucide-file-badge"
|
|
232
|
+
:loading="busy"
|
|
233
|
+
:disabled="!pick"
|
|
234
|
+
@click="link('template')"
|
|
235
|
+
>
|
|
236
|
+
{{ t('documents.templates.setTemplate') }}
|
|
237
|
+
</UButton>
|
|
238
|
+
<UButton
|
|
239
|
+
color="neutral"
|
|
240
|
+
variant="soft"
|
|
241
|
+
icon="i-lucide-star"
|
|
242
|
+
:loading="busy"
|
|
243
|
+
:disabled="!pick"
|
|
244
|
+
@click="link('exemplar')"
|
|
245
|
+
>
|
|
246
|
+
{{ t('documents.templates.addExemplar') }}
|
|
247
|
+
</UButton>
|
|
248
|
+
</div>
|
|
249
|
+
</template>
|
|
250
|
+
</div>
|
|
251
|
+
</template>
|
|
252
|
+
</UModal>
|
|
253
|
+
</template>
|
|
@@ -194,7 +194,18 @@ const groups = computed<IntegrationGroup[]>(() => {
|
|
|
194
194
|
onClick: () => go(() => ui.openDocumentImport(null)),
|
|
195
195
|
})
|
|
196
196
|
}
|
|
197
|
-
|
|
197
|
+
// Per-DocKind template + exemplar links are workspace CONFIG over the imported corpus, not an
|
|
198
|
+
// integration to connect — so they sit as a quiet footer link under the sources.
|
|
199
|
+
out.push({
|
|
200
|
+
title: t('layout.integrationsHub.groups.documents'),
|
|
201
|
+
items: docs,
|
|
202
|
+
footerLink: {
|
|
203
|
+
key: 'doc:templates',
|
|
204
|
+
icon: 'i-lucide-file-badge',
|
|
205
|
+
label: t('layout.integrationsHub.items.documentTemplates.label'),
|
|
206
|
+
onClick: () => go(() => ui.openDocumentTemplates()),
|
|
207
|
+
},
|
|
208
|
+
})
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
// --- Task trackers (dynamic sources: Jira / GitHub) ------------------------
|
|
@@ -3,14 +3,17 @@ import {
|
|
|
3
3
|
disconnectDocumentSourceContract,
|
|
4
4
|
importDocumentContract,
|
|
5
5
|
linkDocumentContract,
|
|
6
|
+
linkDocumentForKindContract,
|
|
6
7
|
listDocumentConnectionsContract,
|
|
8
|
+
listDocumentRoleLinksContract,
|
|
7
9
|
listDocumentsContract,
|
|
8
10
|
listDocumentSourcesContract,
|
|
9
11
|
planDocumentContract,
|
|
10
12
|
searchDocumentsContract,
|
|
11
13
|
spawnDocumentContract,
|
|
14
|
+
unlinkDocumentForKindContract,
|
|
12
15
|
} from '@cat-factory/contracts'
|
|
13
|
-
import type { DocumentSourceKind } from '~/types/domain'
|
|
16
|
+
import type { DocKind, DocumentLinkRole, DocumentSourceKind } from '~/types/domain'
|
|
14
17
|
import type { ApiContext } from './context'
|
|
15
18
|
|
|
16
19
|
/** Document sources (Confluence, Notion, …): connect, import, search, board-spawn. */
|
|
@@ -72,5 +75,24 @@ export function documentsApi({ send, ws }: ApiContext) {
|
|
|
72
75
|
workspaceId: string,
|
|
73
76
|
body: { source: DocumentSourceKind; externalId: string; blockId: string },
|
|
74
77
|
) => send(linkDocumentContract, { pathPrefix: ws(workspaceId), body }),
|
|
78
|
+
|
|
79
|
+
// ---- workspace+DocKind template / exemplar links (WS1) ----------------
|
|
80
|
+
listDocumentRoleLinks: (workspaceId: string) =>
|
|
81
|
+
send(listDocumentRoleLinksContract, { pathPrefix: ws(workspaceId) }),
|
|
82
|
+
|
|
83
|
+
linkDocumentForKind: (
|
|
84
|
+
workspaceId: string,
|
|
85
|
+
body: {
|
|
86
|
+
source: DocumentSourceKind
|
|
87
|
+
externalId: string
|
|
88
|
+
role: DocumentLinkRole
|
|
89
|
+
docKind: DocKind
|
|
90
|
+
},
|
|
91
|
+
) => send(linkDocumentForKindContract, { pathPrefix: ws(workspaceId), body }),
|
|
92
|
+
|
|
93
|
+
unlinkDocumentForKind: (
|
|
94
|
+
workspaceId: string,
|
|
95
|
+
body: { source: DocumentSourceKind; externalId: string },
|
|
96
|
+
) => send(unlinkDocumentForKindContract, { pathPrefix: ws(workspaceId), body }),
|
|
75
97
|
}
|
|
76
98
|
}
|
package/app/pages/index.vue
CHANGED
|
@@ -47,6 +47,9 @@ const DocumentSourceConnectModal = defineAsyncComponent(
|
|
|
47
47
|
const DocumentImportModal = defineAsyncComponent(
|
|
48
48
|
() => import('~/components/documents/DocumentImportModal.vue'),
|
|
49
49
|
)
|
|
50
|
+
const DocumentTemplatesModal = defineAsyncComponent(
|
|
51
|
+
() => import('~/components/documents/DocumentTemplatesModal.vue'),
|
|
52
|
+
)
|
|
50
53
|
const SpawnPreviewModal = defineAsyncComponent(
|
|
51
54
|
() => import('~/components/documents/SpawnPreviewModal.vue'),
|
|
52
55
|
)
|
|
@@ -347,6 +350,7 @@ watch(
|
|
|
347
350
|
<KaizenPanel v-if="ui.kaizenScreenOpen" />
|
|
348
351
|
<DocumentSourceConnectModal v-if="ui.documentConnect" />
|
|
349
352
|
<DocumentImportModal v-if="ui.documentImport" />
|
|
353
|
+
<DocumentTemplatesModal v-if="ui.documentTemplates" />
|
|
350
354
|
<SpawnPreviewModal v-if="ui.spawnPreview" />
|
|
351
355
|
<BootstrapModal v-if="ui.bootstrapOpen" />
|
|
352
356
|
<AddServiceFromRepoModal v-if="ui.addServiceOpen" />
|
package/app/stores/documents.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { defineStore } from 'pinia'
|
|
2
2
|
import { ref } from 'vue'
|
|
3
3
|
import type {
|
|
4
|
+
DocKind,
|
|
4
5
|
DocumentBoardPlan,
|
|
5
6
|
DocumentConnection,
|
|
7
|
+
DocumentLinkRole,
|
|
6
8
|
DocumentSearchResult,
|
|
7
9
|
DocumentSourceDescriptor,
|
|
8
10
|
DocumentSourceKind,
|
|
@@ -50,6 +52,10 @@ export const useDocumentsStore = defineStore('documents', () => {
|
|
|
50
52
|
})
|
|
51
53
|
const loading = ref(false)
|
|
52
54
|
|
|
55
|
+
// Workspace+DocKind template / exemplar role links (WS1). Loaded lazily when the management
|
|
56
|
+
// panel opens; the full list of role-tagged documents across kinds.
|
|
57
|
+
const roleLinks = ref<SourceDocument[]>([])
|
|
58
|
+
|
|
53
59
|
/** Imported documents currently attached to a given block. */
|
|
54
60
|
function docsForBlock(blockId: string): SourceDocument[] {
|
|
55
61
|
return documents.value.filter((d) => d.linkedBlockId === blockId)
|
|
@@ -116,6 +122,58 @@ export const useDocumentsStore = defineStore('documents', () => {
|
|
|
116
122
|
return doc
|
|
117
123
|
}
|
|
118
124
|
|
|
125
|
+
// ---- workspace+DocKind template / exemplar links (WS1) ------------------
|
|
126
|
+
|
|
127
|
+
/** Load every role-tagged (template/exemplar) document for the workspace. */
|
|
128
|
+
async function loadRoleLinks() {
|
|
129
|
+
roleLinks.value = await api.listDocumentRoleLinks(workspace.requireId())
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** The current template link for a kind (singular), if any. */
|
|
133
|
+
function templateFor(docKind: DocKind): SourceDocument | undefined {
|
|
134
|
+
return roleLinks.value.find((d) => d.role === 'template' && d.docKind === docKind)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** The exemplar links for a kind (multi-valued). */
|
|
138
|
+
function exemplarsFor(docKind: DocKind): SourceDocument[] {
|
|
139
|
+
return roleLinks.value.filter((d) => d.role === 'exemplar' && d.docKind === docKind)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Tag an imported document as the workspace's template (singular per kind) or exemplar for a
|
|
144
|
+
* kind, then reconcile the local list (a template replaces the prior one for its kind).
|
|
145
|
+
*/
|
|
146
|
+
async function linkForKind(
|
|
147
|
+
source: DocumentSourceKind,
|
|
148
|
+
externalId: string,
|
|
149
|
+
role: DocumentLinkRole,
|
|
150
|
+
docKind: DocKind,
|
|
151
|
+
) {
|
|
152
|
+
const doc = await api.linkDocumentForKind(workspace.requireId(), {
|
|
153
|
+
source,
|
|
154
|
+
externalId,
|
|
155
|
+
role,
|
|
156
|
+
docKind,
|
|
157
|
+
})
|
|
158
|
+
const key = (d: SourceDocument) => `${d.source}:${d.externalId}`
|
|
159
|
+
// Drop any row for this doc, plus the prior template for this kind (singular replace).
|
|
160
|
+
roleLinks.value = roleLinks.value.filter(
|
|
161
|
+
(d) =>
|
|
162
|
+
key(d) !== key(doc) &&
|
|
163
|
+
!(role === 'template' && d.role === 'template' && d.docKind === docKind),
|
|
164
|
+
)
|
|
165
|
+
roleLinks.value.push(doc)
|
|
166
|
+
return doc
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Clear a document's role tag (built-in template resumes for the kind / exemplar drops). */
|
|
170
|
+
async function unlinkForKind(source: DocumentSourceKind, externalId: string) {
|
|
171
|
+
await api.unlinkDocumentForKind(workspace.requireId(), { source, externalId })
|
|
172
|
+
roleLinks.value = roleLinks.value.filter(
|
|
173
|
+
(d) => !(d.source === source && d.externalId === externalId),
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
119
177
|
return {
|
|
120
178
|
available,
|
|
121
179
|
sources,
|
|
@@ -137,5 +195,11 @@ export const useDocumentsStore = defineStore('documents', () => {
|
|
|
137
195
|
plan,
|
|
138
196
|
spawn,
|
|
139
197
|
linkToBlock,
|
|
198
|
+
roleLinks,
|
|
199
|
+
loadRoleLinks,
|
|
200
|
+
templateFor,
|
|
201
|
+
exemplarsFor,
|
|
202
|
+
linkForKind,
|
|
203
|
+
unlinkForKind,
|
|
140
204
|
}
|
|
141
205
|
})
|
package/app/stores/ui.ts
CHANGED
|
@@ -56,6 +56,9 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
56
56
|
source: DocumentSourceKind | null
|
|
57
57
|
targetFrameId: string | null
|
|
58
58
|
} | null>(null)
|
|
59
|
+
// The workspace+DocKind template / exemplar management modal (WS1). A single boolean —
|
|
60
|
+
// it manages every kind's links in one place.
|
|
61
|
+
const documentTemplates = ref(false)
|
|
59
62
|
const spawnPreview = ref<{
|
|
60
63
|
source: DocumentSourceKind
|
|
61
64
|
externalId: string
|
|
@@ -390,6 +393,13 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
390
393
|
function closeDocumentImport() {
|
|
391
394
|
documentImport.value = null
|
|
392
395
|
}
|
|
396
|
+
function openDocumentTemplates() {
|
|
397
|
+
resetHubReturn()
|
|
398
|
+
documentTemplates.value = true
|
|
399
|
+
}
|
|
400
|
+
function closeDocumentTemplates() {
|
|
401
|
+
documentTemplates.value = false
|
|
402
|
+
}
|
|
393
403
|
function openSpawnPreview(
|
|
394
404
|
source: DocumentSourceKind,
|
|
395
405
|
externalId: string,
|
|
@@ -796,6 +806,7 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
796
806
|
decisionContext,
|
|
797
807
|
documentConnect,
|
|
798
808
|
documentImport,
|
|
809
|
+
documentTemplates,
|
|
799
810
|
spawnPreview,
|
|
800
811
|
taskConnect,
|
|
801
812
|
taskImport,
|
|
@@ -866,6 +877,8 @@ export const useUiStore = defineStore('ui', () => {
|
|
|
866
877
|
closeDocumentConnect,
|
|
867
878
|
openDocumentImport,
|
|
868
879
|
closeDocumentImport,
|
|
880
|
+
openDocumentTemplates,
|
|
881
|
+
closeDocumentTemplates,
|
|
869
882
|
openSpawnPreview,
|
|
870
883
|
closeSpawnPreview,
|
|
871
884
|
openTaskConnect,
|
package/app/types/documents.ts
CHANGED
package/i18n/locales/en.json
CHANGED
|
@@ -210,7 +210,10 @@
|
|
|
210
210
|
"label": "Options to compare",
|
|
211
211
|
"placeholder": "The options to weigh against each other"
|
|
212
212
|
},
|
|
213
|
-
"apiSurface": {
|
|
213
|
+
"apiSurface": {
|
|
214
|
+
"label": "API surface",
|
|
215
|
+
"placeholder": "The endpoints or surface in scope"
|
|
216
|
+
}
|
|
214
217
|
},
|
|
215
218
|
"optional": "optional",
|
|
216
219
|
"pipeline": "Pipeline",
|
|
@@ -1634,6 +1637,9 @@
|
|
|
1634
1637
|
"localRunners": {
|
|
1635
1638
|
"label": "My local runners",
|
|
1636
1639
|
"description": "Your own-machine model runners (Ollama, LM Studio, vLLM…)."
|
|
1640
|
+
},
|
|
1641
|
+
"documentTemplates": {
|
|
1642
|
+
"label": "Templates & examples"
|
|
1637
1643
|
}
|
|
1638
1644
|
}
|
|
1639
1645
|
}
|
|
@@ -2772,6 +2778,26 @@
|
|
|
2772
2778
|
"empty": "Attach a requirement, RFC or PRD so agents see it while implementing this task.",
|
|
2773
2779
|
"attached": "Document attached",
|
|
2774
2780
|
"attachFailed": "Could not attach"
|
|
2781
|
+
},
|
|
2782
|
+
"templates": {
|
|
2783
|
+
"title": "Document templates & examples",
|
|
2784
|
+
"intro": "Point a document kind at your own template and example documents. They must be imported first via the Documents integration. A template's sections replace the built-in skeleton for that kind; the examples guide the author agents.",
|
|
2785
|
+
"kindLabel": "Document kind",
|
|
2786
|
+
"importFirst": "Import a document first — a template or example is one of your imported documents.",
|
|
2787
|
+
"importButton": "Import a document",
|
|
2788
|
+
"templateHeading": "Template",
|
|
2789
|
+
"templateHint": "Overrides the built-in {kind} skeleton. One template per kind.",
|
|
2790
|
+
"templateEmpty": "Using the built-in template.",
|
|
2791
|
+
"exemplarsHeading": "Examples to emulate",
|
|
2792
|
+
"exemplarsHint": "Good examples the author agents study, added to the built-in set.",
|
|
2793
|
+
"exemplarsEmpty": "No examples linked.",
|
|
2794
|
+
"pickLabel": "Imported document",
|
|
2795
|
+
"pickPlaceholder": "Choose an imported document…",
|
|
2796
|
+
"setTemplate": "Set as template",
|
|
2797
|
+
"addExemplar": "Add example",
|
|
2798
|
+
"remove": "Remove",
|
|
2799
|
+
"linkFailed": "Couldn't update the document link",
|
|
2800
|
+
"loadFailed": "Couldn't load document templates"
|
|
2775
2801
|
}
|
|
2776
2802
|
},
|
|
2777
2803
|
"tasks": {
|
package/i18n/locales/es.json
CHANGED
|
@@ -1584,6 +1584,9 @@
|
|
|
1584
1584
|
"localRunners": {
|
|
1585
1585
|
"label": "Mis ejecutores locales",
|
|
1586
1586
|
"description": "Tus ejecutores de modelos en tu propia máquina (Ollama, LM Studio, vLLM…)."
|
|
1587
|
+
},
|
|
1588
|
+
"documentTemplates": {
|
|
1589
|
+
"label": "Plantillas y ejemplos"
|
|
1587
1590
|
}
|
|
1588
1591
|
}
|
|
1589
1592
|
},
|
|
@@ -2702,6 +2705,26 @@
|
|
|
2702
2705
|
"empty": "Adjunta un requisito, RFC o PRD para que los agentes lo vean mientras implementan esta tarea.",
|
|
2703
2706
|
"attached": "Documento adjuntado",
|
|
2704
2707
|
"attachFailed": "No se pudo adjuntar"
|
|
2708
|
+
},
|
|
2709
|
+
"templates": {
|
|
2710
|
+
"title": "Plantillas y ejemplos de documentos",
|
|
2711
|
+
"intro": "Asigna a un tipo de documento tu propia plantilla y documentos de ejemplo. Primero deben importarse mediante la integración de Documentos. Las secciones de una plantilla reemplazan el esqueleto integrado de ese tipo; los ejemplos guían a los agentes autores.",
|
|
2712
|
+
"kindLabel": "Tipo de documento",
|
|
2713
|
+
"importFirst": "Importa primero un documento: una plantilla o ejemplo es uno de tus documentos importados.",
|
|
2714
|
+
"importButton": "Importar un documento",
|
|
2715
|
+
"templateHeading": "Plantilla",
|
|
2716
|
+
"templateHint": "Reemplaza el esqueleto integrado de {kind}. Una plantilla por tipo.",
|
|
2717
|
+
"templateEmpty": "Usando la plantilla integrada.",
|
|
2718
|
+
"exemplarsHeading": "Ejemplos a emular",
|
|
2719
|
+
"exemplarsHint": "Buenos ejemplos que estudian los agentes autores, añadidos al conjunto integrado.",
|
|
2720
|
+
"exemplarsEmpty": "No hay ejemplos vinculados.",
|
|
2721
|
+
"pickLabel": "Documento importado",
|
|
2722
|
+
"pickPlaceholder": "Elige un documento importado…",
|
|
2723
|
+
"setTemplate": "Establecer como plantilla",
|
|
2724
|
+
"addExemplar": "Añadir ejemplo",
|
|
2725
|
+
"remove": "Quitar",
|
|
2726
|
+
"linkFailed": "No se pudo actualizar el vínculo del documento",
|
|
2727
|
+
"loadFailed": "No se pudieron cargar las plantillas de documentos"
|
|
2705
2728
|
}
|
|
2706
2729
|
},
|
|
2707
2730
|
"tasks": {
|
package/i18n/locales/fr.json
CHANGED
|
@@ -1584,6 +1584,9 @@
|
|
|
1584
1584
|
"localRunners": {
|
|
1585
1585
|
"label": "Mes exécuteurs locaux",
|
|
1586
1586
|
"description": "Vos exécuteurs de modèles sur votre propre machine (Ollama, LM Studio, vLLM…)."
|
|
1587
|
+
},
|
|
1588
|
+
"documentTemplates": {
|
|
1589
|
+
"label": "Modèles et exemples"
|
|
1587
1590
|
}
|
|
1588
1591
|
}
|
|
1589
1592
|
},
|
|
@@ -2702,6 +2705,26 @@
|
|
|
2702
2705
|
"empty": "Joignez une exigence, un RFC ou un PRD pour que les agents le voient pendant l'implémentation de cette tâche.",
|
|
2703
2706
|
"attached": "Document joint",
|
|
2704
2707
|
"attachFailed": "Impossible de joindre"
|
|
2708
|
+
},
|
|
2709
|
+
"templates": {
|
|
2710
|
+
"title": "Modèles et exemples de documents",
|
|
2711
|
+
"intro": "Associez à un type de document votre propre modèle et des documents d'exemple. Ils doivent d'abord être importés via l'intégration Documents. Les sections d'un modèle remplacent le squelette intégré de ce type ; les exemples guident les agents rédacteurs.",
|
|
2712
|
+
"kindLabel": "Type de document",
|
|
2713
|
+
"importFirst": "Importez d'abord un document : un modèle ou un exemple est l'un de vos documents importés.",
|
|
2714
|
+
"importButton": "Importer un document",
|
|
2715
|
+
"templateHeading": "Modèle",
|
|
2716
|
+
"templateHint": "Remplace le squelette intégré de {kind}. Un modèle par type.",
|
|
2717
|
+
"templateEmpty": "Utilisation du modèle intégré.",
|
|
2718
|
+
"exemplarsHeading": "Exemples à suivre",
|
|
2719
|
+
"exemplarsHint": "De bons exemples que les agents rédacteurs étudient, ajoutés à l'ensemble intégré.",
|
|
2720
|
+
"exemplarsEmpty": "Aucun exemple lié.",
|
|
2721
|
+
"pickLabel": "Document importé",
|
|
2722
|
+
"pickPlaceholder": "Choisissez un document importé…",
|
|
2723
|
+
"setTemplate": "Définir comme modèle",
|
|
2724
|
+
"addExemplar": "Ajouter un exemple",
|
|
2725
|
+
"remove": "Retirer",
|
|
2726
|
+
"linkFailed": "Impossible de mettre à jour le lien du document",
|
|
2727
|
+
"loadFailed": "Impossible de charger les modèles de documents"
|
|
2705
2728
|
}
|
|
2706
2729
|
},
|
|
2707
2730
|
"tasks": {
|
package/i18n/locales/he.json
CHANGED
|
@@ -156,7 +156,10 @@
|
|
|
156
156
|
"label": "משתמשי היעד",
|
|
157
157
|
"placeholder": "למי מיועד המסמך ואילו משימות הם מבצעים"
|
|
158
158
|
},
|
|
159
|
-
"successMetrics": {
|
|
159
|
+
"successMetrics": {
|
|
160
|
+
"label": "מדדי הצלחה",
|
|
161
|
+
"placeholder": "תוצאות מדידות שמראות שזה עובד"
|
|
162
|
+
},
|
|
160
163
|
"alternativesConsidered": {
|
|
161
164
|
"label": "חלופות שנשקלו",
|
|
162
165
|
"placeholder": "גישות אחרות שנשקלו ומדוע נפסלו"
|
|
@@ -189,7 +192,10 @@
|
|
|
189
192
|
"label": "אפשרויות להשוואה",
|
|
190
193
|
"placeholder": "האפשרויות שיש לשקול זו מול זו"
|
|
191
194
|
},
|
|
192
|
-
"apiSurface": {
|
|
195
|
+
"apiSurface": {
|
|
196
|
+
"label": "משטח ה-API",
|
|
197
|
+
"placeholder": "נקודות הקצה או המשטח שבתחום"
|
|
198
|
+
}
|
|
193
199
|
},
|
|
194
200
|
"optional": "אופציונלי",
|
|
195
201
|
"pipeline": "צינור",
|
|
@@ -1578,6 +1584,9 @@
|
|
|
1578
1584
|
"localRunners": {
|
|
1579
1585
|
"label": "המריצים המקומיים שלי",
|
|
1580
1586
|
"description": "מריצי מודלים על המכונה שלך (Ollama, LM Studio, vLLM…)."
|
|
1587
|
+
},
|
|
1588
|
+
"documentTemplates": {
|
|
1589
|
+
"label": "תבניות ודוגמאות"
|
|
1581
1590
|
}
|
|
1582
1591
|
}
|
|
1583
1592
|
},
|
|
@@ -2707,6 +2716,26 @@
|
|
|
2707
2716
|
"empty": "צרף דרישה, RFC או PRD כדי שהסוכנים יראו אותם בעת מימוש משימה זו.",
|
|
2708
2717
|
"attached": "המסמך צורף",
|
|
2709
2718
|
"attachFailed": "לא ניתן לצרף"
|
|
2719
|
+
},
|
|
2720
|
+
"templates": {
|
|
2721
|
+
"title": "תבניות ודוגמאות למסמכים",
|
|
2722
|
+
"intro": "כוונו סוג מסמך לתבנית משלכם ולמסמכי דוגמה. יש לייבא אותם תחילה דרך שילוב המסמכים. הסעיפים של תבנית מחליפים את השלד המובנה של אותו סוג; הדוגמאות מנחות את סוכני הכתיבה.",
|
|
2723
|
+
"kindLabel": "סוג מסמך",
|
|
2724
|
+
"importFirst": "ייבאו קודם מסמך — תבנית או דוגמה היא אחד מהמסמכים המיובאים שלכם.",
|
|
2725
|
+
"importButton": "ייבוא מסמך",
|
|
2726
|
+
"templateHeading": "תבנית",
|
|
2727
|
+
"templateHint": "מחליפה את השלד המובנה של {kind}. תבנית אחת לכל סוג.",
|
|
2728
|
+
"templateEmpty": "נעשה שימוש בתבנית המובנית.",
|
|
2729
|
+
"exemplarsHeading": "דוגמאות לחיקוי",
|
|
2730
|
+
"exemplarsHint": "דוגמאות טובות שסוכני הכתיבה לומדים, נוספות למערך המובנה.",
|
|
2731
|
+
"exemplarsEmpty": "לא מקושרות דוגמאות.",
|
|
2732
|
+
"pickLabel": "מסמך מיובא",
|
|
2733
|
+
"pickPlaceholder": "בחרו מסמך מיובא…",
|
|
2734
|
+
"setTemplate": "הגדר כתבנית",
|
|
2735
|
+
"addExemplar": "הוסף דוגמה",
|
|
2736
|
+
"remove": "הסר",
|
|
2737
|
+
"linkFailed": "לא ניתן לעדכן את קישור המסמך",
|
|
2738
|
+
"loadFailed": "לא ניתן היה לטעון את תבניות המסמכים"
|
|
2710
2739
|
}
|
|
2711
2740
|
},
|
|
2712
2741
|
"tasks": {
|
package/i18n/locales/ja.json
CHANGED
|
@@ -184,7 +184,10 @@
|
|
|
184
184
|
"label": "エスカレーション経路",
|
|
185
185
|
"placeholder": "失敗時の連絡先とエスカレーション方法"
|
|
186
186
|
},
|
|
187
|
-
"researchQuestion": {
|
|
187
|
+
"researchQuestion": {
|
|
188
|
+
"label": "リサーチの問い",
|
|
189
|
+
"placeholder": "答えるべき問いや仮説"
|
|
190
|
+
},
|
|
188
191
|
"optionsToCompare": {
|
|
189
192
|
"label": "比較する選択肢",
|
|
190
193
|
"placeholder": "互いに比較検討する選択肢"
|
|
@@ -1581,6 +1584,9 @@
|
|
|
1581
1584
|
"localRunners": {
|
|
1582
1585
|
"label": "マイローカルランナー",
|
|
1583
1586
|
"description": "自分のマシンで動かすモデルランナー (Ollama、LM Studio、vLLM…)。"
|
|
1587
|
+
},
|
|
1588
|
+
"documentTemplates": {
|
|
1589
|
+
"label": "テンプレートと例"
|
|
1584
1590
|
}
|
|
1585
1591
|
}
|
|
1586
1592
|
},
|
|
@@ -2711,6 +2717,26 @@
|
|
|
2711
2717
|
"empty": "要件、RFC、PRD を添付すると、このタスクの実装中にエージェントが参照できます。",
|
|
2712
2718
|
"attached": "ドキュメントを添付しました",
|
|
2713
2719
|
"attachFailed": "添付できませんでした"
|
|
2720
|
+
},
|
|
2721
|
+
"templates": {
|
|
2722
|
+
"title": "ドキュメントのテンプレートと例",
|
|
2723
|
+
"intro": "ドキュメントの種類に独自のテンプレートと例のドキュメントを割り当てます。まずドキュメント連携でインポートする必要があります。テンプレートのセクションはその種類の組み込みスケルトンを置き換え、例は作成エージェントの指針になります。",
|
|
2724
|
+
"kindLabel": "ドキュメントの種類",
|
|
2725
|
+
"importFirst": "先にドキュメントをインポートしてください。テンプレートや例はインポート済みのドキュメントから選びます。",
|
|
2726
|
+
"importButton": "ドキュメントをインポート",
|
|
2727
|
+
"templateHeading": "テンプレート",
|
|
2728
|
+
"templateHint": "{kind} の組み込みスケルトンを置き換えます。種類ごとに1つ。",
|
|
2729
|
+
"templateEmpty": "組み込みテンプレートを使用しています。",
|
|
2730
|
+
"exemplarsHeading": "手本にする例",
|
|
2731
|
+
"exemplarsHint": "作成エージェントが参考にする良い例で、組み込みの一覧に追加されます。",
|
|
2732
|
+
"exemplarsEmpty": "リンクされた例はありません。",
|
|
2733
|
+
"pickLabel": "インポート済みドキュメント",
|
|
2734
|
+
"pickPlaceholder": "インポート済みドキュメントを選択…",
|
|
2735
|
+
"setTemplate": "テンプレートに設定",
|
|
2736
|
+
"addExemplar": "例を追加",
|
|
2737
|
+
"remove": "削除",
|
|
2738
|
+
"linkFailed": "ドキュメントのリンクを更新できませんでした",
|
|
2739
|
+
"loadFailed": "ドキュメントテンプレートを読み込めませんでした"
|
|
2714
2740
|
}
|
|
2715
2741
|
},
|
|
2716
2742
|
"tasks": {
|
package/i18n/locales/pl.json
CHANGED
|
@@ -1584,6 +1584,9 @@
|
|
|
1584
1584
|
"localRunners": {
|
|
1585
1585
|
"label": "Moje lokalne silniki",
|
|
1586
1586
|
"description": "Twoje silniki modeli na własnej maszynie (Ollama, LM Studio, vLLM…)."
|
|
1587
|
+
},
|
|
1588
|
+
"documentTemplates": {
|
|
1589
|
+
"label": "Szablony i przykłady"
|
|
1587
1590
|
}
|
|
1588
1591
|
}
|
|
1589
1592
|
},
|
|
@@ -2702,6 +2705,26 @@
|
|
|
2702
2705
|
"empty": "Dołącz wymaganie, dokument RFC lub PRD, aby agenci widzieli je podczas realizacji tego zadania.",
|
|
2703
2706
|
"attached": "Dokument dołączony",
|
|
2704
2707
|
"attachFailed": "Nie udało się dołączyć"
|
|
2708
|
+
},
|
|
2709
|
+
"templates": {
|
|
2710
|
+
"title": "Szablony i przykłady dokumentów",
|
|
2711
|
+
"intro": "Przypisz typowi dokumentu własny szablon i przykładowe dokumenty. Najpierw trzeba je zaimportować przez integrację Dokumentów. Sekcje szablonu zastępują wbudowany szkielet danego typu; przykłady są wskazówką dla agentów piszących.",
|
|
2712
|
+
"kindLabel": "Typ dokumentu",
|
|
2713
|
+
"importFirst": "Najpierw zaimportuj dokument — szablon lub przykład to jeden z zaimportowanych dokumentów.",
|
|
2714
|
+
"importButton": "Zaimportuj dokument",
|
|
2715
|
+
"templateHeading": "Szablon",
|
|
2716
|
+
"templateHint": "Zastępuje wbudowany szkielet {kind}. Jeden szablon na typ.",
|
|
2717
|
+
"templateEmpty": "Używany jest wbudowany szablon.",
|
|
2718
|
+
"exemplarsHeading": "Przykłady do naśladowania",
|
|
2719
|
+
"exemplarsHint": "Dobre przykłady, które studiują agenci piszący, dodane do wbudowanego zestawu.",
|
|
2720
|
+
"exemplarsEmpty": "Brak powiązanych przykładów.",
|
|
2721
|
+
"pickLabel": "Zaimportowany dokument",
|
|
2722
|
+
"pickPlaceholder": "Wybierz zaimportowany dokument…",
|
|
2723
|
+
"setTemplate": "Ustaw jako szablon",
|
|
2724
|
+
"addExemplar": "Dodaj przykład",
|
|
2725
|
+
"remove": "Usuń",
|
|
2726
|
+
"linkFailed": "Nie udało się zaktualizować powiązania dokumentu",
|
|
2727
|
+
"loadFailed": "Nie udało się wczytać szablonów dokumentów"
|
|
2705
2728
|
}
|
|
2706
2729
|
},
|
|
2707
2730
|
"tasks": {
|
package/i18n/locales/tr.json
CHANGED
|
@@ -192,7 +192,10 @@
|
|
|
192
192
|
"label": "Karşılaştırılacak seçenekler",
|
|
193
193
|
"placeholder": "Birbirine karşı tartılacak seçenekler"
|
|
194
194
|
},
|
|
195
|
-
"apiSurface": {
|
|
195
|
+
"apiSurface": {
|
|
196
|
+
"label": "API yüzeyi",
|
|
197
|
+
"placeholder": "Kapsamdaki uç noktalar veya yüzey"
|
|
198
|
+
}
|
|
196
199
|
},
|
|
197
200
|
"optional": "isteğe bağlı",
|
|
198
201
|
"pipeline": "İşlem hattı",
|
|
@@ -1581,6 +1584,9 @@
|
|
|
1581
1584
|
"localRunners": {
|
|
1582
1585
|
"label": "Yerel runner'larım",
|
|
1583
1586
|
"description": "Kendi makinenizdeki model runner'ları (Ollama, LM Studio, vLLM…)."
|
|
1587
|
+
},
|
|
1588
|
+
"documentTemplates": {
|
|
1589
|
+
"label": "Şablonlar ve örnekler"
|
|
1584
1590
|
}
|
|
1585
1591
|
}
|
|
1586
1592
|
},
|
|
@@ -2711,6 +2717,26 @@
|
|
|
2711
2717
|
"empty": "Agentların bu görevi uygularken görebilmesi için bir gereksinim, RFC veya PRD ekle.",
|
|
2712
2718
|
"attached": "Belge eklendi",
|
|
2713
2719
|
"attachFailed": "Eklenemedi"
|
|
2720
|
+
},
|
|
2721
|
+
"templates": {
|
|
2722
|
+
"title": "Belge şablonları ve örnekleri",
|
|
2723
|
+
"intro": "Bir belge türüne kendi şablonunuzu ve örnek belgelerinizi atayın. Önce Belgeler entegrasyonu ile içe aktarılmaları gerekir. Bir şablonun bölümleri, o türün yerleşik iskeletinin yerini alır; örnekler yazar aracılara rehberlik eder.",
|
|
2724
|
+
"kindLabel": "Belge türü",
|
|
2725
|
+
"importFirst": "Önce bir belge içe aktarın — şablon veya örnek, içe aktardığınız belgelerden biridir.",
|
|
2726
|
+
"importButton": "Belge içe aktar",
|
|
2727
|
+
"templateHeading": "Şablon",
|
|
2728
|
+
"templateHint": "{kind} için yerleşik iskeletin yerini alır. Tür başına bir şablon.",
|
|
2729
|
+
"templateEmpty": "Yerleşik şablon kullanılıyor.",
|
|
2730
|
+
"exemplarsHeading": "Örnek alınacak belgeler",
|
|
2731
|
+
"exemplarsHint": "Yazar aracıların incelediği iyi örnekler, yerleşik kümeye eklenir.",
|
|
2732
|
+
"exemplarsEmpty": "Bağlı örnek yok.",
|
|
2733
|
+
"pickLabel": "İçe aktarılan belge",
|
|
2734
|
+
"pickPlaceholder": "İçe aktarılan bir belge seçin…",
|
|
2735
|
+
"setTemplate": "Şablon olarak ayarla",
|
|
2736
|
+
"addExemplar": "Örnek ekle",
|
|
2737
|
+
"remove": "Kaldır",
|
|
2738
|
+
"linkFailed": "Belge bağlantısı güncellenemedi",
|
|
2739
|
+
"loadFailed": "Belge şablonları yüklenemedi"
|
|
2714
2740
|
}
|
|
2715
2741
|
},
|
|
2716
2742
|
"tasks": {
|
package/i18n/locales/uk.json
CHANGED
|
@@ -1584,6 +1584,9 @@
|
|
|
1584
1584
|
"localRunners": {
|
|
1585
1585
|
"label": "Мої локальні виконавці",
|
|
1586
1586
|
"description": "Ваші виконавці моделей на власній машині (Ollama, LM Studio, vLLM…)."
|
|
1587
|
+
},
|
|
1588
|
+
"documentTemplates": {
|
|
1589
|
+
"label": "Шаблони та приклади"
|
|
1587
1590
|
}
|
|
1588
1591
|
}
|
|
1589
1592
|
},
|
|
@@ -2702,6 +2705,26 @@
|
|
|
2702
2705
|
"empty": "Долучіть вимогу, RFC або PRD, щоб агенти бачили їх під час реалізації цього завдання.",
|
|
2703
2706
|
"attached": "Документ долучено",
|
|
2704
2707
|
"attachFailed": "Не вдалося долучити"
|
|
2708
|
+
},
|
|
2709
|
+
"templates": {
|
|
2710
|
+
"title": "Шаблони та приклади документів",
|
|
2711
|
+
"intro": "Призначте типу документа власний шаблон і приклади документів. Спершу їх потрібно імпортувати через інтеграцію Документів. Розділи шаблону замінюють вбудований каркас цього типу; приклади скеровують агентів-авторів.",
|
|
2712
|
+
"kindLabel": "Тип документа",
|
|
2713
|
+
"importFirst": "Спершу імпортуйте документ — шаблон або приклад це один із ваших імпортованих документів.",
|
|
2714
|
+
"importButton": "Імпортувати документ",
|
|
2715
|
+
"templateHeading": "Шаблон",
|
|
2716
|
+
"templateHint": "Замінює вбудований каркас {kind}. Один шаблон на тип.",
|
|
2717
|
+
"templateEmpty": "Використовується вбудований шаблон.",
|
|
2718
|
+
"exemplarsHeading": "Приклади для наслідування",
|
|
2719
|
+
"exemplarsHint": "Гарні приклади, які вивчають агенти-автори, додані до вбудованого набору.",
|
|
2720
|
+
"exemplarsEmpty": "Немає пов'язаних прикладів.",
|
|
2721
|
+
"pickLabel": "Імпортований документ",
|
|
2722
|
+
"pickPlaceholder": "Виберіть імпортований документ…",
|
|
2723
|
+
"setTemplate": "Встановити як шаблон",
|
|
2724
|
+
"addExemplar": "Додати приклад",
|
|
2725
|
+
"remove": "Видалити",
|
|
2726
|
+
"linkFailed": "Не вдалося оновити зв'язок документа",
|
|
2727
|
+
"loadFailed": "Не вдалося завантажити шаблони документів"
|
|
2705
2728
|
}
|
|
2706
2729
|
},
|
|
2707
2730
|
"tasks": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.92.0",
|
|
4
4
|
"description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"valibot": "^1.4.2",
|
|
35
35
|
"vue": "^3.5.39",
|
|
36
36
|
"wretch": "^3.0.9",
|
|
37
|
-
"@cat-factory/contracts": "0.
|
|
37
|
+
"@cat-factory/contracts": "0.100.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@toad-contracts/testing": "0.3.2",
|