@cat-factory/app 0.85.0 → 0.86.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/AddTaskModal.vue +4 -3
- package/app/components/board/RecurringPipelineModal.vue +3 -2
- package/app/components/focus/BlockFocusView.vue +4 -3
- package/app/components/panels/InspectorPanel.vue +5 -4
- package/app/components/panels/inspector/TaskRunSettings.vue +7 -4
- package/app/utils/pipeline.ts +30 -0
- package/package.json +2 -2
|
@@ -16,7 +16,7 @@ import { DOC_KINDS } from '~/types/domain'
|
|
|
16
16
|
import ContextDocumentPicker from '~/components/documents/ContextDocumentPicker.vue'
|
|
17
17
|
import ContextIssuePicker from '~/components/tasks/ContextIssuePicker.vue'
|
|
18
18
|
import { mergePresetOptionLabel, mergePresetThresholds } from '~/utils/mergePreset'
|
|
19
|
-
import {
|
|
19
|
+
import { pipelineAllowedForManualStart } from '~/utils/pipeline'
|
|
20
20
|
|
|
21
21
|
const ui = useUiStore()
|
|
22
22
|
const board = useBoardStore()
|
|
@@ -197,9 +197,10 @@ const selectedModelPresetLabel = computed(() => {
|
|
|
197
197
|
})
|
|
198
198
|
|
|
199
199
|
// Hide UI-testing pipelines (`tester-ui` / `visual-confirmation`) when the target frame has no
|
|
200
|
-
// UI to exercise — they'd be refused server-side (see utils/pipeline + the backend gate).
|
|
200
|
+
// UI to exercise — they'd be refused server-side (see utils/pipeline + the backend gate). Also
|
|
201
|
+
// hide `'recurring'`-only pipelines: a one-off task start of one is refused at run start.
|
|
201
202
|
const selectablePipelines = computed(() =>
|
|
202
|
-
pipelines.pipelines.filter((p) =>
|
|
203
|
+
pipelines.pipelines.filter((p) => pipelineAllowedForManualStart(p, frame.value, board.blocks)),
|
|
203
204
|
)
|
|
204
205
|
const pipelineMenu = computed(() => [
|
|
205
206
|
[
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// pipeline is picked, the workspace issue-tracker choice is surfaced inline (it is
|
|
7
7
|
// where that pipeline files its ticket) and saved alongside.
|
|
8
8
|
import type { Recurrence, ScheduleTemplate } from '~/types/recurring'
|
|
9
|
-
import {
|
|
9
|
+
import { pipelineAllowedForSchedule } from '~/utils/pipeline'
|
|
10
10
|
|
|
11
11
|
const ui = useUiStore()
|
|
12
12
|
const board = useBoardStore()
|
|
@@ -52,8 +52,9 @@ function defaultRecurrence(): Recurrence {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// Hide UI-testing pipelines when the frame has no UI to exercise — they'd be refused at run start.
|
|
55
|
+
// Also hide `'one-off'`-only pipelines: attaching one to a schedule is refused server-side.
|
|
55
56
|
const selectablePipelines = computed(() =>
|
|
56
|
-
pipelines.pipelines.filter((p) =>
|
|
57
|
+
pipelines.pipelines.filter((p) => pipelineAllowedForSchedule(p, frame.value, board.blocks)),
|
|
57
58
|
)
|
|
58
59
|
const pipelineMenu = computed(() => [
|
|
59
60
|
selectablePipelines.value.map((p) => ({
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { onKeyStroke } from '@vueuse/core'
|
|
3
3
|
import type { Block } from '~/types/domain'
|
|
4
4
|
import { blockTypeMeta, STATUS_META } from '~/utils/catalog'
|
|
5
|
-
import {
|
|
5
|
+
import { pipelineAllowedForManualStart } from '~/utils/pipeline'
|
|
6
6
|
import PipelineProgress from '~/components/pipeline/PipelineProgress.vue'
|
|
7
7
|
|
|
8
8
|
const board = useBoardStore()
|
|
@@ -27,11 +27,12 @@ const deps = computed(() =>
|
|
|
27
27
|
(block.value?.dependsOn ?? []).map((id) => board.getBlock(id)).filter((b): b is Block => !!b),
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
// Hide UI-testing pipelines when this block's frame has no UI to exercise
|
|
30
|
+
// Hide UI-testing pipelines when this block's frame has no UI to exercise, and `'recurring'`-only
|
|
31
|
+
// pipelines (a manual run of one is refused server-side) — see the backend gate.
|
|
31
32
|
const runMenu = computed(() => {
|
|
32
33
|
const frame = block.value ? board.serviceOf(block.value) : undefined
|
|
33
34
|
return pipelines.pipelines
|
|
34
|
-
.filter((p) =>
|
|
35
|
+
.filter((p) => pipelineAllowedForManualStart(p, frame, board.blocks))
|
|
35
36
|
.map((p) => ({
|
|
36
37
|
label: p.name,
|
|
37
38
|
icon: 'i-lucide-play',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { Block, BlockStatus } from '~/types/domain'
|
|
3
3
|
import { blockTypeMeta, STATUS_META } from '~/utils/catalog'
|
|
4
|
-
import {
|
|
4
|
+
import { pipelineAllowedForManualStart } from '~/utils/pipeline'
|
|
5
5
|
import TaskContextDocs from '~/components/documents/TaskContextDocs.vue'
|
|
6
6
|
import TaskContextIssues from '~/components/tasks/TaskContextIssues.vue'
|
|
7
7
|
import TaskAgentConfig from '~/components/panels/inspector/TaskAgentConfig.vue'
|
|
@@ -169,12 +169,13 @@ const taskBranchUrl = computed(() => {
|
|
|
169
169
|
return base ? `${base}/tree/${pr.branch}` : null
|
|
170
170
|
})
|
|
171
171
|
|
|
172
|
-
// Hide UI-testing pipelines when this block's frame has no UI to exercise
|
|
173
|
-
//
|
|
172
|
+
// Hide UI-testing pipelines when this block's frame has no UI to exercise, and `'recurring'`-only
|
|
173
|
+
// pipelines (a manual run of one is refused server-side) — they'd be refused at run start (see
|
|
174
|
+
// utils/pipeline + the backend gate).
|
|
174
175
|
const runMenu = computed(() => {
|
|
175
176
|
const frame = block.value ? board.serviceOf(block.value) : undefined
|
|
176
177
|
return pipelines.pipelines
|
|
177
|
-
.filter((p) =>
|
|
178
|
+
.filter((p) => pipelineAllowedForManualStart(p, frame, board.blocks))
|
|
178
179
|
.map((p) => ({
|
|
179
180
|
label: p.name,
|
|
180
181
|
icon: 'i-lucide-play',
|
|
@@ -4,7 +4,7 @@ import { connectionNeighborIds } from '@cat-factory/contracts'
|
|
|
4
4
|
import type { Block } from '~/types/domain'
|
|
5
5
|
import type { WritebackOverride } from '~/types/tracker'
|
|
6
6
|
import { mergePresetOptionLabel, mergePresetThresholds } from '~/utils/mergePreset'
|
|
7
|
-
import {
|
|
7
|
+
import { pipelineAllowedForManualStart } from '~/utils/pipeline'
|
|
8
8
|
import InspectorSection from '~/components/panels/inspector/InspectorSection.vue'
|
|
9
9
|
|
|
10
10
|
const props = defineProps<{ block: Block }>()
|
|
@@ -132,11 +132,14 @@ function setModelPreset(id: string) {
|
|
|
132
132
|
const selectedPipeline = computed(() =>
|
|
133
133
|
props.block.pipelineId ? pipelines.getPipeline(props.block.pipelineId) : undefined,
|
|
134
134
|
)
|
|
135
|
-
// Hide UI-testing pipelines when this task's frame has no UI to exercise
|
|
136
|
-
//
|
|
135
|
+
// Hide UI-testing pipelines when this task's frame has no UI to exercise, and `'recurring'`-only
|
|
136
|
+
// pipelines (the task's manual Run control can't start one) — they'd be refused at run start
|
|
137
|
+
// (see utils/pipeline + the backend gate).
|
|
137
138
|
const taskFrame = computed(() => board.serviceOf(props.block))
|
|
138
139
|
const selectablePipelines = computed(() =>
|
|
139
|
-
pipelines.pipelines.filter((p) =>
|
|
140
|
+
pipelines.pipelines.filter((p) =>
|
|
141
|
+
pipelineAllowedForManualStart(p, taskFrame.value, board.blocks),
|
|
142
|
+
),
|
|
140
143
|
)
|
|
141
144
|
const pipelineMenu = computed(() => [
|
|
142
145
|
[
|
package/app/utils/pipeline.ts
CHANGED
|
@@ -20,3 +20,33 @@ export function pipelineAllowedForFrame(
|
|
|
20
20
|
): boolean {
|
|
21
21
|
return !pipelineHasVisualStep(pipeline) || frameAllowsVisualPipeline(frame, blocks)
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
// Launch-availability filters, the surface counterpart to the backend's start-origin gate (a
|
|
25
|
+
// `'recurring'`-only pipeline can't be started as a one-off manual task, and a `'one-off'`-only
|
|
26
|
+
// pipeline can't be attached to a schedule). `availability` absent ⇒ `'both'` (unrestricted), so
|
|
27
|
+
// legacy/unset pipelines pass both. Composed with {@link pipelineAllowedForFrame} at each picker.
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Whether `pipeline` may be started as a MANUAL one-off task run (the board/inspector Run menus,
|
|
31
|
+
* the add-task modal, the task run-settings default). Excludes `'recurring'`-only pipelines the
|
|
32
|
+
* backend would refuse.
|
|
33
|
+
*/
|
|
34
|
+
export function pipelineAllowedForManualStart(
|
|
35
|
+
pipeline: Pipeline,
|
|
36
|
+
frame: Block | undefined,
|
|
37
|
+
blocks: readonly Block[],
|
|
38
|
+
): boolean {
|
|
39
|
+
return pipeline.availability !== 'recurring' && pipelineAllowedForFrame(pipeline, frame, blocks)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Whether `pipeline` may be attached to a RECURRING schedule (the recurring-pipeline modal).
|
|
44
|
+
* Excludes `'one-off'`-only pipelines the backend would refuse.
|
|
45
|
+
*/
|
|
46
|
+
export function pipelineAllowedForSchedule(
|
|
47
|
+
pipeline: Pipeline,
|
|
48
|
+
frame: Block | undefined,
|
|
49
|
+
blocks: readonly Block[],
|
|
50
|
+
): boolean {
|
|
51
|
+
return pipeline.availability !== 'one-off' && pipelineAllowedForFrame(pipeline, frame, blocks)
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.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.93.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@toad-contracts/testing": "0.3.2",
|