@frontera-sdk/cli 1.50.28 → 1.50.29
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/package.json +4 -4
- package/src/forge/touch-details.ts +4 -0
- package/src/forge/touches.ts +23 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontera-sdk/cli",
|
|
3
|
-
"version": "1.50.
|
|
3
|
+
"version": "1.50.29",
|
|
4
4
|
"description": "The frontera CLI — scaffold, pull, save and deploy Frontera apps and automations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"frontera",
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@anthropic-ai/claude-agent-sdk": "^0.3.251",
|
|
42
|
-
"@frontera-sdk/functions": "1.50.
|
|
43
|
-
"@frontera-sdk/core": "1.50.
|
|
42
|
+
"@frontera-sdk/functions": "1.50.29",
|
|
43
|
+
"@frontera-sdk/core": "1.50.29",
|
|
44
44
|
"ai": "^6.0.116",
|
|
45
45
|
"gray-matter": "^4.0.3",
|
|
46
46
|
"yaml": "^2.9.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@frontera-sdk/forge-contracts": "1.50.
|
|
49
|
+
"@frontera-sdk/forge-contracts": "1.50.29",
|
|
50
50
|
"@types/bun": "^1.3.14",
|
|
51
51
|
"typescript": "^5.9.3"
|
|
52
52
|
}
|
|
@@ -65,6 +65,10 @@ export const enrichTouch: TouchEnricher = async (touch, project) => {
|
|
|
65
65
|
// Any change to an agent that did not make it live may sit on the draft —
|
|
66
66
|
// from the CLI (`apply`, `skill-attach`) or from MCP (`update_agent`,
|
|
67
67
|
// `set_prompt`, `bind_skill`, …). No draft is a normal answer, not an error.
|
|
68
|
+
//
|
|
69
|
+
// Every other kind, `workflow` included, is left alone on purpose: there is
|
|
70
|
+
// no section to focus (the workflow page opens whole) and the ref is already
|
|
71
|
+
// the slug a person reads, so an extra round trip would buy the pane nothing.
|
|
68
72
|
const { ref } = touch
|
|
69
73
|
const { profile } = project
|
|
70
74
|
if (touch.kind !== 'agent' || !ref || touch.live || !profile) return null
|
package/src/forge/touches.ts
CHANGED
|
@@ -35,6 +35,7 @@ export const FORGE_ARTIFACT_KINDS = [
|
|
|
35
35
|
'source',
|
|
36
36
|
'dataset',
|
|
37
37
|
'knowledge',
|
|
38
|
+
'workflow',
|
|
38
39
|
] as const satisfies readonly ForgeArtifactKind[]
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -52,6 +53,13 @@ export const TOUCHING_VERBS: Record<ForgeArtifactKind, readonly string[]> = {
|
|
|
52
53
|
source: ['create', 'update', 'revise', 'disable'],
|
|
53
54
|
dataset: ['create', 'upload', 'test-source'],
|
|
54
55
|
knowledge: ['create', 'attach', 'detach', 'upload', 'retry', 'delete'],
|
|
56
|
+
// `get`, `lineage`, `list`, `runs` and `validate` are reads — `validate` is
|
|
57
|
+
// `push --dry-run` and writes nothing. `cancel` is deliberately absent: it
|
|
58
|
+
// stops one in-flight run and leaves the definition, the versions and the
|
|
59
|
+
// live pointer exactly as they were, and its positional is a RUN id, not a
|
|
60
|
+
// slug, so it could not name the workflow page anyway. Same call
|
|
61
|
+
// `automation` makes, which lists `run` and not `cancel`.
|
|
62
|
+
workflow: ['push', 'promote', 'run'],
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
/** Verbs after which the artifact is LIVE, not merely changed. */
|
|
@@ -60,6 +68,7 @@ const LIVE_VERBS: Partial<Record<ForgeArtifactKind, readonly string[]>> = {
|
|
|
60
68
|
automation: ['promote', 'enable'],
|
|
61
69
|
app: ['promote'],
|
|
62
70
|
blueprint: ['publish'],
|
|
71
|
+
workflow: ['promote'],
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
/**
|
|
@@ -152,10 +161,19 @@ const MCP_READ_SEGMENT = /(^|_)(list|get)_/
|
|
|
152
161
|
const MCP_READ_TOOLS = new Set([
|
|
153
162
|
'navigate', 'validate_case', 'test_case', 'test_agent', 'test_channel', 'verify_mcp_server',
|
|
154
163
|
'blueprint_aggregate', 'blueprint_query',
|
|
164
|
+
// The workflow reads put their verb last (`workflow_list`, not
|
|
165
|
+
// `list_workflows`), so the segment above cannot see them. The name order is
|
|
166
|
+
// what the copilot's tool search ranks on, and changing it to suit this
|
|
167
|
+
// regex would cost reach on the surface people actually use.
|
|
168
|
+
'workflow_list', 'workflow_inspect', 'workflow_resources', 'workflow_runs',
|
|
169
|
+
// Runs one step of a draft and changes no part of the definition. Same
|
|
170
|
+
// call as `test_agent` two lines up, and for the same reason: an authoring
|
|
171
|
+
// loop tests a step repeatedly, and each one would jerk the pane.
|
|
172
|
+
'workflow_test_step',
|
|
155
173
|
])
|
|
156
174
|
|
|
157
175
|
/** Tools whose success makes the artifact LIVE. */
|
|
158
|
-
const MCP_LIVE_TOOLS = new Set(['publish_agent', 'publish_case', 'promote_platform_app_version'])
|
|
176
|
+
const MCP_LIVE_TOOLS = new Set(['publish_agent', 'publish_case', 'promote_platform_app_version', 'workflow_promote_version'])
|
|
159
177
|
|
|
160
178
|
/** Tools that remove the artifact: nothing left to preview. */
|
|
161
179
|
const MCP_GONE_TOOLS = new Set(['delete_agent'])
|
|
@@ -174,6 +192,10 @@ function mcpArtifact(tool: string, input: Record<string, unknown>): { kind: Forg
|
|
|
174
192
|
const objectType = str('objectTypeApiName') ?? (/_object_type$/.test(tool) ? str('apiName') : null)
|
|
175
193
|
return { kind: 'blueprint', ref: objectType }
|
|
176
194
|
}
|
|
195
|
+
// Every workflow tool addresses the workflow by `slug` and none takes an
|
|
196
|
+
// agentId. Ahead of the agentId lookup so a later tool that happens to
|
|
197
|
+
// carry both still resolves to the workflow page its verb changed.
|
|
198
|
+
if (tool.startsWith('workflow_')) return { kind: 'workflow', ref: str('slug') }
|
|
177
199
|
const agentId = str('agentId') ?? str('caseId')
|
|
178
200
|
if (agentId) return { kind: 'agent', ref: agentId }
|
|
179
201
|
if (tool === 'data_create_source') return { kind: 'source', ref: str('displayName') ?? str('name') }
|