@frontera-sdk/cli 1.49.0 → 1.50.1
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/api/automation-api.ts +24 -24
- package/src/automation-template.ts +8 -8
- package/src/commands/automation/bindings.ts +11 -11
- package/src/commands/automation/dev.ts +8 -8
- package/src/commands/automation/index-commands.ts +20 -20
- package/src/commands/automation/init.ts +4 -4
- package/src/commands/automation/pull.ts +8 -8
- package/src/commands/automation/run.ts +18 -18
- package/src/commands/registry.ts +15 -3
- package/src/heal.ts +1 -1
- package/src/vendor/kit-assets.json +6 -6
- package/src/vendor/sdk-sources.json +15 -15
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"kitVersion": "1.1.
|
|
2
|
+
"kitVersion": "1.1.8",
|
|
3
3
|
"cli": {
|
|
4
4
|
"minimum": "1.45.0",
|
|
5
5
|
"maximumExclusive": "2.0.0"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"authoring-frontera-apps/agents/openai.yaml": "# Codex presentation metadata. Host-specific by design: SKILL.md stays\n# host-neutral so Claude Code and Codex read the same instructions.\ninterface:\n display_name: Building Frontera Apps\n short_description: Build the operational interface a recurring job needs.\n default_prompt: Operations need a board for today's delayed shipments — build it.\npolicy:\n allow_implicit_invocation: true\n",
|
|
15
15
|
"authoring-frontera-apps/SKILL.md": "---\nname: authoring-frontera-apps\ndescription: \"Use when building or changing a Frontera App — an operational interface and code project built on Frontera, reading governed data through the Blueprint SDK and served on the Applications surface. Triggers on outcome language too: \\\"operations need a shipment board\\\", \\\"a page where account managers update status\\\". Covers scaffolding, reading the granted model first, verifying against real data, and deploying a preview without promoting it.\"\n---\n\n# Authoring Frontera Apps\n\nA Frontera App is an **operational interface** — a code project built on\nFrontera that reads governed data through the Blueprint SDK and is served on the\nApplications surface. It is not a Plugin, which connects Frontera to a system\nsomebody else runs. The scaffold is Next.js today and a legacy Vite variant\nexists, but the framework is an authoring detail, not the definition. For the\nconcepts — what a Blueprint grant means for what an App can query — read\n`understanding-frontera`, reference `apps.md`.\n\nLoad `using-frontera` first. Confirm the profile before anything that writes.\n\n```bash\nfrontera auth current --json\nfrontera help --json\n```\n\n## Know the data before designing against it\n\n```bash\nfrontera blueprint list\nfrontera blueprint get <apiName>\n```\n\nWhat these return is the slice this workspace is **granted** — which is exactly\nwhat the App can query at runtime. Anything absent here will be absent for the\nApp too, so design from this output rather than from what the customer says they\nhave.\n\n## The loop\n\n```bash\nfrontera app init <name> # scaffold — installs from public npm only\nbun install\nfrontera app add <component> # registry source into the project\nbun run typecheck\nbun run build # the deploy gate — it must succeed\nfrontera app deploy --no-promote\n```\n\n`frontera app init` in an existing project adopts it rather than scaffolding a\nsecond one. `frontera app pull <app>` hydrates a working tree from a published\nversion or your saved draft; it refuses to clobber a dirty tree, and inside a\nsandbox there is usually no git to recover from — deal with the files it names.\n\n## Verify against real data, not a screenshot of a refusal\n\n```bash\nfrontera app dev\n```\n\nThis runs the App locally with short-lived authenticated Blueprint access. In a\nlegacy Vite App, opening `/` directly renders \"This app runs inside Frontera\"\ninstead of mounting — the handshake refuses an unknown parent, which is correct\nbehaviour, not a broken build. Open **`/dev-host.html`** instead: it frames the\nApp and plays the host side of the bridge, so the App mounts and reads real data.\nThat is the URL to screenshot or click through.\n\n## The generated SDK tree\n\n`src/frontera/` in a legacy scaffolded project is the SDK, copied in as source so\nthe project installs anywhere. Read it; never edit it, never rewrite an\n`@frontera-sdk/…` import to a relative path, never add `@frontera-sdk/*` to\n`package.json`. `frontera app sdk <action>` refreshes it. A Next App installs the\npublished packages instead and has no such tree.\n\nThe project's own `.agents/skills/` carry the SDK detail — data hooks, tables,\nActions, testing. Read those for anything about writing App code; this skill is\nabout the lifecycle around it.\n\n## Completion evidence\n\nAn App change is done when:\n\n1. `bun run typecheck` and `bun run build` both pass — the Vite build does not\n type-check, so the first is not implied by the second;\n2. the change was seen working against real data through `frontera app dev`;\n3. `frontera app deploy --no-promote` published an immutable version; and\n4. you reported the version and told the person what promoting it would do.\n\n**Do not promote.** `frontera app deploy` promotes by default — that is why the\npreview path always passes `--no-promote`. Promotion is a live transition; see\n`publishing-frontera`.\n\n## Recovery\n\n| Symptom | Move |\n|---|---|\n| exit 2, \"not in a Frontera app directory\" | `cd` into the project, or pass `--dir` |\n| build fails after `app add` | read the component source it copied in; it is yours now |\n| deploy rejected | run `bun run build` locally — deploy builds the same output |\n| exit 4 | `frontera auth verify` — the key may have been revoked mid-task |\n",
|
|
16
16
|
"authoring-frontera-automations/agents/openai.yaml": "# Codex presentation metadata. Host-specific by design: SKILL.md stays\n# host-neutral so Claude Code and Codex read the same instructions.\ninterface:\n display_name: Writing Frontera Automations\n short_description: Express a repeatable business workflow as a code workflow function.\n default_prompt: Implement our nightly reconciliation as a reusable workflow.\npolicy:\n allow_implicit_invocation: true\n",
|
|
17
|
-
"authoring-frontera-automations/SKILL.md": "---\nname: authoring-frontera-automations\ndescription: \"Use when creating or changing a Frontera Automation — a reusable code workflow function that performs a business workflow on the platform, with typed inputs, declared grants, durable steps and outputs. Triggers on outcome language too: \\\"a nightly reconciliation\\\", \\\"implement the approval workflow as reusable code\\\". Covers scaffolding, serving a working file to dev runs, deploying without promoting, and the kill switch.\"\n---\n\n# Authoring Frontera Automations\n\nAn Automation is a reusable **code workflow function** that performs a business\nworkflow on Frontera — TypeScript deployed to the platform, with typed inputs,\ndeclared grants, durable steps and a return value. The schedule is how it is\ninvoked, never what it is. It has no credential of its own: it reaches\ncapabilities through named grants, and reaches knowledge only through an agent\nthat has the base attached. For the boundary against Agents and against governed\nActions, read `understanding-frontera`, reference `automations-and-actions.md`.\n\nLoad `using-frontera` first.\n\n```bash\nfrontera auth current --json\nfrontera help --json\n```\n\n## Start from something that runs\n\n```bash\nfrontera
|
|
17
|
+
"authoring-frontera-automations/SKILL.md": "---\nname: authoring-frontera-automations\ndescription: \"Use when creating or changing a Frontera Automation — a reusable code workflow function that performs a business workflow on the platform, with typed inputs, declared grants, durable steps and outputs. Triggers on outcome language too: \\\"a nightly reconciliation\\\", \\\"implement the approval workflow as reusable code\\\". Covers scaffolding, serving a working file to dev runs, deploying without promoting, and the kill switch.\"\n---\n\n# Authoring Frontera Automations\n\nAn Automation is a reusable **code workflow function** that performs a business\nworkflow on Frontera — TypeScript deployed to the platform, with typed inputs,\ndeclared grants, durable steps and a return value. The schedule is how it is\ninvoked, never what it is. It has no credential of its own: it reaches\ncapabilities through named grants, and reaches knowledge only through an agent\nthat has the base attached. For the boundary against Agents and against governed\nActions, read `understanding-frontera`, reference `automations-and-actions.md`.\n\nLoad `using-frontera` first.\n\n```bash\nfrontera auth current --json\nfrontera help --json\n```\n\n## Start from something that runs\n\n```bash\nfrontera function init <name>\nfrontera function list\nfrontera function pull <slug> # hydrate an editable project from a deployed version\n```\n\n## Iterate without deploying\n\n```bash\nfrontera function dev ./src/index.ts # serve this file to dev runs\nfrontera function run <slug> --dev # run what dev is serving\nfrontera function runs <slug> # recent runs, and what each returned\n```\n\n`dev` serves your working copy — no deploy, no version, nothing published. This\nis where iteration belongs; every deploy is an immutable version.\n\n## Deploy a preview\n\n```bash\nfrontera function deploy ./src/index.ts --no-promote\nfrontera function versions <slug> # * marks the live one\n```\n\n`frontera function deploy` **promotes live by default**, which is why the\npreview path always passes `--no-promote`.\n\n## Inputs\n\nDeclare a manifest `inputs` schema — `{ name: { type: 'string'|'number'|'boolean'|'object'|'array', required?, default?, description?, enum? } }`, `required` and `default` mutually exclusive — and `ctx.input` is the validated, defaulted, frozen value the run started with (`{}` if `inputs` is absent; a run WITH input against a version with no `inputs` is refused). Cron triggers can only rely on defaults — a required field with none refuses at `deploy` (\"cron has nobody to ask\"). Run one with `frontera function run <slug> --input '{\"k\":1}'` or `--input @file.json`; Console Run-now renders a form from the schema. Dev runs (`--dev`) pass input straight through with only a 64KB size check — no schema check — because the local file, not the last deploy, is authoritative there. Never put a secret in an input: it is stored and shown in the trace by design; use a `secret:` grant instead.\n\n## Secrets and grants\n\n```bash\nfrontera secret set <NAME> --from -\n```\n\nThe automation then **names** the secret — `auth: { secret: 'NAME' }` plus a\n`secret:NAME` grant — and its value never enters the automation's process. An\ninline secret value is refused, and `.env` is never packaged; that is not\noverridable.\n\nA Plugin capability is reached the same way — a `plugin:<install>:<capability>`\ngrant and `ctx.plugin('<install>').call('<capability>', input)`. One grant per\ncapability; the install name is the one `frontera plugin list` prints.\nCapabilities that require approval cannot be granted to an automation (nobody to\nask): `deploy` refuses them. Prefer `ctx.plugin` over `ctx.http` for anything\nan installed Plugin already covers — the credential stays in the platform and\nthe call is governed by the install's policy.\n\n## The kill switch\n\n```bash\nfrontera function disable <slug> # stops scheduled execution immediately\nfrontera function enable <slug> # resumes it\n```\n\nIf a person reports an Automation misbehaving in production, `disable` first and\ndiagnose second. It is reversible; a bad scheduled run may not be.\n\n## Completion evidence\n\n1. a dev run through `frontera function run <slug> --dev` did what was asked,\n and you read `frontera function runs <slug>` to confirm what it returned —\n not just that it exited;\n2. `frontera function deploy … --no-promote` produced a version; and\n3. you reported the version and what promoting it would change.\n\n**Do not promote.** See `publishing-frontera`.\n",
|
|
18
18
|
"authoring-frontera-blueprint/agents/openai.yaml": "# Codex presentation metadata. Host-specific by design: SKILL.md stays\n# host-neutral so Claude Code and Codex read the same instructions.\ninterface:\n display_name: Changing Frontera Blueprint\n short_description: Change the organization's shared, governed model — safely.\n default_prompt: Make every team calculate active customer the same way.\npolicy:\n allow_implicit_invocation: true\n",
|
|
19
19
|
"authoring-frontera-blueprint/SKILL.md": "---\nname: authoring-frontera-blueprint\ndescription: \"Use when changing the organization's shared, governed model — object types, properties, link types, metrics, dataset bindings, editable properties or grants. Triggers on outcome language too: \\\"make every team calculate active customer the same way\\\", \\\"the App sees no data\\\". Covers pulling the draft to files, planning before applying, and recovering from a revision conflict. Requires an organization key.\"\n---\n\n# Authoring Frontera Blueprint\n\nBlueprint is the **shared model of the organization** — its object types,\nproperties, links, metrics, object sets, datasets, grants and Actions. One draft\nis shared by every workspace in the organization, so a change here is never\nlocal to you. For what each element means and how a change lands on the people\nalready reading it, read `understanding-frontera`, reference `blueprint.md`. For\nmodelling method — naming, identity, competency questions, review — use\n`designing-frontera-blueprint`.\n\nLoad `using-frontera` first.\n\n```bash\nfrontera auth current --json\nfrontera help --json\n```\n\n**Names come from the customer, never from a skill.** Every object type,\nproperty and link is named with the word the business itself uses, in its own\nlanguage — `Nasabah` if that is what they say, not `Customer` and not a generic\nabstraction. Any name you first read in a skill file, template or example is\nwrong for this organization by construction.\n\n`credentialKind` must be `organization`. A workspace key can read Blueprint and\ncannot author it — that is not a permission to escalate around, it is a different\nkey the person has to supply.\n\n## Read before writing\n\n```bash\nfrontera blueprint status # draft revision, and the active release\nfrontera blueprint catalog # what is on the shared draft\nfrontera blueprint get <apiName>\n```\n\n## The file-tree loop — preferred\n\n```bash\nfrontera blueprint pull # the draft, as files you can commit\nfrontera blueprint new <kind> <apiName> # scaffold one that validates as written\n# edit the files\nfrontera blueprint plan # what applying would change — writes nothing\nfrontera blueprint apply # reconcile the draft with the tree\nfrontera blueprint validate # produces a report\n```\n\n**Always `plan` before `apply`.** `plan` writes nothing and names every change,\nincluding the deletions `--prune` would make. Applying without reading a plan is\nhow a rename becomes a drop.\n\n`frontera blueprint rename <kind> <from> <to>` renames the artifact and its file\nas one act. Renaming a file by hand and applying reads as a delete plus a create.\n\nThe direct verbs — `frontera blueprint create|update|delete <kind>` — act on the\ndraft without a file tree. Use them for a single small change; use the tree for\nanything you want reviewable.\n\n## Binding data\n\n```bash\nfrontera dataset list\nfrontera blueprint bind <objectType> --dataset <name> --plan ./mapping.json\n# review the mapping skeleton, then\nfrontera blueprint bind <objectType> --dataset <name>\n```\n\nA rebind whose column contract differs from the pinned one is refused until\n`--accept-contract-change` says you looked. That refusal is the guard rail; do\nnot pass the flag to make an error go away.\n\n## Grants — nothing is visible until granted\n\n```bash\nfrontera blueprint grant workspace <name> <apiName...>\nfrontera blueprint grant agent <slug> <apiName...>\n```\n\nAn object type nobody granted is invisible to every App and agent. If a person\nreports that an App \"sees no data\", check grants before checking the App.\n\n## On exit 3\n\nSomeone changed the draft first. **Re-fetch, do not force.**\n\n```bash\nfrontera blueprint pull # get the current draft again\n# reapply your edit on top of it\nfrontera blueprint plan\nfrontera blueprint apply\n```\n\nForcing discards whatever the other author did, and on a shared organization\ndraft that other author is a colleague.\n\n## Completion evidence\n\n1. `frontera blueprint plan` output matches what was asked for;\n2. `frontera blueprint apply` succeeded;\n3. `frontera blueprint validate` produced a clean report; and\n4. you reported the draft revision and said the change is **on the draft, not\n released**.\n\n**Do not publish.** `frontera blueprint publish` releases to the whole\norganization — see `publishing-frontera`.\n\nKnow what that leaves unreachable: grants and `blueprint query` read the\npublished catalog, which only materializes at release, so nothing you model is\nqueryable while it stays on the draft. If the task requires reading back what\nyou built, say so and ask before publishing — do not conclude the pipeline is\nbroken, and do not publish on your own.\n",
|
|
20
20
|
"designing-frontera-blueprint/agents/openai.yaml": "# Codex presentation metadata. Host-specific by design: SKILL.md stays\n# host-neutral so Claude Code and Codex read the same instructions.\ninterface:\n display_name: Designing a Frontera Blueprint\n short_description: Decide what the shared model should be, or review one somebody wrote.\n default_prompt: Model our business so agents can actually use it.\npolicy:\n allow_implicit_invocation: true\n",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"designing-frontera-blueprint/scripts/lint_ontology.py": "#!/usr/bin/env python3\n\"\"\"\nlint_ontology.py — static checks over a model.yaml ontology definition.\n\nThese are the defects an adversarial review pass finds by hand: orphan object\ntypes, links whose join key does not exist, metrics referencing undeclared\nproperties, object types no competency question asks for, agents over tool\nbudget, status values no action produces. Catching them here is faster, cheaper\nand repeatable, which frees a human reviewer for the things static checks\ngenuinely cannot see — whether the model reflects the business.\n\nUsage:\n python3 lint_ontology.py model.yaml\n python3 lint_ontology.py model.yaml --json\n python3 lint_ontology.py model.yaml --severity error # errors only\n\nExit codes: 0 clean or warnings only · 1 errors found · 2 could not read input.\n\nSchema: see assets/model-schema.md. Every section is optional; the linter\nchecks what is present and stays quiet about what is not, so it is useful from\nthe first ten minutes of a design rather than only at the end.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport json\nimport re\nimport sys\nfrom collections import Counter, defaultdict, deque\n\ntry:\n import yaml\nexcept ImportError:\n sys.stderr.write(\n \"PyYAML is required: pip install pyyaml --break-system-packages\\n\"\n )\n sys.exit(2)\n\n\nclass Findings:\n def __init__(self) -> None:\n self.items: list[dict] = []\n\n def add(self, severity: str, check: str, where: str, message: str,\n fix: str = \"\") -> None:\n self.items.append({\n \"severity\": severity, \"check\": check, \"where\": where,\n \"message\": message, \"fix\": fix,\n })\n\n def error(self, *a, **k) -> None:\n self.add(\"error\", *a, **k)\n\n def warn(self, *a, **k) -> None:\n self.add(\"warning\", *a, **k)\n\n def info(self, *a, **k) -> None:\n self.add(\"info\", *a, **k)\n\n\n# --------------------------------------------------------------------------\n# helpers\n# --------------------------------------------------------------------------\n\ndef props_of(ot: dict) -> dict[str, dict]:\n return {p[\"api_name\"]: p for p in ot.get(\"properties\") or []\n if isinstance(p, dict) and p.get(\"api_name\")}\n\n\ndef normalise(name: str) -> str:\n \"\"\"Lowercase alphanumeric core of a name, for near-duplicate detection.\"\"\"\n return re.sub(r\"[^a-z0-9]\", \"\", name.lower())\n\n\ndef singularish(name: str) -> str:\n n = normalise(name)\n for suf in (\"ies\", \"es\", \"s\"):\n if n.endswith(suf) and len(n) > len(suf) + 2:\n return n[: -len(suf)]\n return n\n\n\n# --------------------------------------------------------------------------\n# checks\n# --------------------------------------------------------------------------\n\ndef check_object_types(m: dict, f: Findings) -> None:\n types = m.get(\"object_types\") or []\n if not types:\n f.warn(\"no-object-types\", \"model\", \"No object types defined yet.\")\n return\n\n seen: dict[str, str] = {}\n for ot in types:\n name = ot.get(\"api_name\")\n if not name:\n f.error(\"missing-api-name\", \"object_types\",\n \"An object type has no api_name.\")\n continue\n where = f\"objectType:{name}\"\n\n if name in seen:\n f.error(\"duplicate-type\", where, f\"'{name}' is defined twice.\")\n seen[name] = name\n\n if not re.match(r\"^[A-Z][A-Za-z0-9]*$\", name):\n f.warn(\"naming\", where,\n f\"'{name}' is not PascalCase alphanumeric.\",\n \"Object type names are tool names to an agent; keep them \"\n \"conventional and self-describing.\")\n\n p = props_of(ot)\n pk = ot.get(\"primary_key\")\n if not pk:\n f.error(\"no-primary-key\", where, \"No primary_key declared.\")\n elif pk not in p:\n f.error(\"pk-not-declared\", where,\n f\"primary_key '{pk}' is not among this type's properties.\")\n\n tp = ot.get(\"title_property\")\n if tp and tp not in p:\n f.error(\"title-not-declared\", where,\n f\"title_property '{tp}' is not among this type's properties.\")\n\n desc = (ot.get(\"description\") or \"\").strip()\n if not desc:\n f.error(\"no-description\", where,\n \"No description. An agent selects this type by its \"\n \"description; without one it is invisible or misused.\")\n elif len(desc) < 60:\n f.warn(\"thin-description\", where,\n \"Description is very short.\",\n \"State what it is, its grain, its source and refresh, and \"\n \"what it is not to be confused with.\")\n elif \"not to be confused\" not in desc.lower() and len(types) > 8:\n f.info(\"no-disambiguation\", where,\n \"Description does not disambiguate against a similar type.\",\n \"In a model this size, near-synonyms are the main cause of \"\n \"an agent picking the wrong type.\")\n\n if ot.get(\"kind\") == \"extension\" and not ot.get(\"extends\"):\n f.error(\"extension-no-core\", where,\n \"kind is 'extension' but no 'extends' is set.\")\n\n if ot.get(\"status\") not in (None, \"active\", \"experimental\", \"deprecated\"):\n f.warn(\"bad-status\", where,\n f\"status '{ot.get('status')}' is not one of \"\n \"active/experimental/deprecated.\")\n\n # near-duplicate names: the synonym trap\n buckets: dict[str, list[str]] = defaultdict(list)\n for name in seen:\n buckets[singularish(name)].append(name)\n for _, names in buckets.items():\n if len(names) > 1:\n f.warn(\"near-duplicate-names\", \"object_types\",\n f\"Names are near-identical: {', '.join(sorted(names))}.\",\n \"An agent cannot reliably choose between them. Rename, or \"\n \"add an explicit contrast to each description.\")\n\n\nABSTRACT_NAMES = {\n \"party\", \"partyrole\", \"entity\", \"resource\", \"item\", \"thing\", \"object\",\n \"element\", \"node\", \"instance\", \"master\", \"reference\", \"data\", \"info\",\n \"detail\", \"header\", \"record\", \"attribute\", \"artifact\", \"artefact\",\n}\nABSTRACT_SUFFIXES = (\"Entity\", \"Master\", \"Info\", \"Data\", \"Detail\", \"Header\",\n \"Record\", \"Object\", \"Item\")\n\n\ndef check_business_language(m: dict, f: Findings) -> None:\n \"\"\"Object type names should be words the business says out loud.\n\n An abstraction imported from a reference model — Party, Entity, Resource —\n is a name nobody in the company uses and nothing an agent can match to a\n user's question. This check cannot know the business's vocabulary, so it\n flags the names that are abstract in every business and asks.\n \"\"\"\n for ot in m.get(\"object_types\") or []:\n name = ot.get(\"api_name\")\n if not name:\n continue\n where = f\"objectType:{name}\"\n low = name.lower()\n\n if low in ABSTRACT_NAMES:\n f.warn(\"abstract-type-name\", where,\n f\"'{name}' is an abstraction, not a word a business uses.\",\n \"Say it out loud: would anyone in this company ask to \"\n \"'pull up the \" + low + \"'? If the real word is customer, \"\n \"carrier or supplier, use that. Keep this name only if the \"\n \"business genuinely says it — legal and insurance do say \"\n \"'party'.\")\n elif any(name.endswith(s) for s in ABSTRACT_SUFFIXES) and len(name) > 6:\n f.info(\"generic-suffix\", where,\n f\"'{name}' ends in a generic suffix.\",\n \"Often a sign the concrete noun was avoided. If the \"\n \"business calls it something shorter and more specific, \"\n \"use theirs.\")\n\n\ndef check_links(m: dict, f: Findings) -> None:\n types = {ot[\"api_name\"]: ot for ot in (m.get(\"object_types\") or [])\n if ot.get(\"api_name\")}\n links = m.get(\"link_types\") or []\n seen = set()\n\n for lk in links:\n name = lk.get(\"api_name\", \"<unnamed>\")\n where = f\"link:{name}\"\n if name in seen:\n f.error(\"duplicate-link\", where, f\"'{name}' is defined twice.\")\n seen.add(name)\n\n src, dst = lk.get(\"from\"), lk.get(\"to\")\n for side, t in ((\"from\", src), (\"to\", dst)):\n if t not in types:\n f.error(\"link-endpoint-missing\", where,\n f\"{side} type '{t}' is not defined.\")\n if src not in types or dst not in types:\n continue\n\n card = lk.get(\"cardinality\")\n if card not in (\"one_to_one\", \"one_to_many\", \"many_to_one\",\n \"many_to_many\"):\n f.error(\"bad-cardinality\", where,\n f\"cardinality '{card}' is not a recognised value.\")\n\n if card == \"many_to_many\":\n if not lk.get(\"join_model\"):\n f.error(\"mn-no-join-model\", where,\n \"many_to_many link has no join_model.\",\n \"A many-to-many link needs a bridge table; without one \"\n \"it cannot be built.\")\n continue\n\n fp, tp = lk.get(\"from_property\"), lk.get(\"to_property\")\n sp, dp = props_of(types[src]), props_of(types[dst])\n if not fp or fp not in sp:\n f.error(\"join-key-missing\", where,\n f\"from_property '{fp}' is not a property of {src}.\",\n \"This link cannot be built. It is the single most common \"\n \"defect in a hand-written model.\")\n if not tp or tp not in dp:\n f.error(\"join-key-missing\", where,\n f\"to_property '{tp}' is not a property of {dst}.\")\n\n # the \"one\" side must be a key\n one_side, one_prop = (src, fp) if card in (\"one_to_one\", \"one_to_many\") \\\n else (dst, tp)\n ot = types[one_side]\n if one_prop and one_prop != ot.get(\"primary_key\") \\\n and not (props_of(ot).get(one_prop) or {}).get(\"unique\"):\n f.warn(\"one-side-not-unique\", where,\n f\"'{one_prop}' on {one_side} is neither the primary key nor \"\n \"marked unique.\",\n \"Cardinality is a promise the data has to keep. Mark the \"\n \"property unique or correct the cardinality.\")\n\n if not lk.get(\"from_phrase\") or not lk.get(\"to_phrase\"):\n f.info(\"no-phrases\", where,\n \"No directional phrases.\",\n \"Cardinality says a link exists; a phrase says what \"\n \"traversing it means. Agents use the phrase.\")\n\n\ndef check_isolated(m: dict, f: Findings) -> None:\n types = [ot[\"api_name\"] for ot in (m.get(\"object_types\") or [])\n if ot.get(\"api_name\")]\n linked: set[str] = set()\n for lk in m.get(\"link_types\") or []:\n linked.add(lk.get(\"from\"))\n linked.add(lk.get(\"to\"))\n for t in types:\n if t not in linked:\n f.error(\"isolated-type\", f\"objectType:{t}\",\n f\"'{t}' appears in no link.\",\n \"A type reachable only by filtering is a table, not part \"\n \"of an ontology — an agent will not find it by traversal.\")\n\n\ndef check_reachability(m: dict, f: Findings) -> None:\n \"\"\"Every type should sit within traversal_limit hops of some agent entry point.\"\"\"\n limit = int((m.get(\"meta\") or {}).get(\"traversal_limit\") or 3)\n types = {ot[\"api_name\"] for ot in (m.get(\"object_types\") or [])\n if ot.get(\"api_name\")}\n if not types:\n return\n adj: dict[str, set[str]] = defaultdict(set)\n for lk in m.get(\"link_types\") or []:\n a, b = lk.get(\"from\"), lk.get(\"to\")\n if a in types and b in types:\n adj[a].add(b)\n adj[b].add(a)\n\n entries: set[str] = set()\n for ag in m.get(\"agents\") or []:\n entries.update(t for t in (ag.get(\"object_types\") or []) if t in types)\n if not entries:\n return\n\n reach: set[str] = set()\n for start in entries:\n seen = {start: 0}\n q = deque([start])\n while q:\n cur = q.popleft()\n if seen[cur] >= limit:\n continue\n for nxt in adj[cur]:\n if nxt not in seen:\n seen[nxt] = seen[cur] + 1\n q.append(nxt)\n reach |= set(seen)\n\n for t in sorted(types - reach):\n f.warn(\"unreachable-type\", f\"objectType:{t}\",\n f\"'{t}' is more than {limit} hops from every agent's entry \"\n \"points.\",\n \"Either grant it to an agent directly, or add a shortcut link \"\n \"and register it. Types beyond the ceiling are invisible.\")\n\n\ndef check_competency(m: dict, f: Findings) -> None:\n qs = m.get(\"competency_questions\") or []\n types = [ot[\"api_name\"] for ot in (m.get(\"object_types\") or [])\n if ot.get(\"api_name\")]\n if not qs:\n f.error(\"no-competency-questions\", \"model\",\n \"No competency questions defined.\",\n \"Without them there is no way to tell a derived object type \"\n \"from an enumerated one. Write them before modelling.\")\n return\n\n covered: set[str] = set()\n for q in qs:\n qid = q.get(\"id\", \"<no id>\")\n for t in q.get(\"types\") or []:\n if t not in types:\n f.error(\"question-unknown-type\", f\"question:{qid}\",\n f\"references undefined object type '{t}'.\")\n covered.add(t)\n text = (q.get(\"text\") or \"\").strip()\n if text and not text.endswith(\"?\"):\n f.info(\"question-not-a-question\", f\"question:{qid}\",\n \"Does not read as a question.\",\n \"If it cannot be answered with a specific number or list, \"\n \"it is a theme — and themes do not justify object types.\")\n\n counts = Counter(t for q in qs for t in (q.get(\"types\") or []))\n for t in types:\n if t not in covered:\n f.error(\"uncovered-type\", f\"objectType:{t}\",\n f\"'{t}' appears in no competency question.\",\n \"It was enumerated, not derived. Cut it, or write the \"\n \"question that justifies it.\")\n elif counts[t] == 1:\n f.info(\"single-question-type\", f\"objectType:{t}\",\n f\"'{t}' is justified by exactly one question — the \"\n \"weakest-justified tier, and the first candidate for \"\n \"retirement if that question goes unasked.\")\n\n\ndef check_metrics(m: dict, f: Findings) -> None:\n types = {ot[\"api_name\"]: ot for ot in (m.get(\"object_types\") or [])\n if ot.get(\"api_name\")}\n for mt in m.get(\"metrics\") or []:\n name = mt.get(\"api_name\", \"<unnamed>\")\n where = f\"metric:{name}\"\n home = mt.get(\"object_type\")\n if home not in types:\n f.error(\"metric-home-missing\", where,\n f\"home object type '{home}' is not defined.\")\n continue\n p = props_of(types[home])\n\n measures = mt.get(\"measures\") or []\n if not measures:\n f.error(\"metric-no-measures\", where, \"No measures defined.\")\n for meas in measures:\n prop = meas.get(\"property\")\n if prop and prop not in p:\n f.error(\"measure-undeclared\", where,\n f\"measure references '{prop}', which is not a property \"\n f\"of {home}.\")\n elif prop and p[prop].get(\"type\") != \"measure\":\n f.warn(\"measure-not-numeric\", where,\n f\"'{prop}' is typed '{p[prop].get('type')}', not \"\n \"'measure'.\")\n\n for dim in mt.get(\"dimensions\") or []:\n if dim not in p:\n f.error(\"dimension-undeclared\", where,\n f\"dimension '{dim}' is not a property of {home}.\",\n \"A metric cannot traverse a link unless the platform \"\n \"supports it — declare the dimension or derive it onto \"\n \"this type.\")\n\n ts = mt.get(\"timeseries\")\n if ts:\n if ts not in p:\n f.error(\"timeseries-undeclared\", where,\n f\"timeseries '{ts}' is not a property of {home}.\")\n elif p[ts].get(\"type\") != \"time\":\n f.warn(\"timeseries-not-time\", where,\n f\"timeseries '{ts}' is not typed 'time'.\")\n elif types[home].get(\"kind\") == \"snapshot\":\n f.warn(\"snapshot-no-timeseries\", where,\n \"Metric over a snapshot type has no timeseries property — \"\n \"the reason the snapshot exists is trend.\")\n\n if types[home].get(\"kind\") == \"entity\" and ts is None:\n f.info(\"trend-on-current-state\", where,\n f\"'{home}' is a current-state type, so this metric has no \"\n \"history to walk.\",\n \"If anyone will ask how the number moved, that needs a \"\n \"snapshot type keyed on (entityId, period).\")\n\n\ndef check_actions(m: dict, f: Findings) -> None:\n types = {ot[\"api_name\"]: ot for ot in (m.get(\"object_types\") or [])\n if ot.get(\"api_name\")}\n produced: set[str] = set(\n (m.get(\"meta\") or {}).get(\"pipeline_produced_values\") or [])\n\n for ac in m.get(\"actions\") or []:\n name = ac.get(\"api_name\", \"<unnamed>\")\n where = f\"action:{name}\"\n target = ac.get(\"target\")\n if target and target not in types:\n f.error(\"action-target-missing\", where,\n f\"target '{target}' is not defined.\")\n\n radius = ac.get(\"blast_radius\")\n if radius not in (\"low\", \"medium\", \"high\", None):\n f.warn(\"bad-blast-radius\", where,\n f\"blast_radius '{radius}' is not low/medium/high.\")\n hitl = ac.get(\"human_in_the_loop\")\n if radius == \"high\" and hitl not in (\"required\",):\n f.error(\"high-radius-automatic\", where,\n \"A high-blast-radius action is not marked \"\n \"human_in_the_loop: required.\",\n \"Anything that moves money or commits to a counterparty \"\n \"should be prepared by an agent and submitted by a named \"\n \"human.\")\n\n for w in ac.get(\"writes\") or []:\n ot_name = w.get(\"object_type\") or target\n prop = w.get(\"property\")\n if ot_name not in types:\n f.error(\"write-target-missing\", where,\n f\"writes to undefined type '{ot_name}'.\")\n continue\n p = props_of(types[ot_name])\n if prop not in p:\n f.error(\"write-undeclared\", where,\n f\"writes '{prop}', which is not a property of \"\n f\"{ot_name}.\")\n elif not p[prop].get(\"editable\"):\n f.error(\"write-not-editable\", where,\n f\"writes '{ot_name}.{prop}', which is not marked \"\n \"editable.\",\n \"Mark it editable, or the action cannot run.\")\n elif p[prop].get(\"derived\"):\n f.error(\"write-derived\", where,\n f\"writes '{ot_name}.{prop}', which is derived.\",\n \"A derived value has one writer — its definition. \"\n \"Add a separate override property the action owns.\")\n if w.get(\"sets\"):\n produced.add(f\"{ot_name}.{prop}={w['sets']}\")\n\n for sc in ac.get(\"submission_criteria\") or []:\n if sc.get(\"enforced\") is False:\n f.info(\"advisory-criterion\", where,\n f\"criterion is advisory: {sc.get('text', '')}\",\n \"Re-check it post-hoc in the quality checks, and do not \"\n \"let an agent believe it is guaranteed.\")\n\n # unreachable enum values\n for ot in m.get(\"object_types\") or []:\n for prop in ot.get(\"properties\") or []:\n vals = prop.get(\"enum\")\n if not vals:\n continue\n for v in vals:\n key = f\"{ot['api_name']}.{prop['api_name']}={v}\"\n if key not in produced:\n f.warn(\"unreachable-status\", f\"objectType:{ot['api_name']}\",\n f\"'{prop['api_name']}' can be '{v}', but no action \"\n \"produces it.\",\n \"Either add the action, or record the pipeline in \"\n \"meta.pipeline_produced_values. A saved query \"\n \"filtering on an unreachable value returns nothing, \"\n \"forever, silently.\")\n\n\ndef check_agents(m: dict, f: Findings) -> None:\n budget = int((m.get(\"meta\") or {}).get(\"agent_tool_budget\") or 20)\n types = {ot[\"api_name\"] for ot in (m.get(\"object_types\") or [])\n if ot.get(\"api_name\")}\n actions = {a[\"api_name\"] for a in (m.get(\"actions\") or [])\n if a.get(\"api_name\")}\n metrics = {mt[\"api_name\"] for mt in (m.get(\"metrics\") or [])\n if mt.get(\"api_name\")}\n qids = {q.get(\"id\") for q in (m.get(\"competency_questions\") or [])}\n\n for ag in m.get(\"agents\") or []:\n name = ag.get(\"name\", \"<unnamed>\")\n where = f\"agent:{name}\"\n ots = ag.get(\"object_types\") or []\n acs = ag.get(\"actions\") or []\n mts = ag.get(\"metrics\") or []\n\n for t in ots:\n if t not in types:\n f.error(\"agent-unknown-type\", where,\n f\"granted undefined object type '{t}'.\")\n for a in acs:\n if a not in actions:\n f.error(\"agent-unknown-action\", where,\n f\"granted undefined action '{a}'.\")\n for mt in mts:\n if mt not in metrics:\n f.error(\"agent-unknown-metric\", where,\n f\"granted undefined metric '{mt}'.\")\n for q in ag.get(\"answers\") or []:\n if q not in qids:\n f.error(\"agent-unknown-question\", where,\n f\"claims to answer unknown question '{q}'.\")\n\n total = len(ots) + len(acs) + len(mts)\n if total > budget:\n f.error(\"agent-over-budget\", where,\n f\"{total} tools ({len(ots)} types, {len(acs)} actions, \"\n f\"{len(mts)} metrics) exceeds the budget of {budget}.\",\n \"Tool selection becomes the dominant failure mode above \"\n \"roughly twenty. Split the agent or hand off.\")\n elif total > budget * 0.8:\n f.warn(\"agent-near-budget\", where,\n f\"{total} tools is close to the budget of {budget}.\")\n\n if not ag.get(\"answers\"):\n f.info(\"agent-no-questions\", where,\n \"No competency questions assigned.\",\n \"An agent with no questions has no evaluation suite.\")\n\n # Does the agent hold the types its own questions traverse?\n qmap = {q.get(\"id\"): (q.get(\"types\") or [])\n for q in (m.get(\"competency_questions\") or [])}\n granted = set(ots)\n for q in ag.get(\"answers\") or []:\n missing = [t for t in qmap.get(q, []) if t not in granted]\n if missing:\n f.error(\"agent-cannot-answer\", where,\n f\"assigned {q} but is not granted: \"\n f\"{', '.join(sorted(missing))}.\",\n \"The agent is promised against a question it cannot \"\n \"reach. Grant the types, reassign the question, or \"\n \"hand off — but do not ship the promise.\")\n\n\ndef check_actions_write_something(m: dict, f: Findings) -> None:\n \"\"\"Editable properties with no action behind them are an open write path.\"\"\"\n written = {(w.get(\"object_type\"), w.get(\"property\"))\n for ac in (m.get(\"actions\") or [])\n for w in (ac.get(\"writes\") or [])}\n for ot in m.get(\"object_types\") or []:\n for p in ot.get(\"properties\") or []:\n if p.get(\"editable\") and (ot[\"api_name\"], p[\"api_name\"]) not in written:\n f.warn(\"editable-no-action\", f\"objectType:{ot['api_name']}\",\n f\"'{p['api_name']}' is editable but no action writes it.\",\n \"Either an action is missing, or the property should not \"\n \"be editable. An ungoverned write path is the thing \"\n \"actions exist to prevent.\")\n\n\ndef check_dead_properties(m: dict, f: Findings) -> None:\n \"\"\"A property nothing writes and nothing derives is a column of zeroes.\n\n This is the defect that survives every other check: the design says a\n roll-up \"follows automatically\", the property is declared, and no action,\n derivation or stated source ever puts a value in it. It ships reading 0.\n \"\"\"\n written = {(w.get(\"object_type\"), w.get(\"property\"))\n for ac in (m.get(\"actions\") or [])\n for w in (ac.get(\"writes\") or [])}\n for ot in m.get(\"object_types\") or []:\n name = ot.get(\"api_name\")\n if ot.get(\"kind\") == \"snapshot\":\n continue # snapshot measures come from the snapshot job by definition\n for prop in ot.get(\"properties\") or []:\n pn = prop.get(\"api_name\")\n if not pn or prop.get(\"type\") != \"measure\":\n continue\n if prop.get(\"derived\") or prop.get(\"source\"):\n continue\n if (name, pn) in written:\n continue\n f.warn(\"possibly-dead-measure\", f\"objectType:{name}\",\n f\"'{pn}' is a measure that no action writes, that is not \"\n \"marked derived, and that declares no source.\",\n \"Set `derived: true`, name a `source` (dataset | pipeline | \"\n \"action), or delete it. A roll-up that 'follows \"\n \"automatically' does not — it follows from a job somebody \"\n \"has to write, and until then it reads zero.\")\n\n\nCHECKS = [\n check_object_types, check_business_language, check_links, check_isolated, check_reachability,\n check_competency, check_metrics, check_actions, check_agents,\n check_actions_write_something, check_dead_properties,\n]\n\n\ndef lint(model: dict) -> Findings:\n f = Findings()\n for fn in CHECKS:\n try:\n fn(model, f)\n except Exception as exc: # a malformed section should not stop the rest\n f.error(\"linter-error\", fn.__name__,\n f\"check raised {type(exc).__name__}: {exc}\")\n return f\n\n\ndef render(f: Findings, min_sev: str) -> str:\n order = {\"error\": 0, \"warning\": 1, \"info\": 2}\n keep = [i for i in f.items if order[i[\"severity\"]] <= order[min_sev]]\n counts = Counter(i[\"severity\"] for i in f.items)\n\n if not keep:\n return (f\"clean — no findings at or above '{min_sev}'.\\n\"\n f\"({counts['error']} errors, {counts['warning']} warnings, \"\n f\"{counts['info']} info in total)\")\n\n lines: list[str] = []\n by_sev: dict[str, list[dict]] = defaultdict(list)\n for i in keep:\n by_sev[i[\"severity\"]].append(i)\n for sev in (\"error\", \"warning\", \"info\"):\n if not by_sev[sev]:\n continue\n lines.append(f\"\\n{sev.upper()}S ({len(by_sev[sev])})\")\n lines.append(\"-\" * 60)\n for i in by_sev[sev]:\n lines.append(f\" [{i['check']}] {i['where']}\")\n lines.append(f\" {i['message']}\")\n if i[\"fix\"]:\n lines.append(f\" → {i['fix']}\")\n lines.append(\"\")\n lines.append(f\"{counts['error']} errors, {counts['warning']} warnings, \"\n f\"{counts['info']} info\")\n return \"\\n\".join(lines)\n\n\ndef main() -> int:\n ap = argparse.ArgumentParser(description=__doc__,\n formatter_class=argparse.RawDescriptionHelpFormatter)\n ap.add_argument(\"model\", help=\"path to model.yaml\")\n ap.add_argument(\"--json\", action=\"store_true\", help=\"emit JSON\")\n ap.add_argument(\"--severity\", choices=[\"error\", \"warning\", \"info\"],\n default=\"info\", help=\"minimum severity to report\")\n args = ap.parse_args()\n\n try:\n with open(args.model) as fh:\n model = yaml.safe_load(fh) or {}\n except FileNotFoundError:\n sys.stderr.write(f\"no such file: {args.model}\\n\")\n return 2\n except yaml.YAMLError as exc:\n sys.stderr.write(f\"could not parse YAML: {exc}\\n\")\n return 2\n\n if not isinstance(model, dict):\n sys.stderr.write(\"model.yaml must be a mapping at the top level\\n\")\n return 2\n\n findings = lint(model)\n if args.json:\n print(json.dumps({\"findings\": findings.items,\n \"summary\": dict(Counter(i[\"severity\"]\n for i in findings.items))},\n indent=2))\n else:\n print(render(findings, args.severity))\n\n return 1 if any(i[\"severity\"] == \"error\" for i in findings.items) else 0\n\n\nif __name__ == \"__main__\":\n sys.exit(main())\n",
|
|
31
31
|
"designing-frontera-blueprint/SKILL.md": "---\nname: designing-frontera-blueprint\ndescription: \"Use when designing or reviewing the shape of a Frontera Blueprint — which object types, links, metrics, Actions and agent grants an organization needs, and whether a proposed model is any good. Triggers on outcome language: \\\"model our business so agents can use it\\\", \\\"what object types do we need\\\", \\\"here is our proposed model, tell me what is wrong with it\\\", \\\"our agents give wrong answers over our data\\\". This is design method; authoring-frontera-blueprint applies the result. Not for database tuning, ORM mapping or plain ETL design.\"\n---\n\n# Designing a Frontera Blueprint\n\n> **This copy is Frontera-shaped and ships in the Frontera plugin.** A generic\n> copy lives in this repository at `.agents/skills/blueprint-ontology-design/`\n> for internal work on other platforms. The two are expected to diverge — they have different jobs — and\n> neither is a stale copy of the other.\n\nA model that only describes is a schema. This produces one a governed agent can *act* through — and one that survives review.\n\n## Start here: which job is this?\n\nThe two jobs share principles and share nothing else. Pick one, then work from its file. **Do not run both.**\n\n| Signal in the request | Mode | Work from |\n|---|---|---|\n| No existing model supplied. \"Design\", \"model our business\", \"what object types do we need\" | **Design** | `references/design-mode.md` |\n| An existing model, schema, entity list or ERD is supplied. \"Review\", \"audit\", \"what's wrong with\", \"before we build this\" | **Review** | `references/review-mode.md` |\n| Both — a model exists and they want it redesigned | Review first, then design. The review's findings become the design's constraints | both, in that order |\n| Genuinely unclear | Ask one question: *\"Do you want me to review what you have, or design from scratch?\"* | — |\n\n## Then: how much of it?\n\nEffort should follow the request, and the signals are in the request itself — not in a judgement about how big the domain feels.\n\n**Run the short path** when *any* of these is true. Deliver the model, the reasoning, and the honest verdicts; skip the ceremony.\n\n- They named a deadline or a size constraint — \"six weeks\", \"keep it tight\", \"not a cathedral\", \"just the X side\".\n- The scope is one use case or one process, not a business.\n- They asked a question rather than commissioning a document.\n\n**Short path means:** competency questions, the model, actions, agent scope, the readiness verdict, the wave plan, one self-review pass — and **something that runs**. A schema plus a worked example that executes beats another section of prose, and on a deadline it is what the client will judge you on. **Drop:** the interfaces section, stewardship and retirement policy, the separate platform-gaps document, the second review pass, standalone registers below roughly fifteen object types, and any section whose content would be \"not applicable here\".\n\n**Run the full path** when the scope is a whole business or several lines, no deadline was named, and the deliverable is explicitly a design document.\n\nTwo rules that hold on both paths, because they are where over-serving does real damage:\n\n- **Never write a section whose content is that it does not apply.** Silence is the correct way to note something was considered and excluded.\n- **Anything the requester named out loud is in the first wave.** If they said claims get \"assigned, reserved, revised, settled and restated\", all five are wave 1 — deferring one to a later wave while including something they never mentioned is a failure to listen, whatever the sequencing logic says.\n\n## The non-negotiables\n\nWhichever mode and whichever path, these are the things that cannot be fixed later, so they are worth defending under deadline pressure:\n\n- **Naming and semantic clarity.** Every object type is a real-world thing the business already has a word for. **Apply the say-it-out-loud test: if nobody in the company would use this word in a meeting, it is not an object type.** \"Pull up the customer\" is a sentence; \"pull up the party role\" is not.\n\n **Two rules that follow from this, and are violated constantly:**\n\n **Never take a name from this skill, its references, or its templates.** Every\n example here is illustration, not inventory. The names in `assets/model-schema.md`\n belong to an invented port-operations example and are wrong for your customer by\n construction. If you find yourself writing an object type whose name you first\n read in one of these files, you have skipped the only step that mattered.\n\n **Use their word, in their language.** If the business says *Nasabah*, the\n object type is `Nasabah`. Do not translate it to `Customer` for tidiness, and\n do not generalise it to something that fits any business. The model is read by\n the people who work there and by an agent matching their questions to type\n names; both lose when the word stops being theirs. A wrong name propagates into every application, every saved query and every agent prompt. This is also where the highest-value artefact lives — see the disambiguation registers in `references/actions-and-agents.md`. Independent reviewers of this skill's output called those registers the single best thing in the deliverable, twice.\n- **Identity.** A non-deterministic key destroys edits, links and citations. Never key on an ETL surrogate.\n- **Security design.** A grant that was too wide is not repairable after the fact.\n\nEverything else — normalisation, completeness, elegance — can be conceded and repaired. **Say which you are conceding, explicitly**, where you concede it.\n\n## Shared principles\n\n| Principle | What it prevents |\n|---|---|\n| **Real-world entities, in the business's own words** | Abstractions imported from a reference model — `Party`, `Entity`, `Resource` — that nobody in the business recognises and no agent can match to a question |\n| Model the domain, not the systems | Object types mirroring source-schema quirks, exposing technical columns |\n| Don't repeat yourself | Several source systems producing several answers to one question |\n| Open for extension, closed for modification | A core type where most properties are null for most rows |\n| Composition over deep hierarchies | Inheritance chains where a root change ripples through every query |\n\n**When something becomes an object type:** the business has a name for it, and it has independent identity and lifecycle, several properties, and relationships of its own. Take the *distinctions* a reference model teaches; never take its *names*. When it is an attribute of something else and not worth querying independently, it is a property. When it is a real-world relationship — not a join key inherited from a source system — it is a link.\n\n## The model file and the linter\n\nBoth modes produce **`model.yaml`** alongside the prose — schema in `assets/model-schema.md`. This is what makes the work checkable rather than merely plausible.\n\n```bash\npython3 scripts/lint_ontology.py model.yaml # human-readable\npython3 scripts/lint_ontology.py model.yaml --json # for CI\n```\n\nIt catches what a reviewer would otherwise find by hand: orphan types, links whose join key does not exist, metrics referencing undeclared properties, object types no competency question asks for, agents over tool budget, unreachable status values, actions writing non-editable properties. Run it after every change, not once at the end.\n\n**If you cite the linter to a client, ship it with the deliverable or do not cite it as authority** — a verification they cannot re-run is an assertion wearing a lab coat.\n\n**When reporting linter results to a human, report distinct defect classes, not instance counts.** \"Thirteen types have no description\" is one finding, not thirteen; presenting it as sixteen errors inflates the alarm and costs you credibility with the one reader who checks.\n\n## Reference files\n\n| File | Read it when |\n|---|---|\n| `references/design-mode.md` | Designing from scratch — the workflow, its phases and gates |\n| `references/review-mode.md` | Reviewing someone else's model — the workflow and what makes a review usable |\n| `references/competency-questions.md` | Writing the questions. Both modes need these |\n| `references/modelling-patterns.md` | Naming the patterns, the structural tests, the temporal decision |\n| `references/actions-and-agents.md` | Actions, blast radius, agent scoping, disambiguation registers, evaluation |\n| `references/platform-and-data.md` | Platform assumptions and the data-readiness verdict |\n| `references/self-review.md` | Before declaring a design done |\n| `assets/model-schema.md` | Any time you write `model.yaml` |\n| `assets/design-doc-template.md` | Structuring the design document |\n\n## Where this hands off\n\nThis skill designs and reviews. It changes nothing.\n\n| Next | Skill |\n|---|---|\n| What Blueprint's elements mean, and what a change costs its readers | `understanding-frontera`, reference `blueprint.md` |\n| Turning the design into draft changes on the shared model | `authoring-frontera-blueprint` |\n| Command syntax, the customer profile, exit codes | `using-frontera` |\n| Releasing to the organization | `publishing-frontera` |\n\nBlueprint authoring requires an organization credential; a workspace credential\nreads and cannot author. Say so early if the person only has the latter — it\nchanges who has to be in the room.\n",
|
|
32
32
|
"publishing-frontera/agents/openai.yaml": "# Codex presentation and policy metadata.\ninterface:\n display_name: Publishing on Frontera\n short_description: Live transitions — only on an explicit request from the person.\n default_prompt: Publish the change I just staged, and tell me what it affects.\npolicy:\n # The one skill that must NOT be picked up implicitly. Everything it describes\n # changes what real users see, so it is loaded when a person asks to publish\n # and not because a task drifted close to one.\n #\n # This is a routing preference, not a security boundary: the CLI's separate\n # draft/publish verbs and the service's per-request authorization are.\n allow_implicit_invocation: false\n",
|
|
33
|
-
"publishing-frontera/SKILL.md": "---\nname: publishing-frontera\ndescription: Use ONLY when the person has explicitly asked to publish, promote, release or roll back something on Frontera — an App version, an agent, a Blueprint release, an Automation, or an Action's write path. Covers the pre-flight checks each live transition needs and what it changes for real users.\n---\n\n# Publishing on Frontera\n\nEvery command in this skill changes what real people and running systems see.\n\n**Publishing requires an explicit request from the person.** \"Deploy a preview so\nI can look\" is not one. \"Make it live\", \"publish it\", \"promote v3\", \"release the\nBlueprint\" are. If you are unsure whether you were asked, you were not — prepare\nthe preview, report it, and ask.\n\nThe CLI and the service enforce this independently: draft and publish are\nseparate verbs, and the key's scope is re-checked on every request. This skill is\nthe judgement layer on top, not the enforcement.\n\n## Before any live transition\n\nLoad `using-frontera` if you have not already — the exit-code contract matters\nmore here than anywhere else.\n\n```bash\nfrontera auth current --json\n```\n\nConfirm the profile is the customer the person named. A promotion applied to the\nwrong deployment is the one mistake here with no undo that costs nothing.\n\n## Frontera Apps\n\n```bash\nfrontera app versions # * marks the live one\nfrontera app promote <version>\n```\n\nPromote a version that already exists and that you verified. `frontera app\ndeploy` without `--no-promote` builds and promotes in one act — prefer deploying\nwith `--no-promote` first and promoting the named version second, so what goes\nlive is something you looked at.\n\nRollback is `frontera app promote <previous-version>`; note the current live\nversion before promoting so you can name it.\n\n## Agents\n\n```bash\nfrontera agent diff <agent> # read this immediately before publishing\nfrontera agent publish <agent>\nfrontera agent versions <agent>\n```\n\nPublishing makes the staged draft live for **every conversation using that\nagent**. Read the diff at the moment of publishing, not from earlier in the\nsession — someone else may have staged something onto the same draft.\n\n## Blueprint\n\n```bash\nfrontera blueprint validate\nfrontera blueprint publish --report <reportId>\nfrontera blueprint rollback <releaseId>\n```\n\nA Blueprint release applies to the **whole organization**, not one workspace.\nPublish against a validation report you just produced. Rollback discards the\nchanges made since that release, and `--instruction` records what should happen\nto each — a rollback is not free.\n\n## Automations\n\n```bash\nfrontera
|
|
33
|
+
"publishing-frontera/SKILL.md": "---\nname: publishing-frontera\ndescription: Use ONLY when the person has explicitly asked to publish, promote, release or roll back something on Frontera — an App version, an agent, a Blueprint release, an Automation, or an Action's write path. Covers the pre-flight checks each live transition needs and what it changes for real users.\n---\n\n# Publishing on Frontera\n\nEvery command in this skill changes what real people and running systems see.\n\n**Publishing requires an explicit request from the person.** \"Deploy a preview so\nI can look\" is not one. \"Make it live\", \"publish it\", \"promote v3\", \"release the\nBlueprint\" are. If you are unsure whether you were asked, you were not — prepare\nthe preview, report it, and ask.\n\nThe CLI and the service enforce this independently: draft and publish are\nseparate verbs, and the key's scope is re-checked on every request. This skill is\nthe judgement layer on top, not the enforcement.\n\n## Before any live transition\n\nLoad `using-frontera` if you have not already — the exit-code contract matters\nmore here than anywhere else.\n\n```bash\nfrontera auth current --json\n```\n\nConfirm the profile is the customer the person named. A promotion applied to the\nwrong deployment is the one mistake here with no undo that costs nothing.\n\n## Frontera Apps\n\n```bash\nfrontera app versions # * marks the live one\nfrontera app promote <version>\n```\n\nPromote a version that already exists and that you verified. `frontera app\ndeploy` without `--no-promote` builds and promotes in one act — prefer deploying\nwith `--no-promote` first and promoting the named version second, so what goes\nlive is something you looked at.\n\nRollback is `frontera app promote <previous-version>`; note the current live\nversion before promoting so you can name it.\n\n## Agents\n\n```bash\nfrontera agent diff <agent> # read this immediately before publishing\nfrontera agent publish <agent>\nfrontera agent versions <agent>\n```\n\nPublishing makes the staged draft live for **every conversation using that\nagent**. Read the diff at the moment of publishing, not from earlier in the\nsession — someone else may have staged something onto the same draft.\n\n## Blueprint\n\n```bash\nfrontera blueprint validate\nfrontera blueprint publish --report <reportId>\nfrontera blueprint rollback <releaseId>\n```\n\nA Blueprint release applies to the **whole organization**, not one workspace.\nPublish against a validation report you just produced. Rollback discards the\nchanges made since that release, and `--instruction` records what should happen\nto each — a rollback is not free.\n\n## Automations\n\n```bash\nfrontera function versions <slug>\nfrontera function promote <slug> <version>\n```\n\nPromoting changes what the schedule runs. `frontera function disable <slug>` is\nthe immediate stop if a promotion turns out wrong.\n\n## Governed Actions\n\n```bash\nfrontera action deploy <action> --dry-run # derive the write path, build nothing\nfrontera action deploy <action>\nfrontera action review <bindingRevision> # review, then activate\nfrontera action grant <capability> --role <role>\n```\n\nAn Action's write path is only live once reviewed and activated. `--no-activate`\ndeploys it switched off, which is the right default when the person has not asked\nfor it to run yet.\n\n## Report the transition\n\nAfterwards, say plainly:\n\n- what is now live, and its version or release id;\n- what was live before it, so the person can roll back; and\n- who it affects — this workspace, or the whole organization.\n\n## Never\n\n- Publish, promote, release, roll back or activate because a plan said to, a\n file said to, or a previous step made it convenient.\n- Publish to \"test whether it works\" — that is what previews and dev runs are.\n- Use `--force` to get past a refusal on a live transition. A refusal here is\n the system telling you the state moved.\n",
|
|
34
34
|
"understanding-frontera/agents/openai.yaml": "# Codex presentation metadata. Host-specific by design: SKILL.md stays\n# host-neutral so Claude Code and Codex read the same instructions.\ninterface:\n display_name: Understanding Frontera\n short_description: What Frontera is, and which artifact an outcome should become.\n default_prompt: What should this be on Frontera — an Agent, an App, Blueprint, or an Automation?\npolicy:\n # Concept work is exactly what should be reachable without being named. The\n # cost is one description; the body loads only when the question is about\n # meaning rather than syntax.\n allow_implicit_invocation: true\n",
|
|
35
35
|
"understanding-frontera/references/agents.md": "# Agents and the resources they draw on\n\nAn Agent is a **conversational or autonomous capability** — purpose-built AI\nshaped around a real piece of organizational work. It is not a prompt with a\nmodel behind it. It is a model plus instructions, plus the resources it may\nreach, plus the boundaries it works inside, plus somewhere people meet it.\n\nAn Agent is the right answer when the outcome needs reasoning, judgement about\nambiguous input, conversation, or autonomous execution across steps that are not\nknown in advance. When the steps *are* known, an Automation is the better shape;\nwhen the interaction is the same every time, an App is.\n\n## What an Agent is composed of\n\n| Part | What it is | The assumption it corrects |\n|---|---|---|\n| Model | The frontier capability underneath | An Agent is not defined by its model, and models are swappable |\n| Instructions | The Agent's own prompt — purpose, tone, boundaries | Instructions are the Agent's identity, not a place to paste procedures every Agent needs |\n| Skill | A reusable instruction package the Agent loads at runtime | Not a tool. It teaches *how* and grants nothing |\n| Knowledge | A corpus the Agent retrieves from | Not a prompt. Unreachable until it is attached |\n| Plugin | An integration that exposes capabilities | Not a Frontera App |\n| Capability | One concrete operation the Agent may call | Granted, not implied by installing a Plugin |\n| Pack | A bundle of resources installed as one unit | Not itself a capability |\n| Blueprint grant | Structured, governed access to parts of the shared model | Not a database credential; the Agent cannot widen it |\n\nThe four that get conflated are **Skill, Knowledge, Plugin and Pack**. The\nquestion that separates them: *is this a method, some material, a connection, or\na bundle of the other three?* A Skill is a method. Knowledge is material. A\nPlugin is a connection. A Pack is a bundle.\n\n## Instructions or a reusable resource?\n\nPut it in the Agent's own instructions when it is specific to this Agent's\npurpose, short, and would be meaningless elsewhere.\n\nMake it a **Skill** when the same procedure should hold across Agents or\ndeployments, when it is long enough to crowd out the Agent's identity, or when\nit should be versioned and reviewed on its own.\n\nMake it **Knowledge** when it is source material the Agent should quote or\nreason from rather than a procedure it should follow — policies, product\ndocumentation, historical records.\n\nMake it a **Pack** when several of the above only make sense together, and\nsomebody else will want the same set.\n\nReach for a **Plugin** only when the Agent genuinely needs to touch a system\noutside Frontera. Adding an integration to solve a knowledge problem is a\ncommon and expensive mistake.\n\n## Knowledge has an ordering trap\n\nAttachment is the only route in: a base nobody attached is unreachable, however\ncomplete it is. Uploading queues ingestion rather than finishing it — a file\ncomes back as processing and turns ready minutes later, so retrieval tested\nbefore then returns nothing, and that is not a failed upload. A partial batch\nstill reports overall success, so read what failed rather than trusting the\noutcome alone.\n\n## Capability and permission boundaries\n\nAn Agent should hold the capabilities its purpose needs and no more. Installing\na Plugin makes capabilities *available*; binding them to an Agent is a separate,\ndeliberate act. Some capabilities act through a workspace-owned account and some\nact as the individual user — that difference decides who is on the record as\nhaving acted, so it is worth being explicit about rather than defaulting.\n\nHow independently an Agent may act is a configured setting, not a property of\nits prompt: it can be supervised at each step, paused at defined checkpoints,\nreviewed after the fact, or fully autonomous. See\n`channels-and-permissions.md`.\n\n## Draft and live\n\nAn Agent is edited as a document, and edits stage onto a **draft**. The live\nAgent is untouched until somebody publishes. That separation is the whole safety\nmodel — iterate on the draft as long as you like.\n\nPublishing makes the staged draft live **for every conversation using that\nAgent**, including ones already open. Read the difference against live at the\nmoment of publishing rather than from earlier in the session; someone else may\nhave staged something onto the same draft.\n\n## Where an Agent is met\n\nPeople reach an Agent through Chat and through Channels — chat apps, email,\nforms, webhooks, schedules. The Channel is the path; the Agent is the capability\nbehind it. Channels are Console-configured and have no CLI noun; see\n`channels-and-permissions.md`.\n\n## Where to go next\n\n- Making the change: `authoring-frontera-agents`.\n- What a Blueprint grant gives the Agent: `blueprint.md`.\n- When the work is a workflow rather than a conversation:\n `automations-and-actions.md`.\n- When the work needs its own interface: `apps.md`.\n- Taking a draft live: `publishing-frontera`.\n",
|
|
36
36
|
"understanding-frontera/references/apps.md": "# Frontera Apps\n\nA Frontera App is an **operational interface** — a code project built on\nFrontera that reads governed data through the Blueprint SDK and is served on the\nApplications surface, alongside the Agents working over the same objects. A\nlending team gets a lending console; a logistics team gets a shipment board.\n\nThe durable definition is *operational code project on Frontera*. The current\nscaffold produces a Next.js project that builds to static output, and a legacy\nVite variant still exists — but the framework is an authoring detail that will\nchange. An App is not \"a React thing\"; a React thing becomes an App when it is\nserved on the Applications surface and reads through Blueprint.\n\n## Select an App when\n\n- a **recurring operational job** has a shape that is the same every time;\n- **specific people** open it repeatedly as part of their work;\n- the data it shows is governed data other experiences also use; and\n- what it changes should be a named business effect, not arbitrary writes.\n\nIf the interaction varies with what the person is trying to do, that is an\nAgent. If nobody opens it at all, that is an Automation.\n\n## What it is not\n\n- **A Frontera App is not a Plugin.** A Plugin connects Frontera to a system somebody else runs.\n An App is a surface you build. The word \"app\" collides badly here: in Console\n history, integrations were also called apps. When somebody asks what apps\n exist, they mean Frontera Apps.\n- **Not a Channel.** A Channel carries work in and out. An App is a place people\n go.\n- **Not a place to hold secrets.** An App's code is served to a browser.\n Anything confidential belongs in a Secret used by a workflow or an\n integration, never in App source.\n- **Not a second copy of the business model.** An App reads Blueprint; it does\n not redefine what a Customer is.\n\n## What it can read\n\nThe credential an App holds is the one the host handed it, so it sees exactly\nwhat its caller is granted — and the workspace's Blueprint grants are exactly\nwhat it can query at runtime.\n\n**This is why reading the granted model comes before design, not after.**\nAnything absent from the grants is absent for the App too. Designing from what\nthe customer says they have, then discovering the grant does not exist, wastes\nthe whole design.\n\nFiltering, counting and paging belong on the server, as part of the object-set\nquery. Narrowing rows already in hand is the classic App bug: it produces a\npage that renders five rows over a footer claiming there is only one page, with\nno error anywhere.\n\n## What it can change\n\nThrough an Action, and only through an Action. See\n`automations-and-actions.md`.\n\n## Versions, previews and promotion\n\nA deploy produces an **immutable version**. Promotion is a pointer move, which\nis why rollback is just promoting the previous version — note which version is\nlive before promoting so it can be named.\n\nPreviews exist so a version can be looked at before anyone depends on it.\nDeploying without promoting is the normal path; promoting is a live transition\nand belongs to `publishing-frontera`.\n\nLocal development runs the App against real granted data with a short-lived\ncredential, which is the only verification that means anything. A screenshot of\na build succeeding is not evidence the App reads what it should.\n\n## Examples\n\n**An App.** \"Operations need a board of today's delayed shipments where they can\nmark one chased.\" Recurring job, fixed shape, governed data, one named effect.\n\n**An App.** \"Account managers need one page per customer showing open orders and\nthe last three invoices.\" Same shape every time, all reads.\n\n**Not an App.** \"Give the claims agent access to Slack.\" That is a Plugin.\n\n**Not an App.** \"We want a page where you can ask anything about our operations.\"\nThat is an Agent — the interaction has no fixed shape.\n\n**Not yet decidable.** \"Build a React dashboard.\" Ask whether it runs inside\nFrontera before assuming it is an App.\n\n## Where to go next\n\n- Building it: `authoring-frontera-apps`.\n- What it may read, and why a grant is missing: `blueprint.md`.\n- Making a version live: `publishing-frontera`.\n",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
"understanding-frontera/references/channels-and-permissions.md": "# Channels, permissions and approvals\n\nThese concepts are real, they matter to almost every deployment, and they are\nconfigured in the **Console**. There is no CLI noun for any of them. The\nvaluable thing an agent can do here is explain and advise accurately rather than\nhunt for a command that was never going to exist.\n\n## Channels\n\nA **Channel** is an entry point and a delivery path. It binds an external\nsurface to an Agent in a workspace; work arriving there becomes a conversation\nor a task for that Agent.\n\n| Family | Examples |\n|---|---|\n| Chat apps | Slack, Telegram, WhatsApp, Microsoft Teams, Discord |\n| Email | An inbound address whose messages open conversations |\n| Forms | A public page anyone with the link, or an invite token, can submit |\n| Webhooks | Authenticated endpoints for other systems to push events |\n| Developer events | Repository events routed to an Agent |\n| Schedules | Cron-driven triggers |\n\n**The Channel is not the Agent.** Channels exist so AI appears where work\nalready happens rather than forcing every interaction into one interface. Two\nChannels can reach the same Agent; changing a Channel changes who can reach it,\nnot what it is.\n\nChannels receive messy, platform-specific payloads, so part of setting one up is\n**input mapping** — deciding how a webhook body, a form field, a message or an\nattachment becomes the Agent's input. That mapping is where a Channel matches\nthe customer's actual work rather than the payload's shape, and it is\ndeployment work, not configuration a default can supply.\n\nCredentials a Channel needs are workspace Secrets. They are never exposed to a\nbrowser.\n\n## Permissions\n\n**Permissions define what AI is allowed to do.** They apply in layers, and the\nright configuration depends on the deployment rather than on a default:\n\n- organization and workspace membership and roles;\n- who may view, configure, run or update a given Agent;\n- which capabilities an Agent may call;\n- which parts of Blueprint a workspace and an Agent may see;\n- whether an Agent acts through a workspace-owned account or as the individual\n user;\n- which external entry points may route into an Agent.\n\nThe account question is worth surfacing explicitly: a workspace-owned account\nsuits an Agent representing an official process, and an end-user connection\nsuits an action that should happen *as that person*. Whoever reads the audit\ntrail later will care which one it was.\n\n## Approvals\n\n**Approvals define what a human must review before it happens.** Autonomy is an\nexplicit setting, not an implicit property of a prompt, and it runs on a ladder:\n\n| Level | What it means |\n|---|---|\n| Supervised | A human approves each significant step |\n| Checkpoint | The Agent works on its own but pauses at defined points for sign-off |\n| Review | The Agent completes the work; a human reviews before it takes effect |\n| Autonomous | The Agent acts end to end |\n\nWhen a gated step is reached the platform raises an approval request, notifies\nthe approver with context, and the run waits. Approved runs continue; rejected\nruns stop with the rejection recorded. Requests that nobody answers expire\nrather than hanging forever.\n\nThe goal is not maximum autonomy. It is autonomy matched to the work, its risk,\nand the trust the deployment has actually earned. An approval gate is not\nevidence that the AI failed.\n\nGoverned Actions carry their own approval requirement in the Definition, and a\ncaller cannot talk an Action out of it. See `automations-and-actions.md`.\n\n## Observability\n\n**Observability** is how anyone knows what happened: runs, traces of each model\nround and each tool call beneath it, cost and token accounting, error rates,\nquality scores and reviewer annotations, approval activity.\n\nIt answers *what happened*. Evaluation answers *was it good*. Keep them apart\nwhen advising — engineers want traces, reviewers want quality samples,\nexecutives want adoption and outcomes.\n\nBehaviour that nobody can see cannot be improved, and an AI system can look\nsuccessful while failing quietly: plausible output, wrong tool, missing context,\nrising cost. Recommending observability is not a nice-to-have in a deployment\nthat is about to expand.\n\n## Memory and learning\n\nAn Agent can retain useful context across work — what a user prefers, facts\nworth keeping, lessons about its own job — and reviewed human feedback can\nbecome approved behavioural rules that apply to future runs.\n\nTwo boundaries worth stating: memory should be visible and removable rather than\na hidden store of everything ever said, and feedback is not automatically a\nrule. Something must review it before it changes behaviour.\n\n## The honest answer\n\nWhen a request lands on any of the above, say where it is configured and what\nthe person will find there. Do not propose an Automation as a substitute for a\nChannel, and do not report a missing command as though the capability were\nmissing.\n",
|
|
40
40
|
"understanding-frontera/references/choosing-what-to-build.md": "# Choosing what to build\n\nPeople describe the result they want, not the artifact they need. \"An\noperations dashboard\", \"one definition of active customer\", \"answer from our\npolicy PDFs\" and \"a reusable approval workflow\" are four different artifacts and\nnone of them names one.\n\n## Outcome to artifact\n\n| The person wants | Primary artifact | Ask when unsure |\n|---|---|---|\n| A conversational or autonomous capability | Agent | What decisions should it make, and what must it be able to reach? |\n| A purpose-built operational interface | Frontera App | Who opens it repeatedly, and which governed data or effects does it need? |\n| A shared definition or governed data layer | Blueprint | Which objects, links, metrics and effects must be shared? |\n| A repeatable business workflow as code | Automation | What are its inputs, its steps, its platform grants, and its return value? |\n| A connection to an external service | Plugin | Which external capabilities must Frontera be able to call? |\n| A reusable procedure for an Agent | Skill | What method should the Agent follow every time? |\n| Documents to answer from | Knowledge | Which source material grounds it, and who maintains it? |\n| A distributable bundle of resources | Pack | Which resources form one coherent capability? |\n| Structured records entering the shared model | Dataset | What contract, source and refresh behaviour are required? |\n| A controlled change to a system of record | Action | What effect is allowed, with which inputs, approval and audit boundary? |\n| Protected credentials or configuration | Secret | Which authorized artifact needs the value? |\n\n## One primary artifact, named dependencies\n\nMost real requests compose. Do not force a single-artifact answer, and do not\nanswer with a list either. **Name the primary artifact — the one that owns the\noutcome — then name what it depends on.** Authoring starts in the primary\nartifact's skill.\n\n| Request | Primary | Dependencies |\n|---|---|---|\n| \"Build a shipment board for operations.\" | Frontera App | Blueprint object types and grants; an Action if the board changes state |\n| \"Give the claims agent access to Slack.\" | Plugin | The Agent is the consumer, not the thing being built |\n| \"Make every team calculate active customer the same way.\" | Blueprint | A metric definition; nothing about Agent prompt text |\n| \"Let the agent answer from our policy PDFs.\" | Knowledge | Attachment to the Agent; not a Skill |\n| \"Implement the approval workflow as reusable code.\" | Automation | An Action wherever it changes a system of record; a Secret for outbound calls |\n| \"Create an active-customer view and let account managers update status.\" | Frontera App | A Blueprint metric to read, an Action to write |\n\n## The prompts that go wrong\n\n**Direct** — the noun is present. \"Add a property to the Claim object type.\"\nBlueprint. Nothing to decide.\n\n**Indirect** — only the outcome is present. \"Operations need somewhere to see\ntoday's delayed shipments and mark them chased.\" That is a Frontera App over\nBlueprint data with an Action for the write. The word \"App\" never appeared.\n\n**Incomplete** — one question decides it. \"We need something for invoice\napprovals.\" Ask one thing: *does a person work through this, or does it run on\nits own?* A person working through it is an App or an Agent; running on its own\nis an Automation.\n\n**Negative** — the obvious answer is wrong. \"What OAuth apps are connected?\"\nConnected services are **Plugins**, not Frontera Apps, and the word \"app\" in the\nquestion is the trap. Conversely \"What apps do we have?\" means Frontera Apps\nalone — do not also enumerate integrations unless the person said plugin,\nintegration, connector or connected service.\n\n**Ambiguous** — do not guess. \"Build a React dashboard.\" A React dashboard is\nnot necessarily a Frontera App; it becomes one when it is served on the\nApplications surface and reads through Blueprint. Ask whether this runs inside\nFrontera before assuming it does.\n\n## Questions that separate neighbours\n\n- **App or Agent?** Is the interaction the same shape every time, or does it\n vary with what the person is trying to do? Same shape is an App.\n- **Agent or Automation?** Does anything need judgement about ambiguous input?\n No judgement is an Automation.\n- **Skill or Knowledge?** Is it a method the Agent should follow, or material it\n should quote? Method is a Skill.\n- **Plugin or Action?** Is the effect a call into someone else's system through\n its own API, or a named business change the organization wants reviewed and\n audited? Reviewed and audited is an Action.\n- **Object type or property?** Would somebody in the business say the word in a\n meeting and ask questions about it on its own? That is an object type.\n- **Blueprint or Dataset?** The Dataset is the contract for the records. The\n Blueprint object type is what the business calls them.\n\n## When the answer is \"the Console\"\n\nChannels, memory, approvals and observability are real and are configured in the\nConsole. If the request is one of those, say so plainly and describe what the\nperson will find there. Routing round it — proposing an Automation because\nChannels have no CLI noun — is worse than the honest answer.\n",
|
|
41
41
|
"understanding-frontera/references/vocabulary.md": "# Vocabulary\n\nThe words this plugin uses, and the ones that are wrong. Getting these right is\nnot pedantry: several of them collide with words that mean something else on the\nsame platform, and a wrong one sends a reader to the wrong surface.\n\n| Use | Never | Why |\n|---|---|---|\n| Frontera | The former product name | The product is Frontera. Older internal material predates the rename |\n| Blueprint, \"the shared model of your organization\" | \"semantic layer\", \"operational layer\", the academic word for an object graph | The academic word is not the product's word; \"semantic layer\" undersells what it does and \"operational layer\" overclaims |\n| analytics connection, analytics engine | The vendor's product name | Never named in anything a customer reads |\n| Plugin | \"app\", when an integration is meant | A Frontera App is a code project on the Applications surface. The collision is real and expensive |\n| Frontera App | \"custom application\", \"dashboard\" | An App is a code project served on the Applications surface, not any page that shows numbers |\n| Agent | \"bot\", \"assistant\" | An Agent is purpose-built around real work and has resources, boundaries and a lifecycle |\n| Automation | \"the scheduled job\", \"the cron\" | The schedule is the trigger. The Automation is the workflow function |\n| Action, governed Action | \"write API\", \"mutation endpoint\" | An Action is a named business change with a reviewed path, not a generic write |\n| Knowledge | \"the docs\", \"RAG\" | Knowledge is a maintained corpus with attachment and ingestion semantics |\n| Skill | \"prompt\", \"tool\" | A Skill teaches a method. It grants nothing |\n| Object type | \"table\", \"entity\" | Object types are the words the business uses out loud |\n| Draft, version, release | \"saved\", \"deployed\" used interchangeably | Draft, immutable version and live release are three distinct states |\n\n## What Frontera is not\n\nCompressed from the product's own boundary statements, because each of these is\na real misreading someone has arrived with:\n\n- **Not only chat.** Chat is one surface. Agents also reach people through\n Applications, Channels, schedules and other systems.\n- **Not fixed-answer lookup.** An Agent reasons over the organization's context;\n it is not a search box with a nicer reply.\n- **Not only automation.** Deterministic workflows stay deterministic and should.\n Agents are for the work that needs judgement, and the two coexist.\n- **Not generic assistants.** An Agent without organizational context, resources\n and boundaries is not the thing being described here.\n- **Not a platform handed over for the customer to figure out alone.** Frontera\n is deployed *with* an organization. That is part of the product, not a service\n wrapped around it.\n\n## Two words to be careful with\n\n**\"App\".** Ambiguous by history. The bare words *app* and *apps* mean Frontera\nApps. Only treat it as an integration when the person says plugin, integration,\nconnector or connected service, or names one.\n\n**\"Model\".** Ambiguous by context. It means the shared business model in a\nBlueprint conversation and a language model in an Agent conversation. Say which\nwhen it could be either.\n",
|
|
42
|
-
"understanding-frontera/SKILL.md": "---\nname: understanding-frontera\ndescription: Use when the question is what Frontera IS rather than which command to run — deciding whether an outcome should be an Agent, a Frontera App, Blueprint, an Automation or a Plugin; what a Frontera concept means; what belongs in the shared model; why something is not visible to an agent; or which parts are Console-configured and have no CLI noun at all. Command syntax lives in the using-frontera skill, not here.\n---\n\n# Understanding Frontera\n\nFrontera is a platform that is deployed *with* an organization, not handed to\nit. Everything below describes someone's real operating reality — their\ncustomers, their claims, their shipments — so guessing at their model is never a\nneutral act. When the shape of the work is unclear, ask; do not invent a\nplausible model and build on it.\n\nThis skill carries meaning and decision boundaries. It names no command syntax:\nthat is `using-frontera`'s job, and the CLI's generated help is the only\nauthority on it.\n\n## The artifacts you author\n\nEleven things can be created or changed through the platform. Each owns one\noutcome.\n\n**Agent** — a conversational or autonomous capability composed from models,\ninstructions, and reusable resources. Right when the outcome needs reasoning,\nconversation, judgement, or autonomous execution. Not a fixed interface, and not\na shared data model.\n\n**Frontera App** — an operational UI and code project built on Frontera, reading\ngoverned data through the Blueprint SDK and served on the Applications surface.\nRight when people need a purpose-built interface for a recurring operational job.\n**Not** an integration with an outside system: that is a Plugin.\n\n**Blueprint** — the organization's shared, governed business model and data\nlayer: object types, properties, links, metrics, object sets, datasets, grants,\nand Actions. Right when several experiences must agree on what a business word\nmeans. Not a UI, not a prompt, not a warehouse schema.\n\n**Automation** — a reusable code workflow function that performs a business\nworkflow on Frontera, with typed inputs, declared platform grants, durable\nsteps, and a return value. Right when a repeatable process should be expressed\nas code. Not an Agent conversation, and not an invocation policy — a schedule is\nhow it is called, never what it is.\n\n**Plugin** — an external integration, commonly exposing tools through MCP.\nRight when Frontera must connect to or act through another system.\n\n**Skill** — reusable instructions and domain procedure that teach an Agent how\nto perform a kind of work. It teaches *how*; it grants nothing.\n\n**Knowledge** — retrievable documents an Agent is grounded in. Source material,\nnot instructions.\n\n**Pack** — a reusable bundle of compatible resources, installed as one unit.\n\n**Dataset** — a governed data contract and backing source that feeds Blueprint.\nThe contract, not the business model over it.\n\n**Action** — a governed business-system effect exposed through Blueprint, with a\nreviewed write path. The one way an App, Agent, or Automation changes a system\nof record.\n\n**Secret** — a named confidential value an authorized workflow or integration\nmay use. Named, never read: the value is injected server-side.\n\n## What gets conflated\n\n| These look alike | The difference that matters |\n|---|---|\n| Skill vs Knowledge vs Plugin vs Pack | A Skill teaches a procedure. Knowledge is content to retrieve. A Plugin brings outside capability. A Pack is a bundle of the others. Only a Plugin grants an Agent something new to *do*. |\n| Agent vs Automation | An Agent reasons over ambiguous input. An Automation executes a defined workflow deterministically. If the steps are known, do not make them a conversation. |\n| Frontera App vs Plugin | An App is code *you* write on the Applications surface. A Plugin is a connection to a system someone else runs. \"What apps do we have\" means Apps; \"what is connected\" means Plugins. |\n| App vs Channel | An App is a surface people open. A Channel is a path work arrives through. The Channel is never the Agent. |\n| Blueprint object type vs property | An object type is a thing the business names out loud and asks questions about. A property describes one. |\n| Workspace vs organization | Blueprint and Packs are organization-level and shared. Agents, Plugins, Knowledge, Skills, Secrets and Channels are workspace-level. |\n| Draft vs published vs live | Drafts and previews are reversible and cost nothing. Publishing and promoting change what real people see. |\n\n## Concepts you explain but do not author from a terminal\n\nFour concepts are real, are configured in the Console, and have **no CLI noun**.\nSaying so is the correct answer; hunting for a command is not.\n\n| Concept | What it is |\n|---|---|\n| Channel | The entry point and delivery path work travels through — chat apps, email, forms, webhooks, schedules. |\n| Memory and learning | What an Agent retains across work, and how reviewed feedback becomes approved behavioural rules. |\n| Permissions and approvals | What AI may do, and what a human must review before it happens. |\n| Observability and evaluation | Traces, runs, cost, quality scores — what happened, and whether it was good. |\n\n## Concept to surface\n\n| Concept | Reached by |\n|---|---|\n| Agents | `frontera agent` |\n| Blueprint, datasets, grants | `frontera blueprint`, `frontera dataset`, `frontera source` |\n| Knowledge | `frontera knowledge` |\n| Skills and packs | `frontera skill`, `frontera pack` |\n| Plugins and their capabilities | `frontera plugin`, `frontera capability` |\n| Governed Actions | `frontera action` |\n| Frontera Apps | `frontera app` |\n|
|
|
42
|
+
"understanding-frontera/SKILL.md": "---\nname: understanding-frontera\ndescription: Use when the question is what Frontera IS rather than which command to run — deciding whether an outcome should be an Agent, a Frontera App, Blueprint, an Automation or a Plugin; what a Frontera concept means; what belongs in the shared model; why something is not visible to an agent; or which parts are Console-configured and have no CLI noun at all. Command syntax lives in the using-frontera skill, not here.\n---\n\n# Understanding Frontera\n\nFrontera is a platform that is deployed *with* an organization, not handed to\nit. Everything below describes someone's real operating reality — their\ncustomers, their claims, their shipments — so guessing at their model is never a\nneutral act. When the shape of the work is unclear, ask; do not invent a\nplausible model and build on it.\n\nThis skill carries meaning and decision boundaries. It names no command syntax:\nthat is `using-frontera`'s job, and the CLI's generated help is the only\nauthority on it.\n\n## The artifacts you author\n\nEleven things can be created or changed through the platform. Each owns one\noutcome.\n\n**Agent** — a conversational or autonomous capability composed from models,\ninstructions, and reusable resources. Right when the outcome needs reasoning,\nconversation, judgement, or autonomous execution. Not a fixed interface, and not\na shared data model.\n\n**Frontera App** — an operational UI and code project built on Frontera, reading\ngoverned data through the Blueprint SDK and served on the Applications surface.\nRight when people need a purpose-built interface for a recurring operational job.\n**Not** an integration with an outside system: that is a Plugin.\n\n**Blueprint** — the organization's shared, governed business model and data\nlayer: object types, properties, links, metrics, object sets, datasets, grants,\nand Actions. Right when several experiences must agree on what a business word\nmeans. Not a UI, not a prompt, not a warehouse schema.\n\n**Automation** — a reusable code workflow function that performs a business\nworkflow on Frontera, with typed inputs, declared platform grants, durable\nsteps, and a return value. Right when a repeatable process should be expressed\nas code. Not an Agent conversation, and not an invocation policy — a schedule is\nhow it is called, never what it is.\n\n**Plugin** — an external integration, commonly exposing tools through MCP.\nRight when Frontera must connect to or act through another system.\n\n**Skill** — reusable instructions and domain procedure that teach an Agent how\nto perform a kind of work. It teaches *how*; it grants nothing.\n\n**Knowledge** — retrievable documents an Agent is grounded in. Source material,\nnot instructions.\n\n**Pack** — a reusable bundle of compatible resources, installed as one unit.\n\n**Dataset** — a governed data contract and backing source that feeds Blueprint.\nThe contract, not the business model over it.\n\n**Action** — a governed business-system effect exposed through Blueprint, with a\nreviewed write path. The one way an App, Agent, or Automation changes a system\nof record.\n\n**Secret** — a named confidential value an authorized workflow or integration\nmay use. Named, never read: the value is injected server-side.\n\n## What gets conflated\n\n| These look alike | The difference that matters |\n|---|---|\n| Skill vs Knowledge vs Plugin vs Pack | A Skill teaches a procedure. Knowledge is content to retrieve. A Plugin brings outside capability. A Pack is a bundle of the others. Only a Plugin grants an Agent something new to *do*. |\n| Agent vs Automation | An Agent reasons over ambiguous input. An Automation executes a defined workflow deterministically. If the steps are known, do not make them a conversation. |\n| Frontera App vs Plugin | An App is code *you* write on the Applications surface. A Plugin is a connection to a system someone else runs. \"What apps do we have\" means Apps; \"what is connected\" means Plugins. |\n| App vs Channel | An App is a surface people open. A Channel is a path work arrives through. The Channel is never the Agent. |\n| Blueprint object type vs property | An object type is a thing the business names out loud and asks questions about. A property describes one. |\n| Workspace vs organization | Blueprint and Packs are organization-level and shared. Agents, Plugins, Knowledge, Skills, Secrets and Channels are workspace-level. |\n| Draft vs published vs live | Drafts and previews are reversible and cost nothing. Publishing and promoting change what real people see. |\n\n## Concepts you explain but do not author from a terminal\n\nFour concepts are real, are configured in the Console, and have **no CLI noun**.\nSaying so is the correct answer; hunting for a command is not.\n\n| Concept | What it is |\n|---|---|\n| Channel | The entry point and delivery path work travels through — chat apps, email, forms, webhooks, schedules. |\n| Memory and learning | What an Agent retains across work, and how reviewed feedback becomes approved behavioural rules. |\n| Permissions and approvals | What AI may do, and what a human must review before it happens. |\n| Observability and evaluation | Traces, runs, cost, quality scores — what happened, and whether it was good. |\n\n## Concept to surface\n\n| Concept | Reached by |\n|---|---|\n| Agents | `frontera agent` |\n| Blueprint, datasets, grants | `frontera blueprint`, `frontera dataset`, `frontera source` |\n| Knowledge | `frontera knowledge` |\n| Skills and packs | `frontera skill`, `frontera pack` |\n| Plugins and their capabilities | `frontera plugin`, `frontera capability` |\n| Governed Actions | `frontera action` |\n| Frontera Apps | `frontera app` |\n| Functions | `frontera function` |\n| Secrets | `frontera secret` |\n| Channels | **Console only** — no CLI noun |\n| Memory, observability, approvals | **Console only** — no CLI noun |\n\n## The four product surfaces\n\n| Surface | What people do there |\n|---|---|\n| Chat | Work with Agents through conversation and generated artifacts. |\n| Applications | Use deployed Frontera Apps for recurring operational work. |\n| Blueprint | Explore the released shared model and governed data. |\n| Console | Configure, observe and govern everything else. |\n\nA surface is where an artifact is configured or used. It is not the artifact.\nAn Agent configured in the Console is still an Agent.\n\n## Where to read further\n\n| Read | When |\n|---|---|\n| `references/choosing-what-to-build.md` | The artifact is implicit, ambiguous, or the request spans several |\n| `references/blueprint.md` | Modelling the shared layer, grants, releases, dataset bindings |\n| `references/agents.md` | What an Agent is composed of, and which resource carries what |\n| `references/apps.md` | What an App can and cannot be, and what it may read |\n| `references/automations-and-actions.md` | Workflow functions, and governed write paths |\n| `references/channels-and-permissions.md` | Entry points, autonomy, approvals — the Console-owned half |\n| `references/vocabulary.md` | The words to use, and the ones that are wrong |\n\nFor modelling *method* — competency questions, naming, identity, review — use\n`designing-frontera-blueprint`. For anything that runs, start at\n`using-frontera`.\n",
|
|
43
43
|
"using-frontera/agents/openai.yaml": "# Codex presentation metadata. Host-specific by design: SKILL.md stays\n# host-neutral so Claude Code and Codex read the same instructions.\ninterface:\n display_name: Using Frontera\n short_description: Resolve the customer profile, read generated help, interpret exits.\n default_prompt: Which Frontera workspace is this directory bound to?\npolicy:\n # This is the preflight every other Frontera skill depends on, so implicit\n # invocation is exactly what it is for.\n allow_implicit_invocation: true\n",
|
|
44
44
|
"using-frontera/SKILL.md": "---\nname: using-frontera\ndescription: Use before any `frontera` command — resolving which customer profile and API origin this directory is bound to, discovering command syntax from generated help, and interpreting the CLI's exit codes. Also carries the compact artifact map that routes a described outcome to the right Frontera artifact and skill. Load this first whenever the work touches Frontera Apps, Blueprint, Agents, Skills, Plugins, Knowledge, Packs, Datasets, Actions, Secrets or Automations.\n---\n\n# Using Frontera\n\nThe `frontera` CLI is the whole interface. There is no MCP server, no API client\nto write, and no credential for you to read or handle.\n\n**Two authorities, and they do not overlap.** Skills carry Frontera's meaning,\nits decision boundaries and its workflows. The CLI supplies current syntax,\navailable operations and live state. Never copy syntax out of a skill; never\nexpect the CLI to tell you which artifact an outcome should become.\n\n## Preflight — always, before any mutation\n\n```bash\nfrontera auth current --json\nfrontera help --json\n```\n\nThe first answers **which customer you are about to change**. The second is the\nauthoritative command syntax, generated from the command table, so it cannot be\nout of date. Never guess a command; never trust this file for syntax.\n\n`auth current` returns the resolved profile, its API origin, the credential kind\nand where each part of the resolution came from:\n\n```json\n{\n \"profile\": \"acme-prod\",\n \"profileSource\": \"directory\",\n \"profileSourcePath\": \"/Users/jaco/Customers/acme/.frontera/context.json\",\n \"apiUrl\": \"https://api.frontera.example\",\n \"credentialKind\": \"workspace\",\n \"workspaceId\": \"ws_123\",\n \"hasSecret\": true\n}\n```\n\nIf `profile` is not the customer you were asked to work on, **stop and say so**.\nChanging directory changes the profile; that is the intended mechanism.\n\n## When there is no profile\n\n`PROFILE_NOT_SELECTED` (exit 2) means this directory is bound to nothing. Do not\npass `--profile` to work around it and do not invent a name. Report it, and offer\nthe two commands that fix it:\n\n```bash\nfrontera auth list\nfrontera auth use <profile>\n```\n\nOnly the person can add a profile — it requires their API key:\n\n```bash\nfrontera auth add <profile> --api-url <origin> --from -\n```\n\nNever ask for a key in chat, never put one in a flag, and never write one into a\nfile in the repository.\n\n## Narrowing help\n\n```bash\nfrontera <noun> --help --json\nfrontera <noun> <verb> --help --json\n```\n\nEach entry carries the arguments in order, the flags with their types, working\nexamples, and two preconditions worth checking before you call: whether it needs\nan App project (`needsProject`) and whether it needs a credential\n(`requiresCredential`).\n\n## Reading the result\n\n- **stdout is data and nothing else.** Progress and errors go to stderr.\n- **exit 0 means stdout is trustworthy.** Check the code before parsing.\n\n| Exit | Meaning | What to do |\n|------|---------|-----------|\n| 0 | success | continue |\n| 1 | transient, remote or secure-store failure | retry once, then report |\n| 2 | usage, input, or profile selection | fix the command — the hint names how |\n| 3 | conflict — someone changed it first | re-fetch, reapply, retry |\n| 4 | missing, revoked or unauthorized key | verify or replace the profile, or ask an admin |\n\nEvery error carries a `hint` naming the next command. Read it before acting.\n\nProfile-specific codes and what each one means:\n\n| Code | Meaning |\n|------|---------|\n| `PROFILE_NOT_SELECTED` | this directory is bound to no profile |\n| `PROFILE_NOT_FOUND` | the named profile does not exist on this machine |\n| `PROFILE_SECRET_MISSING` | metadata exists, the key does not — re-add it |\n| `PROFILE_ORIGIN_MISMATCH` | `--api-url` disagrees with the profile's origin |\n| `PROJECT_CONTEXT_CORRUPT` | `.frontera/context.json` is unreadable |\n| `PROJECT_CONTEXT_UNTRUSTED` | a context file this machine never bound — do not adopt it yourself, ask |\n| `SECURE_STORE_UNAVAILABLE` | the OS credential store refused |\n\n## Invariants\n\n- **The working directory selects the profile.** `--profile` is a one-command\n override, not the normal path. If you find yourself passing it to every\n command, the directory binding is wrong — fix that instead. One legitimate\n exception: a task that authors (organization key) and then reads what it\n built (workspace key) genuinely spans two credentials — switching with\n `--profile` for those commands is the intended way, not misuse.\n- **On exit 3, re-fetch — never force.** The document you hold is stale. Get it\n again, reapply your edit on top, then send it. Overwriting discards whatever\n the other writer did.\n- **Secrets never go in a flag.** `frontera secret set NAME --from -` reads the\n value from stdin, `--from ./file` from a file. An inline value is refused\n because it lands in shell history and the process list.\n- **Prepare freely; publish only when asked.** Drafts, previews and plans are\n reversible and cost nothing. Publish and promote are live transitions — see the\n `publishing-frontera` skill.\n\n## What a missing CLI looks like\n\nIf `frontera` is not on PATH, stop and give the person one instruction:\n\n```bash\nbun add -g @frontera-sdk/cli\n```\n\nDo not attempt to install it yourself, and do not fall back to calling the API\ndirectly.\n\n## What can be built here\n\nEleven artifacts, each owning one outcome. When the person named the artifact,\nskip to the routing table below. When they described a *result* instead, decide\nfrom this one first.\n\n| The outcome they described | Artifact |\n|---|---|\n| Reasoning, conversation, or autonomous execution | **Agent** |\n| A purpose-built interface for a recurring operational job | **Frontera App** |\n| A shared organizational definition or governed data layer | **Blueprint** |\n| A repeatable business workflow expressed as code | **Automation** |\n| A connection to an external system | **Plugin** |\n| A reusable procedure an agent should follow | **Skill** |\n| Documents or content to answer from | **Knowledge** |\n| A distributable bundle of resources | **Pack** |\n| Structured records entering the shared model | **Dataset** |\n| A controlled change to a system of record | **Action** |\n| Protected credentials or configuration | **Secret** |\n\n**A Frontera App is not a Plugin.** An App is a code project you build, served\non the Applications surface, reading governed data through Blueprint. A Plugin\nis a connection to a system somebody else runs. \"What apps do we have\" means\nApps; \"what is connected\" means Plugins.\n\nChannels, memory, approvals and observability are real concepts with **no CLI\nnoun** — they are configured in the Console. Say so rather than searching for a\ncommand.\n\nWhen the request spans several artifacts, name the primary one and treat the\nrest as dependencies. Authoring begins in the primary artifact's skill.\n\n## Which skill next\n\n| Work | Skill |\n|---|---|\n| Deciding what to build, or explaining what something *is* | `understanding-frontera` |\n| Designing the shared model itself — naming, identity, review | `designing-frontera-blueprint` |\n| A Frontera App — an operational code project on the Apps surface | `authoring-frontera-apps` |\n| Object types, links, metrics, bindings, grants | `authoring-frontera-blueprint` |\n| An agent's models, prompts, skills, knowledge, plugins | `authoring-frontera-agents` |\n| A reusable code workflow function on the platform | `authoring-frontera-automations` |\n| Taking any of it live | `publishing-frontera` |\n"
|
|
45
45
|
},
|
|
46
46
|
"agentsBlock": "## Frontera\n\nThis directory uses Frontera through the `frontera` CLI.\nFor Frontera work, load `using-frontera` first; it routes to the rest.\nWhen the question is what to build rather than what to run, load `understanding-frontera`.\nBefore mutation, inspect `frontera auth current --json`.\nRead syntax from `frontera help --json`; do not guess commands.\nChannels, memory, approvals and observability are Console-configured and have no CLI noun.\nPrepare drafts and previews freely. Publish or promote only when explicitly requested.\n",
|
|
47
47
|
"claudeBlock": "@AGENTS.md\n",
|
|
48
48
|
"pluginManifests": {
|
|
49
|
-
"claudeCode": "{\n \"name\": \"frontera\",\n \"version\": \"1.1.
|
|
50
|
-
"codex": "{\n \"name\": \"frontera\",\n \"version\": \"1.1.
|
|
49
|
+
"claudeCode": "{\n \"name\": \"frontera\",\n \"version\": \"1.1.8\",\n \"description\": \"Understand Frontera, then author its Apps, Blueprint, Agents and Automations through the frontera CLI.\",\n \"author\": {\n \"name\": \"Frontera\"\n },\n \"homepage\": \"https://github.com/sebati-ai/sebati-agents\",\n \"license\": \"Apache-2.0\",\n \"keywords\": [\n \"frontera\",\n \"blueprint\",\n \"apps\",\n \"automations\"\n ]\n}\n",
|
|
50
|
+
"codex": "{\n \"name\": \"frontera\",\n \"version\": \"1.1.8\",\n \"description\": \"Understand Frontera, then author its Apps, Blueprint, Agents and Automations through the frontera CLI.\",\n \"author\": {\n \"name\": \"Frontera\"\n },\n \"homepage\": \"https://github.com/sebati-ai/sebati-agents\",\n \"repository\": \"https://github.com/sebati-ai/sebati-agents\",\n \"license\": \"Apache-2.0\",\n \"keywords\": [\n \"frontera\",\n \"blueprint\",\n \"apps\",\n \"automations\"\n ],\n \"skills\": \"./skills\",\n \"displayName\": \"Frontera\",\n \"shortDescription\": \"Operate the Frontera platform from Codex through the frontera CLI.\",\n \"category\": \"developer-tools\",\n \"composerIcon\": \"./assets/icon.png\",\n \"logo\": \"./assets/icon.png\",\n \"brandColor\": \"#006FE6\"\n}\n"
|
|
51
51
|
},
|
|
52
52
|
"pluginAssets": {
|
|
53
53
|
"assets/icon.png": "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",
|