@cat-factory/app 0.75.0 → 0.76.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/board/AgentFailureCard.vue +8 -9
- package/app/components/board/AgentFailureHistory.vue +60 -0
- package/app/components/board/FailureDetail.vue +27 -0
- package/app/components/panels/inspector/FrontendConfig.vue +536 -269
- package/app/components/panels/inspector/ServiceFragments.vue +7 -4
- package/app/components/panels/inspector/TaskExecution.vue +8 -0
- package/app/components/panels/inspector/TaskStructure.vue +10 -4
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +6 -5
- package/app/composables/api/infraHandlers.ts +6 -0
- package/app/stores/agentRuns.ts +10 -0
- package/app/stores/fragmentLibrary.ts +4 -0
- package/app/stores/fragments.ts +30 -7
- package/app/stores/infraConfig.ts +11 -0
- package/app/stores/workspace.ts +5 -0
- package/app/types/domain.ts +2 -0
- package/i18n/locales/en.json +31 -2
- package/i18n/locales/es.json +28 -2
- package/i18n/locales/fr.json +28 -2
- package/i18n/locales/he.json +28 -2
- package/i18n/locales/ja.json +28 -2
- package/i18n/locales/pl.json +28 -2
- package/i18n/locales/tr.json +28 -2
- package/i18n/locales/uk.json +28 -2
- package/package.json +2 -2
|
@@ -4,7 +4,8 @@ import type { Block } from '~/types/domain'
|
|
|
4
4
|
// Service-level best-practice fragments (frame blocks). These are the programming
|
|
5
5
|
// standards/guidelines for the whole service; at run time their bodies are folded
|
|
6
6
|
// into the prompt of every `code-aware` agent on tasks under this service. Drawn from
|
|
7
|
-
// the
|
|
7
|
+
// the board's merged fragment catalog (built-in ∪ registered ∪ account ∪ workspace,
|
|
8
|
+
// via the fragments store; static pool when the library is off), grouped by category.
|
|
8
9
|
const props = defineProps<{ block: Block }>()
|
|
9
10
|
|
|
10
11
|
const board = useBoardStore()
|
|
@@ -17,10 +18,12 @@ onMounted(() => fragments.ensureLoaded())
|
|
|
17
18
|
|
|
18
19
|
type MenuItem = { label: string; icon?: string; onSelect: () => void }
|
|
19
20
|
|
|
21
|
+
// An id the catalog no longer resolves (removed/suppressed after selection) still
|
|
22
|
+
// renders — labelled by its raw id — so it stays visible and removable.
|
|
20
23
|
const selectedFragments = computed(() =>
|
|
21
|
-
(props.block.serviceFragmentIds ?? [])
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
(props.block.serviceFragmentIds ?? []).map(
|
|
25
|
+
(id) => fragments.getFragment(id) ?? { id, title: id, summary: '' },
|
|
26
|
+
),
|
|
24
27
|
)
|
|
25
28
|
|
|
26
29
|
// A trailing group that jumps from "attach a fragment" to authoring/editing the
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
containerPhaseLabel,
|
|
9
9
|
} from '~/utils/pipelineRender'
|
|
10
10
|
import AgentFailureCard from '~/components/board/AgentFailureCard.vue'
|
|
11
|
+
import AgentFailureHistory from '~/components/board/AgentFailureHistory.vue'
|
|
11
12
|
import EmptyState from '~/components/common/EmptyState.vue'
|
|
12
13
|
|
|
13
14
|
const props = defineProps<{ block: Block }>()
|
|
@@ -57,6 +58,10 @@ const failedRun = computed(() => {
|
|
|
57
58
|
return run && run.status === 'failed' ? run : null
|
|
58
59
|
})
|
|
59
60
|
|
|
61
|
+
// Failures from prior attempts, preserved across retries — shown regardless of the run's
|
|
62
|
+
// CURRENT status, so the error trail stays viewable after a restart clears the top banner.
|
|
63
|
+
const failureHistory = computed(() => agentRuns.byBlock[props.block.id]?.failureHistory ?? [])
|
|
64
|
+
|
|
60
65
|
const pr = computed(() => props.block.pullRequest)
|
|
61
66
|
/** A PR is merged once the block is `done`; otherwise it is open awaiting merge. */
|
|
62
67
|
const prMerged = computed(() => props.block.status === 'done')
|
|
@@ -413,6 +418,9 @@ async function mergePr() {
|
|
|
413
418
|
<!-- failed run: shared failure banner + retry -->
|
|
414
419
|
<AgentFailureCard v-if="failedRun" :run="failedRun" />
|
|
415
420
|
|
|
421
|
+
<!-- error trail of prior attempts (survives a retry/restart that cleared the banner) -->
|
|
422
|
+
<AgentFailureHistory :failures="failureHistory" />
|
|
423
|
+
|
|
416
424
|
<!-- Open PR: link straight to it on GitHub -->
|
|
417
425
|
<div v-if="pr" class="space-y-2">
|
|
418
426
|
<span class="text-[11px] font-semibold uppercase tracking-wide text-slate-400">
|
|
@@ -9,14 +9,20 @@ const ui = useUiStore()
|
|
|
9
9
|
const accounts = useAccountsStore()
|
|
10
10
|
const { t } = useI18n()
|
|
11
11
|
|
|
12
|
+
// The catalog is per-board and invalidated on a workspace switch, so (re)load it when the
|
|
13
|
+
// task inspector mounts — mirrors ServiceFragments; ensureLoaded is a no-op while current.
|
|
14
|
+
onMounted(() => fragments.ensureLoaded())
|
|
15
|
+
|
|
12
16
|
type MenuItem = { label: string; icon?: string; onSelect: () => void }
|
|
13
17
|
|
|
14
18
|
// ---- best-practice prompt fragments ----------------------------------------
|
|
15
|
-
// Selected fragments
|
|
19
|
+
// Selected fragments, resolved against the catalog. An id the catalog no longer
|
|
20
|
+
// resolves (removed/suppressed after selection) still renders — labelled by its
|
|
21
|
+
// raw id — so it stays visible and removable.
|
|
16
22
|
const selectedFragments = computed(() =>
|
|
17
|
-
(props.block.fragmentIds ?? [])
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
(props.block.fragmentIds ?? []).map(
|
|
24
|
+
(id) => fragments.getFragment(id) ?? { id, title: id, summary: '' },
|
|
25
|
+
),
|
|
20
26
|
)
|
|
21
27
|
|
|
22
28
|
// A trailing group that jumps from "attach a fragment" to authoring/editing the
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
// Workspace settings: the default best-practice fragments NEW services inherit. The
|
|
3
|
-
// selection is drawn from the
|
|
4
|
-
//
|
|
3
|
+
// selection is drawn from the board's merged fragment catalog (built-in ∪ registered ∪
|
|
4
|
+
// account ∪ workspace via the fragments store; the static GET /prompt-fragments pool
|
|
5
|
+
// when the library is off). Changing it does not retroactively change existing
|
|
5
6
|
// services — each owns its selection from creation. Persisted via the
|
|
6
7
|
// serviceFragmentDefaults store (the backend replaces the whole list on each change).
|
|
7
8
|
import { onMounted, ref } from 'vue'
|
|
@@ -17,10 +18,10 @@ const busy = ref(false)
|
|
|
17
18
|
// The tab renders when Workspace settings opens; load the fragment pool then.
|
|
18
19
|
onMounted(() => void fragments.ensureLoaded())
|
|
19
20
|
|
|
21
|
+
// An id the catalog no longer resolves still renders (labelled by its raw id) so it
|
|
22
|
+
// stays visible and removable from the default set.
|
|
20
23
|
const selected = computed(() =>
|
|
21
|
-
defaults.fragmentIds
|
|
22
|
-
.map((id) => fragments.getFragment(id))
|
|
23
|
-
.filter((f): f is NonNullable<typeof f> => !!f),
|
|
24
|
+
defaults.fragmentIds.map((id) => fragments.getFragment(id) ?? { id, title: id, summary: '' }),
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
// Pool fragments not already in the default set, grouped by category.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
detectFrontendConfigContract,
|
|
2
3
|
detectServiceProvisioningContract,
|
|
3
4
|
listEnvironmentHandlersContract,
|
|
4
5
|
listEnvironmentUserHandlersContract,
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
upsertEnvironmentUserHandlerContract,
|
|
13
14
|
} from '@cat-factory/contracts'
|
|
14
15
|
import type {
|
|
16
|
+
DetectFrontendConfigInput,
|
|
15
17
|
DetectServiceProvisioningInput,
|
|
16
18
|
ProvisionType,
|
|
17
19
|
RegisterEnvironmentHandlerInput,
|
|
@@ -47,6 +49,10 @@ export function infraHandlersApi({ send, ws }: ApiContext) {
|
|
|
47
49
|
detectServiceProvisioning: (workspaceId: string, body: DetectServiceProvisioningInput) =>
|
|
48
50
|
send(detectServiceProvisioningContract, { pathPrefix: ws(workspaceId), body }),
|
|
49
51
|
|
|
52
|
+
// Auto-detect a non-binding recommended frontend config from a frontend repo.
|
|
53
|
+
detectFrontendConfig: (workspaceId: string, body: DetectFrontendConfigInput) =>
|
|
54
|
+
send(detectFrontendConfigContract, { pathPrefix: ws(workspaceId), body }),
|
|
55
|
+
|
|
50
56
|
// Generate/fix a service's custom manifest via the fixer coding agent (async repair run).
|
|
51
57
|
repairCustomManifest: (workspaceId: string, body: RepairCustomManifestInput) =>
|
|
52
58
|
send(repairCustomManifestContract, { pathPrefix: ws(workspaceId), body }),
|
package/app/stores/agentRuns.ts
CHANGED
|
@@ -26,6 +26,13 @@ export interface AgentRunSummary {
|
|
|
26
26
|
runId: string
|
|
27
27
|
/** Structured failure when `status` is `failed`; null otherwise. */
|
|
28
28
|
failure: AgentFailure | null
|
|
29
|
+
/**
|
|
30
|
+
* Failures from the run's PRIOR attempts, oldest→newest — the error trail preserved
|
|
31
|
+
* across retries/restarts. Stays populated after a restart (when `status` is no longer
|
|
32
|
+
* `failed` and the top banner is gone), so the "previous errors" history remains
|
|
33
|
+
* viewable. Empty for a bootstrap run or a run that never failed-then-retried.
|
|
34
|
+
*/
|
|
35
|
+
failureHistory: AgentFailure[]
|
|
29
36
|
/** Latest subtask counts for a live progress bar (null until reported). */
|
|
30
37
|
subtasks: StepSubtasks | null
|
|
31
38
|
}
|
|
@@ -138,6 +145,7 @@ export const useAgentRunsStore = defineStore('agentRuns', () => {
|
|
|
138
145
|
status: e.status,
|
|
139
146
|
runId: e.id,
|
|
140
147
|
failure: e.failure ?? null,
|
|
148
|
+
failureHistory: e.failureHistory ?? [],
|
|
141
149
|
subtasks: e.steps[e.currentStep]?.subtasks ?? null,
|
|
142
150
|
}
|
|
143
151
|
}
|
|
@@ -150,6 +158,8 @@ export const useAgentRunsStore = defineStore('agentRuns', () => {
|
|
|
150
158
|
status: job.status,
|
|
151
159
|
runId: job.id,
|
|
152
160
|
failure: job.failure,
|
|
161
|
+
// Bootstrap runs keep no prior-attempt trail (retry mints a fresh row).
|
|
162
|
+
failureHistory: [],
|
|
153
163
|
subtasks: job.subtasks,
|
|
154
164
|
}
|
|
155
165
|
}
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
UpdatePromptFragmentInput,
|
|
12
12
|
} from '~/types/domain'
|
|
13
13
|
import { useWorkspaceStore } from '~/stores/workspace'
|
|
14
|
+
import { useFragmentsStore } from '~/stores/fragments'
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Prompt-fragment library state (ADR 0006), scoped to a single owner — a board
|
|
@@ -83,6 +84,9 @@ function fragmentLibrarySetup(kind: FragmentOwnerKind, resolveOwnerId: () => str
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
async function refreshResolved() {
|
|
87
|
+
// Every library mutation lands here: drop the picker catalog's cache so the
|
|
88
|
+
// per-service / per-block pickers see the edit on their next open.
|
|
89
|
+
useFragmentsStore().invalidate()
|
|
86
90
|
if (!hasResolved) return
|
|
87
91
|
resolved.value = await api.getResolvedFragments(requireOwnerId())
|
|
88
92
|
}
|
package/app/stores/fragments.ts
CHANGED
|
@@ -1,24 +1,47 @@
|
|
|
1
1
|
import { defineStore } from 'pinia'
|
|
2
2
|
import { ref, computed } from 'vue'
|
|
3
3
|
import type { BlockType, PromptFragment } from '~/types/domain'
|
|
4
|
+
import { useWorkspaceStore } from '~/stores/workspace'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
|
-
* The best-practice prompt fragment catalog
|
|
7
|
-
* the
|
|
8
|
-
*
|
|
7
|
+
* The best-practice prompt fragment catalog backing the per-service and per-block
|
|
8
|
+
* pickers. When the fragment library is configured it loads the MERGED tenant
|
|
9
|
+
* catalog for the active board (`GET /workspaces/:id/prompt-fragments/resolved` —
|
|
10
|
+
* built-in ∪ account ∪ workspace, override-by-id, tombstones applied), so managed,
|
|
11
|
+
* repo-sourced and document-backed fragments are selectable exactly like the
|
|
12
|
+
* built-ins and a suppressed built-in disappears from the picker. When the library
|
|
13
|
+
* is off (the resolved endpoint 503s) it falls back to the workspace-independent
|
|
14
|
+
* static pool (`GET /prompt-fragments`). Cached per board; re-fetched on a board
|
|
15
|
+
* switch or after `invalidate()` (a library edit).
|
|
9
16
|
*/
|
|
10
17
|
export const useFragmentsStore = defineStore('fragments', () => {
|
|
11
18
|
const api = useApi()
|
|
12
19
|
const fragments = ref<PromptFragment[]>([])
|
|
13
20
|
const loaded = ref(false)
|
|
21
|
+
/** The board the catalog was loaded for (null = never; '' = static pool, no board). */
|
|
22
|
+
const loadedFor = ref<string | null>(null)
|
|
14
23
|
|
|
15
|
-
/** Fetch the catalog
|
|
24
|
+
/** Fetch the catalog for the active board; a no-op while it is current. */
|
|
16
25
|
async function ensureLoaded() {
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
const wsId = useWorkspaceStore().workspaceId ?? ''
|
|
27
|
+
if (loaded.value && loadedFor.value === wsId) return
|
|
28
|
+
// Prefer the merged tenant catalog; only a FAILURE (a 503 when the library is
|
|
29
|
+
// unconfigured, or any other error) degrades to the static universal pool — mapped to
|
|
30
|
+
// null by the catch. A successful-but-empty resolved catalog is left empty on purpose:
|
|
31
|
+
// it means every fragment is suppressed at some tier, and falling back to the static
|
|
32
|
+
// pool would resurrect the very built-ins the tenant tombstoned.
|
|
33
|
+
const resolved = wsId ? await api.getResolvedFragments(wsId).catch(() => null) : null
|
|
34
|
+
fragments.value = resolved ?? (await api.getPromptFragments())
|
|
35
|
+
loadedFor.value = wsId
|
|
19
36
|
loaded.value = true
|
|
20
37
|
}
|
|
21
38
|
|
|
39
|
+
/** Drop the cache so the next `ensureLoaded()` re-fetches (after a library edit). */
|
|
40
|
+
function invalidate() {
|
|
41
|
+
loaded.value = false
|
|
42
|
+
loadedFor.value = null
|
|
43
|
+
}
|
|
44
|
+
|
|
22
45
|
const byId = computed(() => {
|
|
23
46
|
const map = new Map<string, PromptFragment>()
|
|
24
47
|
for (const f of fragments.value) map.set(f.id, f)
|
|
@@ -36,5 +59,5 @@ export const useFragmentsStore = defineStore('fragments', () => {
|
|
|
36
59
|
)
|
|
37
60
|
}
|
|
38
61
|
|
|
39
|
-
return { fragments, loaded, ensureLoaded, byId, getFragment, forBlockType }
|
|
62
|
+
return { fragments, loaded, ensureLoaded, invalidate, byId, getFragment, forBlockType }
|
|
40
63
|
})
|
|
@@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
|
|
|
2
2
|
import { ref, type Ref } from 'vue'
|
|
3
3
|
import type {
|
|
4
4
|
CustomManifestType,
|
|
5
|
+
DetectFrontendConfigInput,
|
|
5
6
|
DetectServiceProvisioningInput,
|
|
6
7
|
EnvironmentHandlerView,
|
|
7
8
|
ProvisionType,
|
|
@@ -113,6 +114,15 @@ export const useInfraConfigStore = defineStore('infraConfig', () => {
|
|
|
113
114
|
return api.detectServiceProvisioning(ws.requireId(), input)
|
|
114
115
|
}
|
|
115
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Auto-detect a NON-BINDING recommended frontend config from a frontend repo. The SPA prefills a
|
|
119
|
+
* preview the user applies; nothing is persisted server-side. Pure repo introspection.
|
|
120
|
+
*/
|
|
121
|
+
async function detectFrontendConfig(input: DetectFrontendConfigInput) {
|
|
122
|
+
const ws = useWorkspaceStore()
|
|
123
|
+
return api.detectFrontendConfig(ws.requireId(), input)
|
|
124
|
+
}
|
|
125
|
+
|
|
116
126
|
/**
|
|
117
127
|
* Generate (or fix) a service's custom manifest via the fixer coding agent. Dispatches a
|
|
118
128
|
* durable async repair run and returns immediately with `usedAgent`/`repairJobId`; the run is
|
|
@@ -192,6 +202,7 @@ export const useInfraConfigStore = defineStore('infraConfig', () => {
|
|
|
192
202
|
registerHandler,
|
|
193
203
|
testHandler,
|
|
194
204
|
detectProvisioning,
|
|
205
|
+
detectFrontendConfig,
|
|
195
206
|
repairCustomManifest,
|
|
196
207
|
unregisterHandler,
|
|
197
208
|
upsertCustomType,
|
package/app/stores/workspace.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { useClarityStore } from '~/stores/clarity'
|
|
|
21
21
|
import { useBrainstormStore } from '~/stores/brainstorm'
|
|
22
22
|
import { useConsensusStore } from '~/stores/consensus'
|
|
23
23
|
import { useGitHubStore } from '~/stores/github'
|
|
24
|
+
import { useFragmentsStore } from '~/stores/fragments'
|
|
24
25
|
import { useProviderConnectionsStore } from '~/stores/providerConnections'
|
|
25
26
|
|
|
26
27
|
/**
|
|
@@ -81,6 +82,10 @@ export const useWorkspaceStore = defineStore(
|
|
|
81
82
|
useBrainstormStore().reset()
|
|
82
83
|
useConsensusStore().reset()
|
|
83
84
|
useGitHubStore().reset()
|
|
85
|
+
// The fragment picker catalog is per-board (the merged tenant catalog), so drop
|
|
86
|
+
// it too — the next inspector open re-fetches it for the switched-to board rather
|
|
87
|
+
// than showing the previous board's (or a raw-id placeholder for) fragments.
|
|
88
|
+
useFragmentsStore().invalidate()
|
|
84
89
|
}
|
|
85
90
|
workspaceId.value = snapshot.workspace.id
|
|
86
91
|
spend.value = snapshot.spend ?? null
|
package/app/types/domain.ts
CHANGED
package/i18n/locales/en.json
CHANGED
|
@@ -225,7 +225,13 @@
|
|
|
225
225
|
"retryBootstrap": "Retry bootstrap",
|
|
226
226
|
"retryRun": "Retry run",
|
|
227
227
|
"showDetail": "Show detail",
|
|
228
|
-
"retrying": "Retrying…"
|
|
228
|
+
"retrying": "Retrying…",
|
|
229
|
+
"history": {
|
|
230
|
+
"previousErrors": "{count} previous error | {count} previous errors",
|
|
231
|
+
"@previousErrors": {
|
|
232
|
+
"description": "Count-based tally of a run's earlier failed attempts, rendered as e.g. '3 previous errors' (count is always >= 1). Provide ALL plural forms your language needs (English has 2; Polish/Ukrainian need 3 - one/few/many - via the custom pluralRules in i18n.config.ts)."
|
|
233
|
+
}
|
|
234
|
+
}
|
|
229
235
|
},
|
|
230
236
|
"stop": {
|
|
231
237
|
"label": "Stop",
|
|
@@ -479,14 +485,37 @@
|
|
|
479
485
|
"frontendConfig": {
|
|
480
486
|
"title": "Frontend",
|
|
481
487
|
"hint": "How to build, serve, and mock this frontend for a self-contained UI test. Bindings below link it to the backend services it calls.",
|
|
488
|
+
"detect": {
|
|
489
|
+
"title": "Detect from repo",
|
|
490
|
+
"button": "Detect",
|
|
491
|
+
"hint": "Read the linked repo and propose a config to review before applying. Nothing is saved until you apply.",
|
|
492
|
+
"error": "Couldn't read the repo. Check the frontend is linked to a connected repository.",
|
|
493
|
+
"none": "Nothing frontend-shaped was detected. Set the frontend directory (for a monorepo) or fill the fields in manually.",
|
|
494
|
+
"apply": "Apply",
|
|
495
|
+
"dismiss": "Dismiss",
|
|
496
|
+
"confidenceHigh": "sure",
|
|
497
|
+
"confidenceLow": "guess"
|
|
498
|
+
},
|
|
499
|
+
"groups": {
|
|
500
|
+
"build": "Build",
|
|
501
|
+
"serve": "Serve",
|
|
502
|
+
"mocking": "Mocking",
|
|
503
|
+
"envInjection": "Env injection",
|
|
504
|
+
"bindings": "Backend bindings",
|
|
505
|
+
"preview": "Preview"
|
|
506
|
+
},
|
|
482
507
|
"packageManager": "Package manager",
|
|
508
|
+
"directory": "Frontend directory",
|
|
509
|
+
"directoryHint": "The frontend app's subfolder in the repo (a monorepo, e.g. frontend/). Leave empty if the app is at the repo root.",
|
|
483
510
|
"installCommand": "Install command",
|
|
484
511
|
"buildScript": "Build script",
|
|
485
512
|
"outputDir": "Output directory",
|
|
486
513
|
"serveMode": "Serve mode",
|
|
487
514
|
"serveStatic": "Static",
|
|
488
515
|
"serveCommand": "Command",
|
|
489
|
-
"
|
|
516
|
+
"serveStaticDesc": "serves the built output directory as static files. Cheapest for a UI test of a fully built app.",
|
|
517
|
+
"serveCommandDesc": "runs a package.json script (e.g. preview) to serve the app, for builds that need a running server.",
|
|
518
|
+
"serveEnvAxisNote": "Separate from Env injection (build-time vs runtime) below, which controls how backend URLs reach the app, not how it is served.",
|
|
490
519
|
"serveScript": "Serve script",
|
|
491
520
|
"servePort": "Serve port",
|
|
492
521
|
"mockMappingsPath": "Mock mappings path",
|
package/i18n/locales/es.json
CHANGED
|
@@ -204,7 +204,10 @@
|
|
|
204
204
|
"retryBootstrap": "Reintentar arranque",
|
|
205
205
|
"retryRun": "Reintentar ejecución",
|
|
206
206
|
"showDetail": "Mostrar detalle",
|
|
207
|
-
"retrying": "Reintentando…"
|
|
207
|
+
"retrying": "Reintentando…",
|
|
208
|
+
"history": {
|
|
209
|
+
"previousErrors": "{count} error anterior | {count} errores anteriores"
|
|
210
|
+
}
|
|
208
211
|
},
|
|
209
212
|
"stop": {
|
|
210
213
|
"label": "Detener",
|
|
@@ -439,14 +442,37 @@
|
|
|
439
442
|
"frontendConfig": {
|
|
440
443
|
"title": "Frontend",
|
|
441
444
|
"hint": "Cómo compilar, servir y simular este frontend para una prueba de interfaz autónoma. Las vinculaciones de abajo lo conectan con los servicios de backend a los que llama.",
|
|
445
|
+
"detect": {
|
|
446
|
+
"title": "Detectar del repositorio",
|
|
447
|
+
"button": "Detectar",
|
|
448
|
+
"hint": "Lee el repositorio vinculado y propone una configuración para revisar antes de aplicar. No se guarda nada hasta que la apliques.",
|
|
449
|
+
"error": "No se pudo leer el repositorio. Comprueba que el frontend esté vinculado a un repositorio conectado.",
|
|
450
|
+
"none": "No se detectó nada con forma de frontend. Indica el directorio del frontend (para un monorepo) o rellena los campos manualmente.",
|
|
451
|
+
"apply": "Aplicar",
|
|
452
|
+
"dismiss": "Descartar",
|
|
453
|
+
"confidenceHigh": "seguro",
|
|
454
|
+
"confidenceLow": "estimación"
|
|
455
|
+
},
|
|
456
|
+
"groups": {
|
|
457
|
+
"build": "Compilación",
|
|
458
|
+
"serve": "Servicio",
|
|
459
|
+
"mocking": "Simulación",
|
|
460
|
+
"envInjection": "Inyección de entorno",
|
|
461
|
+
"bindings": "Vinculaciones de backend",
|
|
462
|
+
"preview": "Vista previa"
|
|
463
|
+
},
|
|
442
464
|
"packageManager": "Gestor de paquetes",
|
|
465
|
+
"directory": "Directorio del frontend",
|
|
466
|
+
"directoryHint": "La subcarpeta de la app frontend en el repositorio (un monorepo, p. ej. frontend/). Déjalo vacío si la app está en la raíz del repositorio.",
|
|
443
467
|
"installCommand": "Comando de instalación",
|
|
444
468
|
"buildScript": "Script de compilación",
|
|
445
469
|
"outputDir": "Directorio de salida",
|
|
446
470
|
"serveMode": "Modo de servicio",
|
|
447
471
|
"serveStatic": "Estático",
|
|
448
472
|
"serveCommand": "Comando",
|
|
449
|
-
"
|
|
473
|
+
"serveStaticDesc": "sirve el directorio de salida compilado como archivos estáticos. Lo más económico para una prueba de interfaz de una app ya compilada.",
|
|
474
|
+
"serveCommandDesc": "ejecuta un script de package.json (p. ej. preview) para servir la app, para compilaciones que necesitan un servidor en ejecución.",
|
|
475
|
+
"serveEnvAxisNote": "Distinto de la Inyección de entorno (en compilación vs. en tiempo de ejecución) de abajo, que controla cómo llegan las URL del backend a la app, no cómo se sirve.",
|
|
450
476
|
"serveScript": "Script de servicio",
|
|
451
477
|
"servePort": "Puerto de servicio",
|
|
452
478
|
"mockMappingsPath": "Ruta de asignaciones de simulación",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -204,7 +204,10 @@
|
|
|
204
204
|
"retryBootstrap": "Relancer l’initialisation",
|
|
205
205
|
"retryRun": "Relancer l’exécution",
|
|
206
206
|
"showDetail": "Afficher le détail",
|
|
207
|
-
"retrying": "Nouvelle tentative…"
|
|
207
|
+
"retrying": "Nouvelle tentative…",
|
|
208
|
+
"history": {
|
|
209
|
+
"previousErrors": "{count} erreur précédente | {count} erreurs précédentes"
|
|
210
|
+
}
|
|
208
211
|
},
|
|
209
212
|
"stop": {
|
|
210
213
|
"label": "Arrêter",
|
|
@@ -439,14 +442,37 @@
|
|
|
439
442
|
"frontendConfig": {
|
|
440
443
|
"title": "Frontend",
|
|
441
444
|
"hint": "Comment compiler, servir et simuler ce frontend pour un test d'interface autonome. Les liaisons ci-dessous le relient aux services de backend qu'il appelle.",
|
|
445
|
+
"detect": {
|
|
446
|
+
"title": "Détecter depuis le dépôt",
|
|
447
|
+
"button": "Détecter",
|
|
448
|
+
"hint": "Lit le dépôt lié et propose une configuration à vérifier avant application. Rien n'est enregistré tant que vous n'appliquez pas.",
|
|
449
|
+
"error": "Impossible de lire le dépôt. Vérifiez que le frontend est lié à un dépôt connecté.",
|
|
450
|
+
"none": "Aucun élément de type frontend détecté. Indiquez le répertoire du frontend (pour un monorepo) ou renseignez les champs manuellement.",
|
|
451
|
+
"apply": "Appliquer",
|
|
452
|
+
"dismiss": "Ignorer",
|
|
453
|
+
"confidenceHigh": "sûr",
|
|
454
|
+
"confidenceLow": "estimation"
|
|
455
|
+
},
|
|
456
|
+
"groups": {
|
|
457
|
+
"build": "Compilation",
|
|
458
|
+
"serve": "Service",
|
|
459
|
+
"mocking": "Simulation",
|
|
460
|
+
"envInjection": "Injection d'environnement",
|
|
461
|
+
"bindings": "Liaisons backend",
|
|
462
|
+
"preview": "Aperçu"
|
|
463
|
+
},
|
|
442
464
|
"packageManager": "Gestionnaire de paquets",
|
|
465
|
+
"directory": "Répertoire du frontend",
|
|
466
|
+
"directoryHint": "Le sous-dossier de l'app frontend dans le dépôt (un monorepo, p. ex. frontend/). Laissez vide si l'app est à la racine du dépôt.",
|
|
443
467
|
"installCommand": "Commande d'installation",
|
|
444
468
|
"buildScript": "Script de compilation",
|
|
445
469
|
"outputDir": "Répertoire de sortie",
|
|
446
470
|
"serveMode": "Mode de service",
|
|
447
471
|
"serveStatic": "Statique",
|
|
448
472
|
"serveCommand": "Commande",
|
|
449
|
-
"
|
|
473
|
+
"serveStaticDesc": "sert le répertoire de sortie compilé en fichiers statiques. Le plus économique pour un test d'interface d'une app entièrement compilée.",
|
|
474
|
+
"serveCommandDesc": "exécute un script de package.json (p. ex. preview) pour servir l'app, pour les compilations nécessitant un serveur en fonctionnement.",
|
|
475
|
+
"serveEnvAxisNote": "Distinct de l'Injection d'environnement (à la compilation vs à l'exécution) ci-dessous, qui contrôle comment les URL du backend atteignent l'app, pas comment elle est servie.",
|
|
450
476
|
"serveScript": "Script de service",
|
|
451
477
|
"servePort": "Port de service",
|
|
452
478
|
"mockMappingsPath": "Chemin des mappages de simulation",
|
package/i18n/locales/he.json
CHANGED
|
@@ -204,7 +204,10 @@
|
|
|
204
204
|
"retryBootstrap": "נסה שוב לאתחל",
|
|
205
205
|
"retryRun": "נסה שוב להריץ",
|
|
206
206
|
"showDetail": "הצג פרטים",
|
|
207
|
-
"retrying": "מנסה שוב…"
|
|
207
|
+
"retrying": "מנסה שוב…",
|
|
208
|
+
"history": {
|
|
209
|
+
"previousErrors": "שגיאה קודמת {count} | {count} שגיאות קודמות"
|
|
210
|
+
}
|
|
208
211
|
},
|
|
209
212
|
"stop": {
|
|
210
213
|
"label": "עצור",
|
|
@@ -439,14 +442,37 @@
|
|
|
439
442
|
"frontendConfig": {
|
|
440
443
|
"title": "Frontend",
|
|
441
444
|
"hint": "כיצד לבנות, להגיש ולדמות את ה-frontend הזה לבדיקת ממשק עצמאית. הקישורים למטה מחברים אותו לשירותי ה-backend שהוא קורא אליהם.",
|
|
445
|
+
"detect": {
|
|
446
|
+
"title": "זהה מהמאגר",
|
|
447
|
+
"button": "זהה",
|
|
448
|
+
"hint": "קורא את המאגר המקושר ומציע תצורה לבדיקה לפני החלה. שום דבר לא נשמר עד שתחיל.",
|
|
449
|
+
"error": "לא ניתן לקרוא את המאגר. ודא שה-frontend מקושר למאגר מחובר.",
|
|
450
|
+
"none": "לא זוהה דבר בעל מבנה frontend. הגדר את תיקיית ה-frontend (עבור monorepo) או מלא את השדות ידנית.",
|
|
451
|
+
"apply": "החל",
|
|
452
|
+
"dismiss": "בטל",
|
|
453
|
+
"confidenceHigh": "בטוח",
|
|
454
|
+
"confidenceLow": "ניחוש"
|
|
455
|
+
},
|
|
456
|
+
"groups": {
|
|
457
|
+
"build": "בנייה",
|
|
458
|
+
"serve": "הגשה",
|
|
459
|
+
"mocking": "הדמיה",
|
|
460
|
+
"envInjection": "הזרקת סביבה",
|
|
461
|
+
"bindings": "קישורי backend",
|
|
462
|
+
"preview": "תצוגה מקדימה"
|
|
463
|
+
},
|
|
442
464
|
"packageManager": "מנהל חבילות",
|
|
465
|
+
"directory": "תיקיית frontend",
|
|
466
|
+
"directoryHint": "תת-התיקייה של אפליקציית ה-frontend במאגר (monorepo, למשל frontend/). השאר ריק אם האפליקציה נמצאת בשורש המאגר.",
|
|
443
467
|
"installCommand": "פקודת התקנה",
|
|
444
468
|
"buildScript": "סקריפט בנייה",
|
|
445
469
|
"outputDir": "תיקיית פלט",
|
|
446
470
|
"serveMode": "מצב הגשה",
|
|
447
471
|
"serveStatic": "סטטי",
|
|
448
472
|
"serveCommand": "פקודה",
|
|
449
|
-
"
|
|
473
|
+
"serveStaticDesc": "מגיש את תיקיית פלט הבנייה כקבצים סטטיים. הזול ביותר לבדיקת ממשק של אפליקציה בנויה במלואה.",
|
|
474
|
+
"serveCommandDesc": "מריץ סקריפט מ-package.json (למשל preview) כדי להגיש את האפליקציה, עבור בנייה הזקוקה לשרת פעיל.",
|
|
475
|
+
"serveEnvAxisNote": "נפרד מהזרקת הסביבה (בזמן בנייה מול זמן ריצה) שלמטה, השולטת כיצד כתובות ה-backend מגיעות לאפליקציה, לא כיצד היא מוגשת.",
|
|
450
476
|
"serveScript": "סקריפט הגשה",
|
|
451
477
|
"servePort": "פורט הגשה",
|
|
452
478
|
"mockMappingsPath": "נתיב מיפויי הדמיה",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -204,7 +204,10 @@
|
|
|
204
204
|
"retryBootstrap": "ブートストラップを再試行",
|
|
205
205
|
"retryRun": "実行を再試行",
|
|
206
206
|
"showDetail": "詳細を表示",
|
|
207
|
-
"retrying": "再試行中…"
|
|
207
|
+
"retrying": "再試行中…",
|
|
208
|
+
"history": {
|
|
209
|
+
"previousErrors": "以前のエラー {count} 件 | 以前のエラー {count} 件"
|
|
210
|
+
}
|
|
208
211
|
},
|
|
209
212
|
"stop": {
|
|
210
213
|
"label": "停止",
|
|
@@ -439,14 +442,37 @@
|
|
|
439
442
|
"frontendConfig": {
|
|
440
443
|
"title": "フロントエンド",
|
|
441
444
|
"hint": "自己完結型の UI テストのために、このフロントエンドをビルド、配信、モックする方法。下のバインディングは、呼び出すバックエンドサービスとフロントエンドをつなぎます。",
|
|
445
|
+
"detect": {
|
|
446
|
+
"title": "リポジトリから検出",
|
|
447
|
+
"button": "検出",
|
|
448
|
+
"hint": "リンクされたリポジトリを読み取り、適用前に確認できる設定を提案します。適用するまで何も保存されません。",
|
|
449
|
+
"error": "リポジトリを読み取れませんでした。フロントエンドが接続済みリポジトリにリンクされているか確認してください。",
|
|
450
|
+
"none": "フロントエンドらしきものは検出されませんでした。(モノレポの場合は)フロントエンドのディレクトリを指定するか、手動で入力してください。",
|
|
451
|
+
"apply": "適用",
|
|
452
|
+
"dismiss": "却下",
|
|
453
|
+
"confidenceHigh": "確実",
|
|
454
|
+
"confidenceLow": "推測"
|
|
455
|
+
},
|
|
456
|
+
"groups": {
|
|
457
|
+
"build": "ビルド",
|
|
458
|
+
"serve": "配信",
|
|
459
|
+
"mocking": "モック",
|
|
460
|
+
"envInjection": "環境変数の注入",
|
|
461
|
+
"bindings": "バックエンドバインディング",
|
|
462
|
+
"preview": "プレビュー"
|
|
463
|
+
},
|
|
442
464
|
"packageManager": "パッケージマネージャー",
|
|
465
|
+
"directory": "フロントエンドのディレクトリ",
|
|
466
|
+
"directoryHint": "リポジトリ内のフロントエンドアプリのサブフォルダー(モノレポ、例: frontend/)。アプリがリポジトリのルートにある場合は空のままにします。",
|
|
443
467
|
"installCommand": "インストールコマンド",
|
|
444
468
|
"buildScript": "ビルドスクリプト",
|
|
445
469
|
"outputDir": "出力ディレクトリ",
|
|
446
470
|
"serveMode": "配信モード",
|
|
447
471
|
"serveStatic": "静的",
|
|
448
472
|
"serveCommand": "コマンド",
|
|
449
|
-
"
|
|
473
|
+
"serveStaticDesc": "ビルド出力ディレクトリを静的ファイルとして配信します。完全にビルド済みのアプリの UI テストに最も低コストです。",
|
|
474
|
+
"serveCommandDesc": "package.json のスクリプト(例: preview)を実行してアプリを配信します。サーバーの起動が必要なビルド向けです。",
|
|
475
|
+
"serveEnvAxisNote": "下の環境変数の注入(ビルド時とランタイム)とは別物で、そちらはバックエンド URL がアプリにどう届くかを制御し、配信方法ではありません。",
|
|
450
476
|
"serveScript": "配信スクリプト",
|
|
451
477
|
"servePort": "配信ポート",
|
|
452
478
|
"mockMappingsPath": "モックマッピングのパス",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -204,7 +204,10 @@
|
|
|
204
204
|
"retryBootstrap": "Ponów inicjalizację",
|
|
205
205
|
"retryRun": "Ponów uruchomienie",
|
|
206
206
|
"showDetail": "Pokaż szczegóły",
|
|
207
|
-
"retrying": "Ponawianie…"
|
|
207
|
+
"retrying": "Ponawianie…",
|
|
208
|
+
"history": {
|
|
209
|
+
"previousErrors": "{count} poprzedni błąd | {count} poprzednie błędy | {count} poprzednich błędów"
|
|
210
|
+
}
|
|
208
211
|
},
|
|
209
212
|
"stop": {
|
|
210
213
|
"label": "Zatrzymaj",
|
|
@@ -439,14 +442,37 @@
|
|
|
439
442
|
"frontendConfig": {
|
|
440
443
|
"title": "Frontend",
|
|
441
444
|
"hint": "Jak zbudować, uruchomić i zamockować ten frontend na potrzeby samodzielnego testu interfejsu. Powiązania poniżej łączą go z usługami backendu, które wywołuje.",
|
|
445
|
+
"detect": {
|
|
446
|
+
"title": "Wykryj z repozytorium",
|
|
447
|
+
"button": "Wykryj",
|
|
448
|
+
"hint": "Odczytuje połączone repozytorium i proponuje konfigurację do sprawdzenia przed zastosowaniem. Nic nie jest zapisywane, dopóki nie zastosujesz.",
|
|
449
|
+
"error": "Nie można odczytać repozytorium. Sprawdź, czy frontend jest połączony z podłączonym repozytorium.",
|
|
450
|
+
"none": "Nie wykryto niczego w kształcie frontendu. Ustaw katalog frontendu (dla monorepo) lub wypełnij pola ręcznie.",
|
|
451
|
+
"apply": "Zastosuj",
|
|
452
|
+
"dismiss": "Odrzuć",
|
|
453
|
+
"confidenceHigh": "pewne",
|
|
454
|
+
"confidenceLow": "przypuszczenie"
|
|
455
|
+
},
|
|
456
|
+
"groups": {
|
|
457
|
+
"build": "Budowanie",
|
|
458
|
+
"serve": "Serwowanie",
|
|
459
|
+
"mocking": "Mockowanie",
|
|
460
|
+
"envInjection": "Wstrzykiwanie środowiska",
|
|
461
|
+
"bindings": "Powiązania backendu",
|
|
462
|
+
"preview": "Podgląd"
|
|
463
|
+
},
|
|
442
464
|
"packageManager": "Menedżer pakietów",
|
|
465
|
+
"directory": "Katalog frontendu",
|
|
466
|
+
"directoryHint": "Podfolder aplikacji frontendowej w repozytorium (monorepo, np. frontend/). Pozostaw puste, jeśli aplikacja jest w katalogu głównym repozytorium.",
|
|
443
467
|
"installCommand": "Polecenie instalacji",
|
|
444
468
|
"buildScript": "Skrypt budowania",
|
|
445
469
|
"outputDir": "Katalog wyjściowy",
|
|
446
470
|
"serveMode": "Tryb serwowania",
|
|
447
471
|
"serveStatic": "Statyczny",
|
|
448
472
|
"serveCommand": "Polecenie",
|
|
449
|
-
"
|
|
473
|
+
"serveStaticDesc": "serwuje zbudowany katalog wyjściowy jako pliki statyczne. Najtańsze dla testu interfejsu w pełni zbudowanej aplikacji.",
|
|
474
|
+
"serveCommandDesc": "uruchamia skrypt z package.json (np. preview) do serwowania aplikacji, dla kompilacji wymagających działającego serwera.",
|
|
475
|
+
"serveEnvAxisNote": "Osobne od Wstrzykiwania środowiska (w czasie budowania vs w czasie działania) poniżej, które kontroluje sposób, w jaki adresy URL backendu docierają do aplikacji, a nie sposób jej serwowania.",
|
|
450
476
|
"serveScript": "Skrypt serwowania",
|
|
451
477
|
"servePort": "Port serwowania",
|
|
452
478
|
"mockMappingsPath": "Ścieżka mapowań mocków",
|