Skip to content

feat(template): author and publish community templates from the CLI - #355

Merged
CarmenDou merged 8 commits into
mainfrom
feat/template-authoring
Oct 7, 2026
Merged

CarmenDou merged 8 commits into
mainfrom
feat/template-authoring

Conversation

@CarmenDou

@CarmenDou CarmenDou commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

What

An agent, or a person, can author the org's community templates from the CLI: the same drafts the console editor changes, with the same checks. Spec: docs/superpowers/specs/2026-10-06-agent-template-authoring-design.md in the insta-cloud superproject (not in this repo), section 3.

  • insta template create generates a draft from the linked project (or --project) and prints its code, name, status and the console editor link. --blank starts one with no project in the org (--org, else the linked project's org), once the platform creates blank templates. Until then it says so.
  • insta template drafts and insta template draft <code> read the org's templates and one draft: services, every variable with its choice, the publish requirements.
  • insta template edit <code> --patch <file|-> sends the console editor's PATCH body. Without expectedUpdatedAt in it, the draft's current one is used.
  • insta template regenerate <code> rebuilds the draft from its project, which is how a blocked item is fixed.
  • insta template publish <code> says the template goes public in the community gallery at once, with no review, and asks on a terminal. Anywhere else it needs --yes and exits 2 without it, and so does an agent on a terminal, because a prompt is never shown to an agent: it passes --yes only after the person has said yes. unpublish takes it out again. delete removes a draft that was never published and asks and refuses like publish.
  • Every command takes --json and prints one document. Most print { template, editorUrl }, the platform's view plus the editor link. Three differ: drafts prints the platform's array, regenerate prints { template, changes, editorUrl }, and delete prints { ok: true, orgId, code }.

How

  • New src/commands/template-author.ts beside template.ts, registered under insta template after deploy. The org routes are account routes in agent mode, so an agent signs them with a bootstrap session, which the platform admits for these operations from InsForge/instacloud-platform branch feat/agent-template-authoring (InsForge/instacloud-platform#634, controller to fill in).
  • The editor link is the API host with its leading api. label read as console., plus /orgs/<orgId>/templates/<code>. Any other host prints the code alone.
  • A coded answer (template_draft_changed, template_not_ready and the other publish codes) and any 400 of regenerate print as the platform's sentence. create --blank tells Fastify's route 404 (and an agent's unclassified_agent_action) from the handler's org not found by the body.
  • publish and delete treat --json and agent mode as nobody being able to answer, whatever the terminal says. A harness that runs commands in a pty would otherwise show the prompt to the agent. The check reads deps.agent, else agent mode, next to deps.tty, so the tests do not depend on the environment. A leading UTF-8 BOM in a patch file is stripped before parsing.
  • resolveOrgId (billing.ts) takes the project reader as a parameter, and postgres.ts exports confirmOnTerminal, so the commands are tested over an injected transport with no module mocks.
  • Agent reach (rule 6): the MCP tools are in InsForge/instacloud-mcp branch feat/template-authoring (InsForge/instacloud-mcp#87, controller to fill in): insta_create_template_draft, insta_list_template_drafts, insta_get_template_draft, insta_update_template_draft, insta_regenerate_template_draft, insta_publish_template, insta_unpublish_template, insta_delete_template_draft.
  • The skills/insta/cli-reference.md mirror (AGENTS.md rule 4) is docs(insta): author and publish a community template instacloud-skills#163, open in the same change set: the eight commands, their flags and the authoring workflow, checked against this branch's --help. It merges right after the release that carries this PR, because it names that release as the CLI floor.
  • The template group description and the README row name the authoring verbs, and test/help-surface.test.ts pins the help order: list, info, deploy, create, drafts, draft, edit, regenerate, publish, unpublish, delete.

Merge and release after the platform branch is in production: before it, an agent's edit, regenerate, publish, unpublish and delete answer unclassified_agent_action.

Known limitation: publish --yes publishes the draft's current updatedAt (spec section 3), so an edit made in the console between the agent showing the draft and the person's yes is published. The skills workflow has the agent re-read the draft right before publish --yes and stop if updatedAt moved. The MCP tool pins it with expectedUpdatedAt.

Verify

  • tsc --noEmit: clean.
  • Vitest on Node 20: 102 files, 2105 tests passed. New: test/template-author.test.ts (62 tests over a fake platform: every request path and body, the editor link, the three answers of a blank create (Fastify's 404 and an agent's 403 unclassified_agent_action print "not supported yet", the handler's org not found passes through), the fresh read for expectedUpdatedAt, the confirmation and the exit-2 refusal with no terminal, under --json and in agent mode, the platform's sentences, a BOM-prefixed patch) and the template help order in help-surface.test.ts.

🤖 Generated with Claude Code

insta template drafts lists the org's templates with their status, and
insta template draft <code> prints one draft: its services, every variable
with its choice, the publish requirements and the console editor link.
The org is --org, else the linked project's org. resolveOrgId takes the
project reader as a parameter so the command is testable without a link.
insta template create generates a draft from the linked project (or
--project), or an empty one with --blank in the org. A platform without the
blank route answers Fastify's 404 to a person and unclassified_agent_action
to an agent, and both read as "this platform does not create blank
templates yet". The handler's own org not found passes through.

insta template edit <code> --patch <file|-> sends the console editor's PATCH
body, filling expectedUpdatedAt from a fresh read when the file has none.
insta template regenerate <code> rebuilds the draft from its project. A coded
answer, and any 400 of regenerate, prints as the platform's sentence.
readAllStdin appended each stdin chunk to a string, so a multi-byte
character split across two chunks came back as U+FFFD. It now collects the
Buffers and decodes once, as the observe hook does, and takes the stream as
a parameter so a test can feed it split bytes. The template edit tests also
remove their temp directory.
insta template publish <code> reads the draft and publishes that version.
On a terminal it says the template goes public in the community gallery at
once, with no review, and asks. Anywhere else, --json included, it needs
--yes and otherwise exits 2 before any request. delete asks the same way.
unpublish takes the template out of the gallery. confirmOnTerminal is
exported from postgres.ts for the shared prompt.
The template group says it also authors the org's community templates,
the README lists the eight authoring verbs, and help-surface pins their
order after list, info and deploy.
The paragraph about releasing after the platform and what an older
platform answers is release sequencing, so it goes stale the day the
platform ships. The PR body carries it instead.
publish and delete showed the clack prompt to an agent whose harness runs
commands in a pty, so the agent could hang on it or answer it itself. Agent
mode now counts as nobody being able to answer, like --json: both commands
need --yes and exit 2 before any request without it. The refusal says an
agent passes --yes only after the person has said yes. TemplateAuthorDeps
gains agent, read from agent mode when not given. The help and the README
say --yes is always needed for an agent.

edit --patch now strips a leading UTF-8 BOM before parsing, as the ignore
file reader does. Tests cover the agent refusal for each command, the agent
mode default, the delete --json refusal and the BOM.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

The implementation is coherent and thoroughly tested, but the required agent-facing command reference is missing.

Requirements context

I assessed the change against the PR description, README.md, AGENTS.md, and the repository development guide. The referenced superproject design (docs/superpowers/specs/2026-10-06-agent-template-authoring-design.md) is not present in this checkout, so its section 3 could not be inspected directly; detailed behavioral intent therefore comes from the PR description.

Findings

Critical

  • The command/flag additions are not mirrored in the agent-facing CLI reference. This PR registers eight new commands and their flags at src/index.ts:577-607, but contains no corresponding skills/insta/cli-reference.md update. The repository explicitly calls this a non-negotiable requirement at AGENTS.md:16-17, and the development guide says a command is only half-complete until the reference is updated in the same change set at .claude/skills/developing-insta-cli/SKILL.md:36-38. The PR description’s plan to update it after release leaves agents unable to discover the released surface during that interval. Please coordinate and land the matching superproject reference update as part of this release change set.

Suggestion

(none)

Information

  • Software engineering/functionality: Coverage is strong for routing, JSON output, error translation, optimistic concurrency, BOM handling, and interactive/agent refusal behavior (test/template-author.test.ts:278-335, test/template-author.test.ts:406-501, test/template-author.test.ts:519-582). The implementation follows the repository’s dependency-injection testing convention.
  • Security: No security finding. Template codes are URL-encoded, authentication remains in the existing API client, destructive operations retain confirmation safeguards, and patch contents are parsed as an object before being forwarded for platform-side authorization and validation (src/commands/template-author.ts:140-152, src/commands/template-author.ts:280-321). No dependencies were added.
  • Performance: No material performance finding. The additional GETs before edit and publish are bounded, intentional concurrency checks rather than N+1 behavior (src/commands/template-author.ts:251-254, src/commands/template-author.ts:287-295). File and stdin reads occur in a short-lived CLI path, not a hot server loop.
  • Verification: git diff --check main...HEAD passed. I attempted the required scripts declared at package.json:35-40, but npm run typecheck could not start because tsc is unavailable in this dependency-free, read-only checkout; consequently the test suite was not run locally.

Verdict

Request changes. The missing agent-facing command reference is an explicit repository requirement and must be resolved before merge.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

The PR implements the stated community-template authoring workflow with appropriate concurrency checks, agent/non-interactive safeguards, JSON output, and broad behavioral tests.

Requirements context

I assessed the change against the PR description, the repository guidance in AGENTS.md and .claude/skills/developing-insta-cli/SKILL.md, and the updated command documentation at README.md:240. The referenced superproject design document and skills mirror are not present in this checkout, so their contents could not be independently verified.

Findings

Critical

(none)

Suggestion

  • src/commands/template-author.ts:7-8, src/commands/postgres.ts:412-416 — The template command imports a generic confirmation helper from the unrelated Postgres command module. Consider moving this helper to a shared prompt/utility module so command groups remain independent and future Postgres changes cannot affect template authoring through an incidental dependency.

Information

  • Software engineering/functionality: coverage includes command registration, request paths and bodies, optimistic concurrency, platform error translation, JSON output, BOM handling, agent-mode refusal, terminal confirmation, and destructive-action cancellation (test/help-surface.test.ts:135-148, test/template-author.test.ts:285-344, test/template-author.test.ts:413-501, test/template-author.test.ts:519-583).
  • Security: no security-relevant defect found. Path-controlled template codes and editor-link components are encoded, patches must parse as JSON objects, and authentication remains centralized in ApiClient (src/commands/template-author.ts:47-54, src/commands/template-author.ts:140-152, src/commands/template-author.ts:207-323).
  • Performance: no material concern found for this one-shot CLI flow; operations use a small, fixed number of API calls, with the extra reads serving optimistic concurrency (src/commands/template-author.ts:240-295).
  • Verification limitation: git diff --check main...HEAD passed, but npm run typecheck && npm test could not run because this checkout has no installed dependencies and tsc is unavailable.

Verdict

Approved under the review rubric: zero Critical findings. The bot should post this as a non-approving PR comment; human approval remains separate.

@CarmenDou
CarmenDou marked this pull request as ready for review October 7, 2026 06:16

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - approved.

@CarmenDou
CarmenDou merged commit 8e9f1e5 into main Oct 7, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants