@frontera-sdk/cli 1.52.38 → 1.52.40
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/README.md +9 -0
- package/package.json +6 -4
- package/src/adopt.ts +6 -2
- package/src/api/apps-api.ts +86 -4
- package/src/api/blueprint-authoring-api.ts +35 -11
- package/src/api/dataset-api.ts +29 -0
- package/src/api/governed-action-api.ts +90 -2
- package/src/api/platform-api.ts +87 -2
- package/src/api/workflow-api.ts +33 -2
- package/src/app-contract.ts +156 -0
- package/src/app-lock.ts +125 -0
- package/src/args.ts +14 -3
- package/src/auth-verify.ts +10 -0
- package/src/automation-template.ts +12 -1
- package/src/blueprint/action-rules.ts +516 -0
- package/src/blueprint/action-semantic-fit.ts +205 -0
- package/src/blueprint/compile.ts +51 -2
- package/src/blueprint/diff.ts +34 -2
- package/src/blueprint/metric-query.ts +215 -0
- package/src/blueprint/metric-rules.ts +122 -0
- package/src/blueprint/object-sets.ts +116 -0
- package/src/blueprint/ontology-edit-plan.ts +48 -4
- package/src/blueprint/projection.ts +24 -1
- package/src/blueprint/scaffold.ts +84 -42
- package/src/commands/action/available.ts +1 -1
- package/src/commands/action/criteria-refusal.ts +84 -0
- package/src/commands/action/decide.ts +5 -2
- package/src/commands/action/deploy.ts +13 -4
- package/src/commands/action/list.ts +134 -19
- package/src/commands/action/requests.ts +34 -6
- package/src/commands/action/submit.ts +28 -13
- package/src/commands/agent/index-commands.ts +69 -7
- package/src/commands/agent/resolve.ts +2 -0
- package/src/commands/app/checks.ts +44 -0
- package/src/commands/app/deploy.ts +243 -60
- package/src/commands/app/deployments.ts +97 -0
- package/src/commands/app/dev.ts +103 -11
- package/src/commands/app/init.ts +36 -3
- package/src/commands/app/promote.ts +45 -19
- package/src/commands/app/pull.ts +3 -1
- package/src/commands/app/rollback.ts +46 -0
- package/src/commands/app/sdk.ts +54 -8
- package/src/commands/app/unpin.ts +27 -0
- package/src/commands/app/versions.ts +1 -1
- package/src/commands/automation/bindings.ts +4 -2
- package/src/commands/automation/build-entry.ts +4 -1
- package/src/commands/automation/index-commands.ts +3 -1
- package/src/commands/automation/pull.ts +6 -1
- package/src/commands/automation/run.ts +34 -9
- package/src/commands/blueprint/bind.ts +2 -1
- package/src/commands/blueprint/declarative.ts +331 -31
- package/src/commands/blueprint/get.ts +6 -2
- package/src/commands/blueprint/grants.ts +64 -10
- package/src/commands/blueprint/metric.ts +108 -0
- package/src/commands/blueprint/object-sets.ts +71 -0
- package/src/commands/blueprint/query.ts +155 -31
- package/src/commands/dataset/index-commands.ts +156 -7
- package/src/commands/knowledge/index-commands.ts +122 -20
- package/src/commands/local/check.ts +657 -44
- package/src/commands/local/data.ts +33 -12
- package/src/commands/local/dev.ts +875 -88
- package/src/commands/local/docs-mcp.ts +10 -18
- package/src/commands/local/index-commands.ts +300 -63
- package/src/commands/local/init.ts +18 -5
- package/src/commands/local/key.ts +0 -3
- package/src/commands/local/providers.ts +0 -7
- package/src/commands/local/remove.ts +116 -0
- package/src/commands/local/schema.ts +3 -4
- package/src/commands/local/sdk-refresh.ts +59 -0
- package/src/commands/local/snapshot.ts +100 -0
- package/src/commands/local/sync-request.ts +320 -13
- package/src/commands/local/sync.ts +102 -5
- package/src/commands/mcp/serve.ts +34 -0
- package/src/commands/registry.ts +52 -8
- package/src/commands/types.ts +29 -0
- package/src/commands/workflow/archive.ts +46 -0
- package/src/commands/workflow/get.ts +2 -1
- package/src/commands/workflow/index-commands.ts +5 -0
- package/src/commands/workflow/push.ts +49 -2
- package/src/commands/workflow/run.ts +65 -7
- package/src/commands/workflow/runs.ts +9 -6
- package/src/commands/workflow/webhook-test.ts +166 -0
- package/src/config.ts +43 -6
- package/src/dev-broker.ts +52 -0
- package/src/exit.ts +103 -4
- package/src/flag-help.ts +77 -17
- package/src/forge/touches.ts +15 -12
- package/src/function-outside-imports.ts +89 -0
- package/src/harness.ts +42 -24
- package/src/heal.ts +112 -1
- package/src/local/fix-words.ts +12 -0
- package/src/local/function-bundle-recovery.ts +775 -0
- package/src/local/local-actions.ts +103 -10
- package/src/local/local-agent-action-grants.ts +210 -0
- package/src/local/local-agent-checks.ts +232 -0
- package/src/local/local-agent-grants.ts +29 -7
- package/src/local/local-agent-lean-plugins.ts +68 -0
- package/src/local/local-agent-missing-tools.ts +68 -0
- package/src/local/local-agent-name.ts +27 -0
- package/src/local/local-app-code.ts +191 -0
- package/src/local/local-app-dev-files.ts +186 -0
- package/src/local/local-app-dev-session.ts +88 -0
- package/src/local/local-app-lock-install.ts +114 -0
- package/src/local/local-app-pulled.ts +167 -0
- package/src/local/local-app-restore.ts +111 -0
- package/src/local/local-app-runtime.ts +68 -0
- package/src/local/local-app-sdk-paths.ts +149 -0
- package/src/local/local-app-sdk.ts +509 -0
- package/src/local/local-applied.ts +211 -21
- package/src/local/local-apply-history.ts +84 -0
- package/src/local/local-apply-summary.ts +86 -0
- package/src/local/local-apply-watchdog.ts +95 -0
- package/src/local/local-apps.ts +180 -7
- package/src/local/local-blueprint-errors.ts +198 -0
- package/src/local/local-blueprint-outline.ts +31 -12
- package/src/local/local-blueprint-schemas.ts +582 -0
- package/src/local/local-build-inputs.ts +48 -0
- package/src/local/local-build-summary.ts +495 -28
- package/src/local/local-case-evidence.ts +120 -0
- package/src/local/local-case-not-run.ts +153 -0
- package/src/local/local-chat-apps.ts +93 -16
- package/src/local/local-check-inherited.ts +83 -0
- package/src/local/local-cities.ts +89 -0
- package/src/local/local-component-health.ts +119 -0
- package/src/local/local-control.ts +34 -7
- package/src/local/local-db-snapshot.ts +348 -0
- package/src/local/local-dev-references.ts +346 -35
- package/src/local/local-dev-sync.ts +136 -7
- package/src/local/local-docker.ts +35 -1
- package/src/local/local-docs-search.ts +1 -1
- package/src/local/local-docs.ts +281 -2
- package/src/local/local-empty-workflows.ts +92 -0
- package/src/local/local-env.ts +16 -1
- package/src/local/local-file-checks.ts +104 -0
- package/src/local/local-function-ids.ts +141 -0
- package/src/local/local-function-recovery.ts +141 -0
- package/src/local/local-function-state.ts +87 -0
- package/src/local/local-keys.ts +7 -5
- package/src/local/local-knowledge-ingestion.ts +225 -0
- package/src/local/local-knowledge-uploads.ts +217 -0
- package/src/local/local-media-placeholders.ts +182 -0
- package/src/local/local-media-sets.ts +90 -10
- package/src/local/local-model-parameters.ts +89 -0
- package/src/local/local-object-sets.ts +18 -6
- package/src/local/local-operating.ts +35 -1
- package/src/local/local-org-settings.ts +205 -7
- package/src/local/local-orphans.ts +321 -0
- package/src/local/local-personas.ts +296 -0
- package/src/local/local-portability.ts +141 -16
- package/src/local/local-ports.ts +99 -7
- package/src/local/local-project-notices.ts +234 -0
- package/src/local/local-project-secrets.ts +133 -0
- package/src/local/local-project.ts +12 -0
- package/src/local/local-provider-refusal.ts +66 -0
- package/src/local/local-request-evidence.ts +112 -0
- package/src/local/local-runtime-health.ts +123 -0
- package/src/local/local-runtime-history.ts +50 -0
- package/src/local/local-runtime-target.ts +42 -0
- package/src/local/local-sample-data.ts +141 -0
- package/src/local/local-sample-remake.ts +138 -0
- package/src/local/local-scaffold.ts +336 -53
- package/src/local/local-schema-check.ts +148 -0
- package/src/local/local-schemas.ts +742 -25
- package/src/local/local-secret-carry.ts +107 -0
- package/src/local/local-secrets.ts +38 -8
- package/src/local/local-seed.ts +102 -26
- package/src/local/local-stand-ins.ts +1 -1
- package/src/local/local-state.ts +43 -2
- package/src/local/local-studio-server.ts +170 -7
- package/src/local/local-supervisor.ts +44 -6
- package/src/local/local-sync-names.ts +2 -0
- package/src/local/local-sync-plan.ts +11 -0
- package/src/local/local-sync-push.ts +10 -7
- package/src/local/local-sync-refs.ts +49 -3
- package/src/local/local-sync-remote.ts +343 -32
- package/src/local/local-sync-snapshot.ts +15 -10
- package/src/local/local-synthetic-data.ts +2116 -99
- package/src/local/local-test-baseline.ts +113 -0
- package/src/local/local-test-cases.ts +76 -1
- package/src/local/local-test-runner.ts +582 -91
- package/src/local/local-test-runs.ts +13 -5
- package/src/local/local-vendored-sdk.ts +183 -0
- package/src/local/local-workflow-state.ts +16 -3
- package/src/local/local-workflow-tests.ts +482 -0
- package/src/local/local-workspace-grants.ts +81 -0
- package/src/main.ts +50 -9
- package/src/mcp/a11y-scan.ts +55 -0
- package/src/mcp/browser/ax-snapshot.ts +181 -0
- package/src/mcp/browser/credentials.ts +78 -0
- package/src/mcp/browser/frames.ts +336 -0
- package/src/mcp/browser/headless-session.ts +413 -0
- package/src/mcp/browser/headless-tab.ts +575 -0
- package/src/mcp/browser/keys.ts +70 -0
- package/src/mcp/browser/page-scripts.ts +129 -0
- package/src/mcp/browser/wait.ts +73 -0
- package/src/mcp/forge-link.ts +126 -0
- package/src/mcp/headless.ts +199 -0
- package/src/mcp/mcp-apps.ts +435 -0
- package/src/mcp/mcp-chat.ts +226 -0
- package/src/mcp/mcp-cli.ts +53 -0
- package/src/mcp/mcp-protocol.ts +122 -0
- package/src/mcp/mcp-runtime.ts +113 -0
- package/src/mcp/mcp-server.ts +108 -0
- package/src/mcp/mcp-traces.ts +409 -0
- package/src/mcp/page-observation.ts +193 -0
- package/src/mcp/tools/agent-tools.ts +700 -0
- package/src/mcp/tools/app-tools.ts +241 -0
- package/src/mcp/tools/browser-tools.ts +310 -0
- package/src/mcp/tools/docs-tools.ts +32 -0
- package/src/mcp/tools/project-tools.ts +205 -0
- package/src/mcp/tools/test-tools.ts +339 -0
- package/src/mcp/tools/workflow-tools.ts +611 -0
- package/src/output.ts +1 -1
- package/src/pack.ts +8 -3
- package/src/packaging.ts +1 -1
- package/src/project-bootstrap.ts +107 -4
- package/src/project-context.ts +18 -1
- package/src/project.ts +27 -2
- package/src/provenance.ts +25 -0
- package/src/render-evidence.ts +65 -7
- package/src/template.ts +14 -8
- package/src/templates/next-app-files.ts +35 -6
- package/src/templates/next-skills.ts +61 -27
- package/src/vendor/kit-assets.json +6 -6
- package/src/vendor/sdk-sources.json +24 -21
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A file checked against the JSON Schema `frontera local schema <kind>`
|
|
3
|
+
* prints for it, before anything reads it: each problem said at its path in
|
|
4
|
+
* the file (`cases.2.checks.0.value: must be text`), not as a crash in the
|
|
5
|
+
* code that reads the field later.
|
|
6
|
+
*
|
|
7
|
+
* Only the keywords this CLI's own schemas use (`local-schemas.ts`,
|
|
8
|
+
* `local-blueprint-schemas.ts`): type, enum, const, required, properties,
|
|
9
|
+
* additionalProperties, items, the length and count bounds, pattern,
|
|
10
|
+
* minimum/maximum, anyOf, oneOf and allOf. A keyword it does not know is not
|
|
11
|
+
* checked, so a schema is never stricter here than it says.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
type Schema = Record<string, unknown>
|
|
15
|
+
|
|
16
|
+
export interface SchemaProblem {
|
|
17
|
+
/** Where in the file: `cases.2.checks.0.value`; empty for the document itself. */
|
|
18
|
+
path: string
|
|
19
|
+
message: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const isRecord = (v: unknown): v is Record<string, unknown> => !!v && typeof v === 'object' && !Array.isArray(v)
|
|
23
|
+
|
|
24
|
+
const WORDS: Record<string, string> = {
|
|
25
|
+
string: 'text',
|
|
26
|
+
number: 'a number',
|
|
27
|
+
integer: 'a whole number',
|
|
28
|
+
boolean: 'true or false',
|
|
29
|
+
object: 'a mapping',
|
|
30
|
+
array: 'a list',
|
|
31
|
+
null: 'null',
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function typeOf(value: unknown): string {
|
|
35
|
+
if (value === null) return 'null'
|
|
36
|
+
if (Array.isArray(value)) return 'array'
|
|
37
|
+
if (typeof value === 'number') return Number.isInteger(value) ? 'integer' : 'number'
|
|
38
|
+
return typeof value
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function fitsType(value: unknown, type: string): boolean {
|
|
42
|
+
const actual = typeOf(value)
|
|
43
|
+
if (type === 'number') return actual === 'number' || actual === 'integer'
|
|
44
|
+
return actual === type
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const show = (v: unknown) => (typeof v === 'string' ? `"${v}"` : JSON.stringify(v))
|
|
48
|
+
|
|
49
|
+
const join = (path: string, key: string | number) => (path ? `${path}.${key}` : String(key))
|
|
50
|
+
|
|
51
|
+
/** `anyOf` whose branches only require keys: said as the key sets that would do. */
|
|
52
|
+
function requiredOnly(branches: unknown[]): string[][] | null {
|
|
53
|
+
const sets: string[][] = []
|
|
54
|
+
for (const b of branches) {
|
|
55
|
+
if (!isRecord(b) || Object.keys(b).some((k) => k !== 'required') || !Array.isArray(b.required)) return null
|
|
56
|
+
sets.push(b.required as string[])
|
|
57
|
+
}
|
|
58
|
+
return sets
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Every problem with `value` against `schema`, at `path`. */
|
|
62
|
+
export function checkAgainstSchema(value: unknown, schema: Schema, path = ''): SchemaProblem[] {
|
|
63
|
+
const out: SchemaProblem[] = []
|
|
64
|
+
const say = (message: string, at = path) => out.push({ path: at, message })
|
|
65
|
+
|
|
66
|
+
if ('const' in schema && JSON.stringify(value) !== JSON.stringify(schema.const)) {
|
|
67
|
+
say(`must be ${show(schema.const)}`)
|
|
68
|
+
return out
|
|
69
|
+
}
|
|
70
|
+
if (Array.isArray(schema.enum) && !schema.enum.some((e) => JSON.stringify(e) === JSON.stringify(value))) {
|
|
71
|
+
say(`must be one of ${schema.enum.map(show).join(', ')}; it is ${show(value)}`)
|
|
72
|
+
return out
|
|
73
|
+
}
|
|
74
|
+
const types = typeof schema.type === 'string' ? [schema.type] : Array.isArray(schema.type) ? (schema.type as string[]) : null
|
|
75
|
+
if (types && !types.some((t) => fitsType(value, t))) {
|
|
76
|
+
say(`must be ${types.map((t) => WORDS[t] ?? t).join(' or ')}; it is ${WORDS[typeOf(value)] ?? typeOf(value)}${typeof value === 'object' && value !== null ? '' : ` (${show(value)})`}`)
|
|
77
|
+
return out
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (typeof value === 'string') {
|
|
81
|
+
if (typeof schema.minLength === 'number' && value.length < schema.minLength) say(schema.minLength === 1 ? 'must not be empty' : `must be at least ${schema.minLength} characters`)
|
|
82
|
+
if (typeof schema.maxLength === 'number' && value.length > schema.maxLength) say(`must be at most ${schema.maxLength} characters`)
|
|
83
|
+
if (typeof schema.pattern === 'string') {
|
|
84
|
+
try {
|
|
85
|
+
if (!new RegExp(schema.pattern).test(value)) say(`${show(value)} does not match ${schema.pattern}`)
|
|
86
|
+
} catch {
|
|
87
|
+
// A pattern this engine cannot read is not checked here.
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (typeof value === 'number') {
|
|
92
|
+
if (typeof schema.minimum === 'number' && value < schema.minimum) say(`must be at least ${schema.minimum}`)
|
|
93
|
+
if (typeof schema.maximum === 'number' && value > schema.maximum) say(`must be at most ${schema.maximum}`)
|
|
94
|
+
}
|
|
95
|
+
if (Array.isArray(value)) {
|
|
96
|
+
if (typeof schema.minItems === 'number' && value.length < schema.minItems) say(schema.minItems === 1 ? 'must list at least one item' : `must list at least ${schema.minItems} items`)
|
|
97
|
+
if (typeof schema.maxItems === 'number' && value.length > schema.maxItems) say(schema.maxItems === 0 ? 'must be empty' : `must list at most ${schema.maxItems} items`)
|
|
98
|
+
if (isRecord(schema.items)) value.forEach((item, i) => out.push(...checkAgainstSchema(item, schema.items as Schema, join(path, i))))
|
|
99
|
+
}
|
|
100
|
+
if (isRecord(value)) {
|
|
101
|
+
const props = isRecord(schema.properties) ? schema.properties : {}
|
|
102
|
+
for (const key of Array.isArray(schema.required) ? (schema.required as string[]) : []) {
|
|
103
|
+
if (!(key in value)) say(`\`${key}\` is required`, path)
|
|
104
|
+
}
|
|
105
|
+
const keys = Object.keys(value)
|
|
106
|
+
if (typeof schema.minProperties === 'number' && keys.length < schema.minProperties) say(`must hold at least ${schema.minProperties} key${schema.minProperties === 1 ? '' : 's'}`)
|
|
107
|
+
if (typeof schema.maxProperties === 'number' && keys.length > schema.maxProperties) say(`must hold at most ${schema.maxProperties} key${schema.maxProperties === 1 ? '' : 's'}`)
|
|
108
|
+
// A key the file names itself (a variable's name): checked against its pattern.
|
|
109
|
+
const names = isRecord(schema.propertyNames) && typeof schema.propertyNames.pattern === 'string' ? new RegExp(schema.propertyNames.pattern, 'u') : null
|
|
110
|
+
for (const key of keys) if (names && !names.test(key)) say(`\`${key}\` is not a name this takes (it matches ${schema.propertyNames && (schema.propertyNames as Schema).pattern})`, join(path, key))
|
|
111
|
+
for (const key of keys) {
|
|
112
|
+
const child = props[key]
|
|
113
|
+
if (isRecord(child)) out.push(...checkAgainstSchema(value[key], child, join(path, key)))
|
|
114
|
+
else if (schema.additionalProperties === false) {
|
|
115
|
+
const known = Object.keys(props)
|
|
116
|
+
say(`\`${key}\` is not a key this file takes${known.length ? ` (it takes ${known.map((k) => `\`${k}\``).join(', ')})` : ''}`, join(path, key))
|
|
117
|
+
} else if (isRecord(schema.additionalProperties)) out.push(...checkAgainstSchema(value[key], schema.additionalProperties, join(path, key)))
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
for (const sub of Array.isArray(schema.allOf) ? schema.allOf : []) if (isRecord(sub)) out.push(...checkAgainstSchema(value, sub, path))
|
|
122
|
+
if (Array.isArray(schema.anyOf) && schema.anyOf.length) {
|
|
123
|
+
const results = schema.anyOf.map((b) => (isRecord(b) ? checkAgainstSchema(value, b, path) : []))
|
|
124
|
+
if (!results.some((r) => r.length === 0)) {
|
|
125
|
+
const sets = requiredOnly(schema.anyOf)
|
|
126
|
+
if (sets) say(`needs ${sets.map((s) => s.map((k) => `\`${k}\``).join(' and ')).join(', or ')}`)
|
|
127
|
+
else out.push(...closest(results))
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (Array.isArray(schema.oneOf) && schema.oneOf.length) {
|
|
131
|
+
const branches = schema.oneOf.filter(isRecord)
|
|
132
|
+
// A branch picked by a `const` key (`kind: file`) is the one to report against.
|
|
133
|
+
const picked = branches.find((b) => isRecord(b.properties) && Object.entries(b.properties).some(([k, p]) => isRecord(p) && 'const' in p && isRecord(value) && value[k] === p.const))
|
|
134
|
+
const results = (picked ? [picked] : branches).map((b) => checkAgainstSchema(value, b, path))
|
|
135
|
+
if (!results.some((r) => r.length === 0)) out.push(...closest(results))
|
|
136
|
+
}
|
|
137
|
+
return out
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Of several branches that failed, the one that came nearest: fewest problems. */
|
|
141
|
+
function closest(results: SchemaProblem[][]): SchemaProblem[] {
|
|
142
|
+
return [...results].sort((a, b) => a.length - b.length)[0] ?? []
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Problems as lines: `file: path: message`. */
|
|
146
|
+
export function describeProblems(problems: SchemaProblem[], file?: string): string[] {
|
|
147
|
+
return problems.map((p) => `${file ? `${file}: ` : ''}${p.path ? `${p.path}: ` : ''}${p.message}`)
|
|
148
|
+
}
|