Skip to content

feat(exec): detect compiler activity during process startup#119

Merged
moshloop merged 21 commits into
mainfrom
feat/pluggable-live-renderer
Jun 26, 2026
Merged

feat(exec): detect compiler activity during process startup#119
moshloop merged 21 commits into
mainfrom
feat/pluggable-live-renderer

Conversation

@moshloop

@moshloop moshloop commented Jun 16, 2026

Copy link
Copy Markdown
Member

What

  • Add compiler and linker detection to distinguish compilation phase from startup phase
  • Introduce StatusCompiling to track when build tools are actively running
  • Update watchPorts function to accept compilationDetector callback
  • Manage three startup states: compiling → starting → running

Why

  • Prevent premature promotion to StatusRunning during builds
  • Allow long compilation times without timing out
  • Improve startup lifecycle management

Notes

  • Compiler activity resets the grace period timer
  • Detected port immediately promotes to running regardless of compilation state

Summary by CodeRabbit

  • New Features
    • Detect compiler/linker activity and add a “compiling” phase in supervised process monitoring.
    • Added schema-less --input-format support for stdin/files, plus Markdown parsing/rendering upgrades (new block primitives; improved HTML-React).
    • Enhanced chat runtime with per-request tool preferences/context handling and tool gating; added thread deletion endpoint.
  • Improvements / Bug Fixes
    • Lint now distinguishes errors vs warnings/load errors for exit behavior and summaries.
  • Documentation / Chores
    • Expanded contributing docs and added local docs server make docs.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@moshloop, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 21 minutes and 2 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3b58cc9e-8c63-4f2f-a57f-d634453f26b2

📥 Commits

Reviewing files that changed from the base of the PR and between 50fd92e and ddb09f9.

⛔ Files ignored due to path filters (6)
  • aichat/go.sum is excluded by !**/*.sum
  • examples/enitity/go.sum is excluded by !**/*.sum
  • examples/enitity/webapp/dist/index.html is excluded by !**/dist/**
  • examples/go.sum is excluded by !**/*.sum
  • examples/uber_demo/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (131)
  • .github/workflows/release.yml
  • .gitignore
  • CLAUDE.md
  • CONTRIBUTING.md
  • Makefile
  • aichat/approval.go
  • aichat/approval_test.go
  • aichat/genkit.go
  • aichat/go.mod
  • aichat/messages.go
  • aichat/messages_test.go
  • aichat/models.go
  • aichat/server.go
  • aichat/settings.go
  • aichat/settings_test.go
  • aichat/threads.go
  • aichat/threads_http.go
  • aichat/tool_group_test.go
  • aichat/tool_registry.go
  • aichat/tool_registry_test.go
  • aichat/tools_clicky.go
  • api/blocks.go
  • api/blocks_test.go
  • args_parser.go
  • cmd/clicky/input_format_test.go
  • cmd/clicky/main.go
  • cmd/clicky/output_test.go
  • e2e_integration_test.go
  • entity/annotations.go
  • entity/attach.go
  • entity/attach_test.go
  • entity/builder.go
  • entity/command.go
  • entity/command_test.go
  • entity/doc.go
  • entity/dynamic.go
  • entity/dynamic_spec.go
  • entity/dynamic_test.go
  • entity/entity.go
  • entity/entity_suite_test.go
  • entity/entity_test.go
  • entity/filter.go
  • entity/filter_test.go
  • entity/filters_test.go
  • entity/lookup_response.go
  • entity/multi_filter.go
  • entity/operation.go
  • entity/pagination.go
  • entity/registry.go
  • entity/render.go
  • entity/response_meta.go
  • entity/schema.go
  • entity/searchable_filter_test.go
  • entity/sources.go
  • entity/spec.go
  • entity/sub_command.go
  • entity/sub_command_test.go
  • entity/toolgroup_test.go
  • entity/types.go
  • entity_aliases.go
  • examples/ANSI-FIXTURES.md
  • examples/date-formatting-tests.md
  • examples/enitity/Procfile
  • examples/enitity/README.md
  • examples/enitity/Taskfile.yaml
  • examples/enitity/go.mod
  • examples/enitity/main.go
  • examples/enitity/main_test.go
  • examples/enitity/webapp/package.json
  • examples/enitity/webapp/pnpm-workspace.yaml
  • examples/enitity/webapp/src/App.tsx
  • examples/enitity/webapp/src/MarkdownEditorPage.tsx
  • examples/enitity/webapp/src/main.tsx
  • examples/enitity/webapp/tsconfig.tsbuildinfo
  • examples/enitity/webapp/vite.config.ts
  • examples/go.mod
  • examples/kitchen-sink.md
  • examples/simple-test.md
  • examples/uber_demo/README.md
  • examples/uber_demo/go.mod
  • exec/compiler.go
  • exec/supervise_loop.go
  • exec/supervised.go
  • exec/supervised_test.go
  • format.go
  • formatters/clicky_document.go
  • formatters/html_react_formatter.go
  • formatters/html_react_formatter_test.go
  • go.mod
  • lint/analyzer.go
  • lint/analyzer_test.go
  • lint/direct_stdout.go
  • lint/entity_registration.go
  • lint/render_builder.go
  • lint/runner.go
  • lint/severity.go
  • lint/severity_test.go
  • lint/summary.go
  • lint/summary_test.go
  • lint/testdata/src/bad/bad.go
  • lint/testdata/src/entityreg/bad/bad.go
  • lint/testdata/src/entityreg/good/good.go
  • lint/testdata/src/github.com/flanksource/clicky/api/stub.go
  • lint/testdata/src/github.com/flanksource/clicky/stub.go
  • lint/testdata/src/github.com/spf13/cobra/stub.go
  • lint/testdata/src/good/good.go
  • markdown.go
  • markdown/document.go
  • markdown/markdown_test.go
  • markdown/options.go
  • markdown/parse.go
  • markdown/table_dedup_test.go
  • mcp/registry.go
  • mcp/server.go
  • prompt_test.go
  • rpc/cobra_command.go
  • rpc/context_datafunc_test.go
  • rpc/converter.go
  • rpc/converter_toolgroup_test.go
  • rpc/executor.go
  • rpc/executor_test.go
  • rpc/filter_ref_openapi_test.go
  • rpc/openapi.go
  • rpc/openapi_reflect.go
  • rpc/openapi_reflect_test.go
  • rpc/openapi_test.go
  • rpc/request_context.go
  • rpc/request_context_test.go
  • rpc/types.go
  • task/render.go
  • task/render_test.go

Walkthrough

Adds compiler detection and a StatusCompiling lifecycle state, expands chat/runtime/tool handling, moves the entity model into a dedicated package with filters and dynamic schema entities, adds markdown parsing and rendering support, and updates RPC/MCP, linting, docs, examples, and build tooling.

Changes

Compiler-aware supervision

Layer / File(s) Summary
Compiler detection
exec/compiler.go, exec/supervised.go
Adds compiler/linker process matching helpers and the StatusCompiling status value.
Startup state machine
exec/supervise_loop.go, exec/supervised_test.go
Extends port watching to track compilation activity, wait time, and promotions between starting, compiling, and running states.

Aichat chat/runtime/tooling

Layer / File(s) Summary
Tool approval and grouping
aichat/approval.go, aichat/tool_registry.go, aichat/tools_clicky.go, aichat/tool_group_test.go, aichat/approval_test.go, aichat/tool_registry_test.go
Adds structured tool metadata, tool preferences, grouped tool listings, and approval decisions based on ToolInfo.
Runtime settings and provider credentials
aichat/genkit.go, aichat/models.go, aichat/server.go, aichat/settings.go, aichat/messages.go, aichat/threads.go, aichat/threads_http.go
Adds request-scoped provider credentials, runtime settings enforcement, contextual message prepending, and thread deletion.
Tool and runtime tests
aichat/*_test.go
Covers approval, tool filtering, context prompts, runtime limits, and thread deletion behavior.

Entity package split and dynamic filters

Layer / File(s) Summary
Entity core
entity/*.go
Moves core entity types and command plumbing into package entity, adds tool-group metadata, and routes command output through RenderResult.
Filters and dynamic entities
entity/filter.go, entity/registry.go, entity/sources.go, entity/spec.go, entity/attach.go, entity/dynamic.go, entity/dynamic_spec.go, entity/schema.go, entity/operation.go
Adds named filters, typed attachment, declarative specs, schema parsing, and dynamic entity registration.
Entity tests
entity/*_test.go
Covers entities, filters, tool groups, and dynamic entity registration.

Markdown parsing and rendering

Layer / File(s) Summary
Markdown core
markdown.go, markdown/options.go, markdown/parse.go, markdown/document.go, format.go, formatters/clicky_document.go, formatters/html_react_formatter.go
Adds markdown parsing entrypoints, semantic document rendering, Clicky conversion, and new block helpers for headings, blockquotes, and footnotes.
Markdown tests
markdown/markdown_test.go, markdown/table_dedup_test.go, api/blocks.go, api/blocks_test.go, formatters/html_react_formatter_test.go
Adds coverage for markdown round-tripping, table deduplication, and the new renderable block types.

RPC, OpenAPI, and MCP transport

Layer / File(s) Summary
Executable command adapter
rpc/cobra_command.go, rpc/request_context.go, rpc/types.go, rpc/executor.go
Adds a transport-neutral executable command wrapper and request-context helpers, then updates RPC execution to use them.
OpenAPI metadata and schemas
rpc/openapi.go, rpc/openapi_reflect.go
Adds clicky lookup metadata, reusable filter refs, and schema describer/tag support.
OpenAPI and command tests
rpc/*_test.go
Adds coverage for command wrapping, request context, OpenAPI metadata, schema reflection, and filter lookup refs.
MCP transport
mcp/registry.go, mcp/server.go
Updates MCP registry and server execution to use the transport-neutral command interface.

Lint severity and entity checks

Layer / File(s) Summary
Severity-aware reporting
lint/severity.go, lint/runner.go, lint/summary.go
Adds severity classification, severity-carrying violations, and severity-based summaries.
Analyzer rules
lint/analyzer.go, lint/direct_stdout.go, lint/entity_registration.go, lint/render_builder.go
Expands analyzer coverage to new render types and entity registration patterns, and routes diagnostics through severity-aware reporting.
Lint tests and fixtures
lint/*_test.go, lint/testdata/src/..., e2e_integration_test.go
Updates analyzer tests, fixtures, and integration assertions for the new rules and severity behavior.

Docs, examples, and build tooling

Layer / File(s) Summary
Docs and tooling
.gitignore, CLAUDE.md, CONTRIBUTING.md, Makefile
Adds contributor and architecture docs plus Makefile and ignore updates.
Examples and fixtures
examples/*
Adds example markdown/doc files and example module metadata.
Example app and webapp
examples/enitity/main.go, examples/enitity/main_test.go, examples/enitity/webapp/*, examples/go.mod
Adds the markdown preview endpoint, dev-server workflow, and related UI updates.
CLI input/output tests
cmd/clicky/input_format_test.go, cmd/clicky/output_test.go
Adds CLI tests for input-format detection and output-path resolution.

Possibly related PRs

  • flanksource/clicky#118: Changes the same exec/supervise_loop.go startup promotion path that this PR extends with compilation-aware transitions.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(exec): detect compiler activity during process startup' clearly describes the main feature addition in the changeset, focusing on compiler detection in the startup phase.
Description check ✅ Passed The PR description covers the main changes, objectives, and rationale. It includes a clear 'What', 'Why', and 'Notes' section that aligns with the template structure and provides sufficient context.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pluggable-live-renderer
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/pluggable-live-renderer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Gavel summary

Source Pass Fail Skip Duration
ai 9 0 0 2ms
api 125 0 12 57ms
cache 12 0 0 14ms
clicky 98 0 0 7.0s
entity 34 0 0 3ms
exec 91 0 1 8.8s
flags 20 0 0 654.648µs
formatters 26 0 0 3ms
github.com/flanksource/clicky 28 0 0 14.7s
github.com/flanksource/clicky/ai 10 0 0 40ms
github.com/flanksource/clicky/aichat 64 0 0 -
github.com/flanksource/clicky/api 239 0 0 120ms
github.com/flanksource/clicky/api/tailwind 427 0 0 -
github.com/flanksource/clicky/cmd/clicky 10 0 0 10ms
github.com/flanksource/clicky/docs 19 0 0 -
github.com/flanksource/clicky/entity 32 0 0 -
github.com/flanksource/clicky/examples/enitity 7 0 0 -
github.com/flanksource/clicky/exec 3 0 0 330ms
github.com/flanksource/clicky/flags 32 0 0 30ms
github.com/flanksource/clicky/formatters 55 0 0 -
github.com/flanksource/clicky/formatters/http 38 0 0 -
github.com/flanksource/clicky/formatters/pdf 0 0 1 -
github.com/flanksource/clicky/formatters/tests 202 0 1 50.8s
github.com/flanksource/clicky/internal/gumchoose 2 0 0 -
github.com/flanksource/clicky/lint 9 0 0 -
github.com/flanksource/clicky/markdown 9 0 0 -
github.com/flanksource/clicky/mcp 34 0 0 20ms
github.com/flanksource/clicky/middleware 31 0 0 -
github.com/flanksource/clicky/rpc 198 0 1 20ms
github.com/flanksource/clicky/task 96 0 0 11.8s
lint 8 0 0 8.3s
metrics 7 0 0 2ms
middleware 38 0 0 4ms
task 6 0 0 36ms
tests 11 0 47 7ms
text 78 0 0 305ms
valkey 22 0 0 43ms

Totals: 2130 passed · 0 failed · 63 skipped · 1m42s

View full results

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@exec/compiler.go`:
- Around line 34-50: The detectCompilers function silently ignores all errors
from gopsutil probes (gops.NewProcess, proc.Name, proc.Exe, proc.CmdlineSlice)
by using continue statements and always returns nil error regardless of
inspection failures. Track errors during the iteration through collectPids
results, and when compiler detection has no visibility into the process tree
(all probes fail), return an appropriate error instead of nil so callers can
distinguish between "no compilers found" and "couldn't inspect processes". This
ensures the caller doesn't prematurely advance startup state when inspection
failures occur.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 21e3e8df-63fe-40e8-b4b9-6c478b1c7cd0

📥 Commits

Reviewing files that changed from the base of the PR and between 3e7da2d and 9ba901b.

📒 Files selected for processing (4)
  • exec/compiler.go
  • exec/supervise_loop.go
  • exec/supervised.go
  • exec/supervised_test.go

Comment thread exec/compiler.go
Comment thread api/blocks.go Fixed
@moshloop moshloop force-pushed the feat/pluggable-live-renderer branch from fc1dda6 to 31009b5 Compare June 23, 2026 10:58
@socket-security

socket-security Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedgolang/​github.com/​yuin/​goldmark@​v1.7.139999100100100

View full report

moshloop added a commit that referenced this pull request Jun 23, 2026
… comments

- rpc: pass a non-nil args slice to the executed cobra command so an empty request no longer falls back to os.Args[1:] and leaks the server's --port flag

- aichat: implement missing provider-credential helpers (configuredProviders, credentialMap, resolveProviderKey, firstNonEmptyString) and drop the unused strings import so the module compiles

- lint(e2e): update fixtures/expectations for severity levels — warnings are advisory, only error-severity violations fail the run; summary reports errors/warnings

- api: build footnote HTML via strings.Builder to clear the CodeQL unsafe-quoting alert without changing output

- exec: surface compiler-probe failures when detection has no visibility into the process tree

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 17

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
examples/enitity/main.go (1)

949-969: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

--dev failure can leave the API server running unexpectedly.

The HTTP server starts before startViteDevServer(...). If Vite startup fails, RunE returns early, but the already-started ListenAndServe goroutine is not shut down first.

Suggested ordering fix
- errCh := make(chan error, 1)
- go func() {
-   ...
-   if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
-     errCh <- err
-   }
- }()
-
 if dev {
   vite, err := startViteDevServer(ctx, cmd, host, port, uiPort)
   if err != nil {
     return err
   }
   defer func() { _ = vite.Wait() }()
 }
+
+errCh := make(chan error, 1)
+go func() {
+  ...
+  if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+    errCh <- err
+  }
+}()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/enitity/main.go` around lines 949 - 969, The HTTP server
(httpSrv.ListenAndServe) is started in a goroutine before the Vite dev server is
initialized, so if startViteDevServer fails and returns an error, the RunE
function exits early while the HTTP server goroutine continues running. To fix
this, reorder the code so that the dev mode check and Vite server startup happen
before the HTTP server goroutine is launched. This way, if Vite initialization
fails, the HTTP server is never started in the first place, preventing the
server from running unexpectedly after an early return.
rpc/openapi.go (1)

325-332: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Propagate the resolved operation path before OpenAPI conversion

When op.Path is empty, you compute path for routing but still pass an op with empty Path into convertOperationToOpenAPI. Downstream, filterLookupMeta emits x-clicky-lookup.url from op.Path, so lookup URLs can be blank even though the route exists.

Suggested change
 		for _, op := range operations {
 			method := strings.ToLower(op.Method)
 			if method == "" {
 				method = "post"
 			}
+			if op.Path == "" {
+				op.Path = path
+			}

 			openAPIPath[method] = g.convertOperationToOpenAPI(op)
 		}

Also applies to: 486-489

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rpc/openapi.go` around lines 325 - 332, The operation object being passed to
convertOperationToOpenAPI has an empty Path field, which causes downstream
functions like filterLookupMeta to generate blank lookup URLs. Before calling
convertOperationToOpenAPI on the op object within the loop that iterates over
operations, update the op.Path field with the computed path value that is
determined when op.Path is empty, ensuring that the resolved path is propagated
through the OpenAPI conversion process.
🧹 Nitpick comments (13)
api/blocks.go (1)

61-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the api.Text builder path instead of a struct literal.

Line 61 builds Text with a struct literal; switch to the builder-style construction used by the project conventions.

As per coding guidelines, "Build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than api.Text{...} struct literals or Children: slice literals."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/blocks.go` at line 61, The return statement on line 61 constructs Text
using a struct literal with Content and Style fields. Replace this struct
literal construction Text{Content: h.Content.String(), Style: "font-bold"} with
the builder-style pattern by using either clicky.Text() or api.Text{}.Append()
chaining methods, ensuring the same Content value (h.Content.String()) and Style
value ("font-bold") are properly set through the builder methods instead of
direct struct initialization.

Source: Coding guidelines

aichat/threads_http.go (1)

16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Register this endpoint through entity/RPC surfaces instead of raw ServeMux.

Line 16 adds another direct mux.HandleFunc route, which bypasses the generated CLI/REST/MCP pipeline used elsewhere.

As per coding guidelines, "Do not directly register net/http handlers via http.HandleFunc, http.Handle, or (*http.ServeMux).HandleFunc/.Handle" and "Prefer a command + filter struct ... rather than a raw mux.HandleFunc." Based on learnings, register operations via clicky.NewEntity(...).Register() so surfaces are generated consistently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aichat/threads_http.go` at line 16, Remove the direct mux.HandleFunc
registration for the DELETE endpoint in the handleDeleteThread handler setup.
Instead, register this operation through the entity/RPC surface pattern by using
clicky.NewEntity(...).Register() to ensure the endpoint is consistently exposed
across CLI/REST/MCP pipelines. This aligns with the coding guidelines that
require operations to be registered through command and filter structs rather
than raw http.ServeMux handlers.

Sources: Coding guidelines, Learnings

entity/dynamic.go (1)

175-179: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Build PrettyRow cells with the approved text builders.

PrettyRow currently constructs cells with api.Text{...} literals. Please use clicky.Text(...) or api.Text{}.Append(...) for consistency with clicky render-builder rules.

As per coding guidelines, build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than struct literals. Based on learnings, clicky lint ./... enforces these API-usage rules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entity/dynamic.go` around lines 175 - 179, In the dynamicItem.PrettyRow
method, replace the api.Text struct literal construction with the approved text
builders. Instead of using api.Text{Content: toStringValue(v)} when assigning to
out[k], use either clicky.Text(...) or api.Text{}.Append(...) to build the text
object. This ensures consistency with clicky render-builder rules and passes the
linting requirements enforced by clicky lint.

Sources: Coding guidelines, Learnings

lint/summary.go (1)

85-93: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use approved text builders in lint summary render nodes.

These changed render branches still construct output with api.Text{...} literals. Please switch to clicky.Text(...) or api.Text{}.Append(...) to match the repository render-builder contract.

As per coding guidelines, build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than struct literals. Based on learnings, clicky lint ./... enforces these API-usage rules.

Also applies to: 167-176

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lint/summary.go` around lines 85 - 93, Replace all direct api.Text struct
literal constructions with the approved text builder functions. In the render
branches that return api.Text objects (including the ones that construct text
with "text-red-600", "text-green-600", and "text-yellow-600" styles), switch
from using api.Text{Content: ..., Style: ...} syntax to using either
clicky.Text(...) or api.Text{}.Append(...) chaining methods. This change should
be applied to all occurrences in the file, including both the section at lines
85-93 and the additional section at lines 167-176 mentioned in the comment.

Sources: Coding guidelines, Learnings

entity/attach_test.go (1)

56-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use render builders for api.Text test fixtures.

The StaticOptions fixture currently uses api.Text{...} literals. Please switch to clicky.Text(...) or api.Text{}.Append(...) so tests follow the same render-construction contract as production code.

As per coding guidelines, build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than struct literals. Based on learnings, clicky lint ./... enforces these API-usage rules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entity/attach_test.go` around lines 56 - 59, The RegisterFilter call in the
StaticOptions is using api.Text struct literals (api.Text{Content: "..."})
instead of render builders. Replace these struct literals with builder methods
by using either clicky.Text(...) for creating the text objects or
api.Text{}.Append(...) for chaining. Update the map values in the StaticOptions
call to use the appropriate builder pattern instead of direct struct
initialization to align with the coding guidelines and production code
contracts.

Sources: Coding guidelines, Learnings

entity/filter_test.go (1)

39-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use supported api.Text builders in fixtures instead of struct literals.

Please replace these api.Text{Content: ...} values with clicky.Text(...) or api.Text{}.Append(...) to keep test code aligned with renderer API rules.

As per coding guidelines, “Build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than api.Text{...} struct literals.” Based on learnings, “Use the clicky lint ./... bundled analyzer to enforce API-usage rules when building clicky render primitives.”

Also applies to: 75-75, 119-119

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entity/filter_test.go` around lines 39 - 42, The test fixture uses api.Text
struct literals (api.Text{Content: "..."}) which violates the coding guidelines
for building render primitives. Replace all instances of api.Text{Content:
"..."} struct literals in the options map (at lines 40-41) and other locations
(also at lines 75 and 119) with the proper builder methods using either
clicky.Text(...) or api.Text{}.Append(...) to maintain consistency with the
renderer API rules and pass the clicky lint analyzer checks.

Sources: Coding guidelines, Learnings

entity/dynamic_test.go (1)

61-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace api.Text{Content: ...} literals with supported text builders.

Use clicky.Text(...) or api.Text{}.Append(...) for these fixture values to match the render-builder contract and avoid lint drift.

As per coding guidelines, “Build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than api.Text{...} struct literals.” Based on learnings, “Use the clicky lint ./... bundled analyzer to enforce API-usage rules when building clicky render primitives.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entity/dynamic_test.go` around lines 61 - 64, Replace the api.Text{Content:
...} struct literal values in the StaticOptions map for the "open" and "closed"
keys with proper text builders. Instead of using struct literals like
api.Text{Content: "Open"}, use either clicky.Text("Open") or
api.Text{}.Append(...) to build these text values. This aligns with the coding
guidelines that require building api.Text objects through builder methods rather
than direct struct instantiation, ensuring consistency with the render-builder
contract.

Sources: Coding guidelines, Learnings

entity/sources.go (1)

175-175: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use clicky text builders instead of api.Text struct literals.

Line 175 and Line 231 construct labels with api.Text{Content: ...}. Please switch to clicky.Text(...) or api.Text{}.Append(...) to align with render-builder conventions.

As per coding guidelines, "Build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than api.Text{...} struct literals or Children: slice literals".

Also applies to: 231-231

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entity/sources.go` at line 175, Replace the api.Text struct literal syntax
api.Text{Content: item.GetName()} on line 175 and the similar pattern on line
231 with the builder method pattern using either clicky.Text(...) function or
api.Text{}.Append(...) chaining method. Update both occurrences to use these
builder approaches instead of struct literal constructors to align with the
render-builder conventions.

Source: Coding guidelines

entity/spec.go (1)

49-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid api.Text{...} literals in static filter option conversion.

Line 51 should use a text builder (clicky.Text(...) or api.Text{}.Append(...)) instead of direct struct literal construction.

As per coding guidelines, "Build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than api.Text{...} struct literals or Children: slice literals".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entity/spec.go` around lines 49 - 52, In the loop that iterates over
s.Source.Options and builds the options map, replace the direct api.Text struct
literal api.Text{Content: label} with the appropriate text builder function.
Instead of constructing the api.Text object with api.Text{Content: label}, use
either clicky.Text(label) or api.Text{}.Append(label) to conform with the coding
guidelines for building api.Text objects. This change should be applied in the
assignment within the for loop where value and label are being processed.

Source: Coding guidelines

formatters/clicky_document.go (1)

19-21: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Default provider documents to schema version 1.

This fast-path returns provider payloads verbatim; if a provider returns a zero-value document, output becomes version: 0 while the non-provider path defaults to version: 1. Normalizing here keeps the envelope contract stable.

Suggested fix
 func NewClickyDocument(t api.Textable) ClickyDocument {
 	if t == nil {
 		return ClickyDocument{Version: 1, Node: clickyTextNode("")}
 	}
 	if provider, ok := t.(ClickyDocumentProvider); ok {
-		return provider.ClickyDocument()
+		doc := provider.ClickyDocument()
+		if doc.Version == 0 {
+			doc.Version = 1
+		}
+		return doc
 	}
 	return ClickyDocument{Version: 1, Node: convertTextable(t)}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@formatters/clicky_document.go` around lines 19 - 21, The
ClickyDocumentProvider fast-path in the conditional block checks if the type
assertion succeeds and returns the provider.ClickyDocument() result directly
without normalizing the schema version. When a provider returns a zero-value
document, this results in version: 0 instead of the expected default version: 1
that the non-provider path uses. After obtaining the document from
provider.ClickyDocument(), apply the same schema version normalization logic
used in the non-provider path to ensure consistency in the output envelope
contract.
rpc/executor.go (1)

323-332: 🔒 Security & Privacy | 🔵 Trivial

Unbounded io.ReadAll on request body.

Buffering the whole body with io.ReadAll has no size cap, so a large/malicious payload can drive memory pressure. Consider wrapping with http.MaxBytesReader (or enforcing a configured limit) before reading.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rpc/executor.go` around lines 323 - 332, The io.ReadAll call on r.Body has no
size limit, which can cause memory exhaustion from large or malicious payloads.
Wrap r.Body with http.MaxBytesReader before calling io.ReadAll to enforce a
configured maximum size limit. This ensures the request body reading respects a
bounded memory constraint and prevents unbounded buffering.
rpc/openapi_reflect_test.go (1)

8-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a pointer-receiver SchemaDescriber test case

Current coverage only validates value-receiver describers. Add one type with func (*T) JSONSchema() map[string]any and assert SchemaForStruct does not panic and emits the expected schema.

Also applies to: 114-129

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rpc/openapi_reflect_test.go` around lines 8 - 16, Add test coverage for
pointer-receiver SchemaDescriber implementations. Create a new type similar to
envVarLike (which has a value-receiver JSONSchema method) but with a
pointer-receiver func (*T) JSONSchema() map[string]any instead. Then add test
assertions that call SchemaForStruct on this new type to verify it does not
panic and correctly emits the expected schema, ensuring SchemaForStruct properly
handles both value-receiver and pointer-receiver SchemaDescriber
implementations.
rpc/filter_ref_openapi_test.go (1)

47-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use clicky.Text(...) instead of api.Text{...} literal

Replace the struct literal in the static options map with the clicky text builder to match project rendering conventions.

Suggested change
-		Source: entity.StaticOptions(map[string]api.Textable{"u1": api.Text{Content: "Alice"}}),
+		Source: entity.StaticOptions(map[string]api.Textable{"u1": clicky.Text("Alice")}),

As per coding guidelines, “Build api.Text via clicky.Text(...) or api.Text{}.Append(...) chaining rather than api.Text{...} struct literals.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rpc/filter_ref_openapi_test.go` around lines 47 - 51, In the RegisterFilter
call that registers the "ref-users" filter with Label "Owner", replace the
api.Text struct literal in the Source parameter's StaticOptions map with the
clicky.Text builder function. Instead of using api.Text{Content: "Alice"}
directly in the map for the "u1" key, use clicky.Text to construct the text
value according to the project's coding conventions for building api.Text
objects.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@aichat/server.go`:
- Around line 208-218: Move the enforceRuntimeSettings call to execute
immediately after the runtimeSettings check completes and before the runtime
call. Currently s.runtime is called before enforceRuntimeSettings, which causes
provider initialization failures to return 503 status instead of the
deterministic local policy rejections (402/413). Reorder these calls so that
local guardrails are checked first, preventing unnecessary runtime setup and
ensuring proper error precedence.

In `@aichat/settings.go`:
- Around line 44-49: The modelIDForRequest function checks if the trimmed
request model is non-empty on the emptiness check, but returns the untrimmed
req.Model value, which causes downstream failures when the model contains
leading or trailing whitespace. Apply strings.TrimSpace to req.Model before
returning it on the line where req.Model is returned, ensuring consistency
between the emptiness check and the actual value returned to the caller.

In `@aichat/threads_http.go`:
- Around line 82-84: The store.Delete call in the delete handler currently maps
all errors to HTTP 404, which incorrectly hides actual backend failures. Define
or use a typed/sentinel error in the store package to distinguish "not found"
errors from other failures. In the error handling block after store.Delete,
check if the returned error matches the not-found error type and return
http.StatusNotFound only in that case, while returning
http.StatusInternalServerError for all other non-nil errors. This ensures actual
failures are reported correctly to clients.

In `@cmd/clicky/main.go`:
- Around line 1388-1397: The issue is that when outputPattern contains a
wildcard (*), the ReplaceAll call in this code block replaces the asterisk with
only the base filename without appending the format extension. The ext variable
is calculated by calling getOutputExtension(format) but is not used when
handling the wildcard case. To fix this, modify the strings.ReplaceAll call that
handles the wildcard pattern to use base+ext instead of just base, so that the
format-derived extension is included in the final output path.

In `@entity/dynamic_spec.go`:
- Around line 126-130: The validation of DynamicFilter.Options is currently
happening inside a loop during the lookup execution path, which is too late and
should be caught at registration time instead. Move the nil check for df.Options
from within the loop in the current location to the RegisterDynamicEntity
function where filters are being registered, so that invalid configurations are
rejected immediately when the entity is registered rather than causing a panic
during live request processing.

In `@entity/entity.go`:
- Around line 1178-1179: The RenderResult function calls at lines 1178-1179 and
the other locations mentioned (1250-1251, 1337-1338, 1383-1384) are ignoring
errors returned by RenderResult using the blank identifier. Instead of
discarding the error, capture the return value from RenderResult and check if it
is non-nil; if an error occurs during rendering, return that error instead of
returning nil. This ensures that rendering failures are properly propagated and
the command does not exit successfully when output rendering fails.

In `@entity/schema.go`:
- Around line 103-108: The code currently allows multiple properties to be
marked with IsID or IsName by silently overwriting the previous selection when
assigning to ps.IDKey and ps.NameKey. Add validation checks before each
assignment to detect if ps.IDKey or ps.NameKey has already been set by a
previous property. If either has been set and you're attempting to set it again,
return a validation error instead of allowing the overwrite. This will ensure
schemas with duplicate ID or name markers are rejected rather than silently
accepted and resolved by iteration order.
- Around line 85-99: The variable `p` retrieved from `doc.Properties[name]` can
be nil when a property is explicitly null, but the code does not validate this
before dereferencing its fields (such as `p.Type`, `p.Format`, `p.Label`,
`p.PrettyFmt`, `p.Short`, and `p.Filter`). Add a nil check immediately after the
assignment to `p` and before constructing the schemaField. If `p` is nil, return
an appropriate schema-validation error to handle the case gracefully instead of
allowing a panic to occur when accessing nil pointer fields.

In `@examples/enitity/main.go`:
- Line 901: The markdown-preview handler is being registered directly via
mux.HandleFunc at line 901, which bypasses the entity-first routing model and
prevents auto-generation of CLI/REST/MCP/OpenAPI integration. Remove the direct
mux.HandleFunc call for serveMarkdownPreview and instead define the markdown
preview functionality as a registered entity using the project's fluent builder
pattern. Register this entity with the RPC layer so it will automatically expose
the functionality through the generated REST, CLI, and web UI surfaces rather
than wiring it directly to the HTTP mux.
- Around line 1121-1139: Invalid format values passed by clients are currently
causing internal server errors (500) when clicky.Format() fails, but should
instead return bad request errors (400) since format validation is a client
request issue. After normalizing the format using
normalizeMarkdownPreviewFormat(), validate that it is a supported format before
attempting to use it in clicky.Format() or serveMarkdownPreviewExcel(). Return
http.Error with http.StatusBadRequest when the format is not in the allowlist of
supported formats, rather than allowing clicky.Format() to fail with a 500 error
later.

In `@lint/summary.go`:
- Around line 119-124: The ruleGroup severity is initialized only once when the
group is first created (when checking if key exists in byRule map), but it is
never updated when subsequent violations are appended to that group. When
appending a violation to an existing ruleGroup at the location where
g.violations = append(g.violations, v) is called, add logic to compare the
incoming violation's severity (v.Severity) with the current group's severity
(g.severity) and update g.severity to the higher/more severe value if the new
violation is more severe than what was previously recorded.

In `@markdown/document.go`:
- Around line 182-194: The href and src attributes in the "link" and "image"
cases accept URLs without validating their schemes, allowing dangerous schemes
like javascript: to be included in the HTML output, creating an XSS
vulnerability. Before constructing the HTML attributes in both the "link" case
(using n.Href) and the "image" case (using n.Href), validate that the URL starts
with a safe scheme such as http, https, or mailto. If the URL scheme is not in a
whitelist of safe schemes, either omit the href/src attribute entirely or
replace it with a safe default to prevent the XSS vector from being executed.
- Around line 669-689: The code generates ClickyColumn names using
slugColumnName() but does not handle cases where multiple headers slug to the
same name, causing duplicate keys in the ClickyRow.Cells map and silent data
loss. To fix this, track already-used column names in a map as you populate the
columns slice, and when a name collision is detected, append the index or
another unique suffix to slugColumnName() result to ensure each column has a
distinct name. This ensures that when populating clickyRow.Cells in the loop
over rows, each cell is stored with its correct corresponding column name
without overwriting previous values.

In `@markdown/options.go`:
- Around line 17-25: The defaultOptions() function currently sets PreserveHTML
to true, which is an unsafe default that allows raw HTML to pass through
unfiltered and creates XSS exposure. Change the PreserveHTML field in the
defaultOptions() function from true to false to use a safe default that prevents
raw HTML from being preserved by default.

In `@rpc/cobra_command.go`:
- Around line 80-87: The cobra.Command initialization for execCmd does not
silence usage and error output, causing errors to be reported twice - once
through cobra's automatic error handling and once through the returned error.
Add SilenceUsage and SilenceErrors fields set to true in the execCmd struct
initialization to prevent cobra from automatically printing errors and usage
information to stderr, allowing the error to be handled only through the
returned cmdErr value.

In `@rpc/executor.go`:
- Line 356: The Content-Type header check using strict equality comparison with
"application/json" will not match valid values that include additional
parameters such as charset (e.g., "application/json; charset=utf-8"), causing
JSON bodies with these headers to be silently ignored. Replace the strict
equality check on r.Header.Get("Content-Type") == "application/json" with a more
robust approach that matches the media type prefix regardless of parameters. You
can either use strings.HasPrefix to check if the header value starts with
"application/json", or use mime.ParseMediaType to properly parse the header and
extract only the media type portion before comparison.

In `@rpc/request_context.go`:
- Around line 21-23: The RequestFromContext function currently returns (nil,
true) when a typed-nil *http.Request is stored in the context, which violates
the helper's contract and can cause downstream errors when callers trust the ok
value. After the type assertion in RequestFromContext, add a check to verify
that r is not nil; if r is nil despite ok being true, set ok to false before
returning to ensure the function correctly indicates when no valid request is
available.

---

Outside diff comments:
In `@examples/enitity/main.go`:
- Around line 949-969: The HTTP server (httpSrv.ListenAndServe) is started in a
goroutine before the Vite dev server is initialized, so if startViteDevServer
fails and returns an error, the RunE function exits early while the HTTP server
goroutine continues running. To fix this, reorder the code so that the dev mode
check and Vite server startup happen before the HTTP server goroutine is
launched. This way, if Vite initialization fails, the HTTP server is never
started in the first place, preventing the server from running unexpectedly
after an early return.

In `@rpc/openapi.go`:
- Around line 325-332: The operation object being passed to
convertOperationToOpenAPI has an empty Path field, which causes downstream
functions like filterLookupMeta to generate blank lookup URLs. Before calling
convertOperationToOpenAPI on the op object within the loop that iterates over
operations, update the op.Path field with the computed path value that is
determined when op.Path is empty, ensuring that the resolved path is propagated
through the OpenAPI conversion process.

---

Nitpick comments:
In `@aichat/threads_http.go`:
- Line 16: Remove the direct mux.HandleFunc registration for the DELETE endpoint
in the handleDeleteThread handler setup. Instead, register this operation
through the entity/RPC surface pattern by using clicky.NewEntity(...).Register()
to ensure the endpoint is consistently exposed across CLI/REST/MCP pipelines.
This aligns with the coding guidelines that require operations to be registered
through command and filter structs rather than raw http.ServeMux handlers.

In `@api/blocks.go`:
- Line 61: The return statement on line 61 constructs Text using a struct
literal with Content and Style fields. Replace this struct literal construction
Text{Content: h.Content.String(), Style: "font-bold"} with the builder-style
pattern by using either clicky.Text() or api.Text{}.Append() chaining methods,
ensuring the same Content value (h.Content.String()) and Style value
("font-bold") are properly set through the builder methods instead of direct
struct initialization.

In `@entity/attach_test.go`:
- Around line 56-59: The RegisterFilter call in the StaticOptions is using
api.Text struct literals (api.Text{Content: "..."}) instead of render builders.
Replace these struct literals with builder methods by using either
clicky.Text(...) for creating the text objects or api.Text{}.Append(...) for
chaining. Update the map values in the StaticOptions call to use the appropriate
builder pattern instead of direct struct initialization to align with the coding
guidelines and production code contracts.

In `@entity/dynamic_test.go`:
- Around line 61-64: Replace the api.Text{Content: ...} struct literal values in
the StaticOptions map for the "open" and "closed" keys with proper text
builders. Instead of using struct literals like api.Text{Content: "Open"}, use
either clicky.Text("Open") or api.Text{}.Append(...) to build these text values.
This aligns with the coding guidelines that require building api.Text objects
through builder methods rather than direct struct instantiation, ensuring
consistency with the render-builder contract.

In `@entity/dynamic.go`:
- Around line 175-179: In the dynamicItem.PrettyRow method, replace the api.Text
struct literal construction with the approved text builders. Instead of using
api.Text{Content: toStringValue(v)} when assigning to out[k], use either
clicky.Text(...) or api.Text{}.Append(...) to build the text object. This
ensures consistency with clicky render-builder rules and passes the linting
requirements enforced by clicky lint.

In `@entity/filter_test.go`:
- Around line 39-42: The test fixture uses api.Text struct literals
(api.Text{Content: "..."}) which violates the coding guidelines for building
render primitives. Replace all instances of api.Text{Content: "..."} struct
literals in the options map (at lines 40-41) and other locations (also at lines
75 and 119) with the proper builder methods using either clicky.Text(...) or
api.Text{}.Append(...) to maintain consistency with the renderer API rules and
pass the clicky lint analyzer checks.

In `@entity/sources.go`:
- Line 175: Replace the api.Text struct literal syntax api.Text{Content:
item.GetName()} on line 175 and the similar pattern on line 231 with the builder
method pattern using either clicky.Text(...) function or api.Text{}.Append(...)
chaining method. Update both occurrences to use these builder approaches instead
of struct literal constructors to align with the render-builder conventions.

In `@entity/spec.go`:
- Around line 49-52: In the loop that iterates over s.Source.Options and builds
the options map, replace the direct api.Text struct literal api.Text{Content:
label} with the appropriate text builder function. Instead of constructing the
api.Text object with api.Text{Content: label}, use either clicky.Text(label) or
api.Text{}.Append(label) to conform with the coding guidelines for building
api.Text objects. This change should be applied in the assignment within the for
loop where value and label are being processed.

In `@formatters/clicky_document.go`:
- Around line 19-21: The ClickyDocumentProvider fast-path in the conditional
block checks if the type assertion succeeds and returns the
provider.ClickyDocument() result directly without normalizing the schema
version. When a provider returns a zero-value document, this results in version:
0 instead of the expected default version: 1 that the non-provider path uses.
After obtaining the document from provider.ClickyDocument(), apply the same
schema version normalization logic used in the non-provider path to ensure
consistency in the output envelope contract.

In `@lint/summary.go`:
- Around line 85-93: Replace all direct api.Text struct literal constructions
with the approved text builder functions. In the render branches that return
api.Text objects (including the ones that construct text with "text-red-600",
"text-green-600", and "text-yellow-600" styles), switch from using
api.Text{Content: ..., Style: ...} syntax to using either clicky.Text(...) or
api.Text{}.Append(...) chaining methods. This change should be applied to all
occurrences in the file, including both the section at lines 85-93 and the
additional section at lines 167-176 mentioned in the comment.

In `@rpc/executor.go`:
- Around line 323-332: The io.ReadAll call on r.Body has no size limit, which
can cause memory exhaustion from large or malicious payloads. Wrap r.Body with
http.MaxBytesReader before calling io.ReadAll to enforce a configured maximum
size limit. This ensures the request body reading respects a bounded memory
constraint and prevents unbounded buffering.

In `@rpc/filter_ref_openapi_test.go`:
- Around line 47-51: In the RegisterFilter call that registers the "ref-users"
filter with Label "Owner", replace the api.Text struct literal in the Source
parameter's StaticOptions map with the clicky.Text builder function. Instead of
using api.Text{Content: "Alice"} directly in the map for the "u1" key, use
clicky.Text to construct the text value according to the project's coding
conventions for building api.Text objects.

In `@rpc/openapi_reflect_test.go`:
- Around line 8-16: Add test coverage for pointer-receiver SchemaDescriber
implementations. Create a new type similar to envVarLike (which has a
value-receiver JSONSchema method) but with a pointer-receiver func (*T)
JSONSchema() map[string]any instead. Then add test assertions that call
SchemaForStruct on this new type to verify it does not panic and correctly emits
the expected schema, ensuring SchemaForStruct properly handles both
value-receiver and pointer-receiver SchemaDescriber implementations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: df9b9111-1130-4d05-ad7f-1a8085e57543

📥 Commits

Reviewing files that changed from the base of the PR and between 9ba901b and e07aef4.

⛔ Files ignored due to path filters (6)
  • aichat/go.sum is excluded by !**/*.sum
  • examples/enitity/go.sum is excluded by !**/*.sum
  • examples/enitity/webapp/dist/index.html is excluded by !**/dist/**
  • examples/go.sum is excluded by !**/*.sum
  • examples/uber_demo/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (127)
  • .gitignore
  • CLAUDE.md
  • CONTRIBUTING.md
  • Makefile
  • aichat/approval.go
  • aichat/approval_test.go
  • aichat/genkit.go
  • aichat/go.mod
  • aichat/messages.go
  • aichat/messages_test.go
  • aichat/models.go
  • aichat/server.go
  • aichat/settings.go
  • aichat/settings_test.go
  • aichat/threads.go
  • aichat/threads_http.go
  • aichat/tool_group_test.go
  • aichat/tool_registry.go
  • aichat/tool_registry_test.go
  • aichat/tools_clicky.go
  • api/blocks.go
  • api/blocks_test.go
  • args_parser.go
  • cmd/clicky/input_format_test.go
  • cmd/clicky/main.go
  • e2e_integration_test.go
  • entity/annotations.go
  • entity/attach.go
  • entity/attach_test.go
  • entity/builder.go
  • entity/command.go
  • entity/command_test.go
  • entity/doc.go
  • entity/dynamic.go
  • entity/dynamic_spec.go
  • entity/dynamic_test.go
  • entity/entity.go
  • entity/entity_suite_test.go
  • entity/entity_test.go
  • entity/filter.go
  • entity/filter_test.go
  • entity/filters_test.go
  • entity/lookup_response.go
  • entity/multi_filter.go
  • entity/operation.go
  • entity/pagination.go
  • entity/registry.go
  • entity/render.go
  • entity/response_meta.go
  • entity/schema.go
  • entity/searchable_filter_test.go
  • entity/sources.go
  • entity/spec.go
  • entity/sub_command.go
  • entity/sub_command_test.go
  • entity/toolgroup_test.go
  • entity/types.go
  • entity_aliases.go
  • examples/ANSI-FIXTURES.md
  • examples/date-formatting-tests.md
  • examples/enitity/Procfile
  • examples/enitity/README.md
  • examples/enitity/Taskfile.yaml
  • examples/enitity/go.mod
  • examples/enitity/main.go
  • examples/enitity/main_test.go
  • examples/enitity/webapp/package.json
  • examples/enitity/webapp/pnpm-workspace.yaml
  • examples/enitity/webapp/src/App.tsx
  • examples/enitity/webapp/src/MarkdownEditorPage.tsx
  • examples/enitity/webapp/src/main.tsx
  • examples/enitity/webapp/tsconfig.tsbuildinfo
  • examples/enitity/webapp/vite.config.ts
  • examples/go.mod
  • examples/kitchen-sink.md
  • examples/simple-test.md
  • examples/uber_demo/README.md
  • examples/uber_demo/go.mod
  • exec/compiler.go
  • exec/supervise_loop.go
  • exec/supervised.go
  • exec/supervised_test.go
  • format.go
  • formatters/clicky_document.go
  • formatters/html_react_formatter.go
  • formatters/html_react_formatter_test.go
  • go.mod
  • lint/analyzer.go
  • lint/analyzer_test.go
  • lint/direct_stdout.go
  • lint/entity_registration.go
  • lint/render_builder.go
  • lint/runner.go
  • lint/severity.go
  • lint/severity_test.go
  • lint/summary.go
  • lint/summary_test.go
  • lint/testdata/src/bad/bad.go
  • lint/testdata/src/entityreg/bad/bad.go
  • lint/testdata/src/entityreg/good/good.go
  • lint/testdata/src/github.com/flanksource/clicky/api/stub.go
  • lint/testdata/src/github.com/flanksource/clicky/stub.go
  • lint/testdata/src/github.com/spf13/cobra/stub.go
  • lint/testdata/src/good/good.go
  • markdown.go
  • markdown/document.go
  • markdown/markdown_test.go
  • markdown/options.go
  • markdown/parse.go
  • mcp/registry.go
  • mcp/server.go
  • rpc/cobra_command.go
  • rpc/context_datafunc_test.go
  • rpc/converter.go
  • rpc/converter_toolgroup_test.go
  • rpc/executor.go
  • rpc/executor_test.go
  • rpc/filter_ref_openapi_test.go
  • rpc/openapi.go
  • rpc/openapi_reflect.go
  • rpc/openapi_reflect_test.go
  • rpc/openapi_test.go
  • rpc/request_context.go
  • rpc/request_context_test.go
  • rpc/types.go
  • task/render.go
  • task/render_test.go
💤 Files with no reviewable changes (2)
  • args_parser.go
  • examples/go.mod
✅ Files skipped from review due to trivial changes (24)
  • examples/enitity/Procfile
  • examples/enitity/webapp/tsconfig.tsbuildinfo
  • lint/testdata/src/github.com/spf13/cobra/stub.go
  • entity/doc.go
  • entity/filters_test.go
  • rpc/converter_toolgroup_test.go
  • lint/testdata/src/entityreg/good/good.go
  • lint/summary_test.go
  • examples/date-formatting-tests.md
  • examples/kitchen-sink.md
  • aichat/tool_group_test.go
  • CONTRIBUTING.md
  • format.go
  • entity/multi_filter.go
  • examples/enitity/README.md
  • entity/sub_command_test.go
  • entity/types.go
  • exec/supervised.go
  • CLAUDE.md
  • entity/pagination.go
  • examples/uber_demo/README.md
  • lint/testdata/src/good/good.go
  • examples/enitity/webapp/src/main.tsx
  • lint/testdata/src/entityreg/bad/bad.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • exec/compiler.go
  • exec/supervised_test.go
  • exec/supervise_loop.go

Comment thread aichat/server.go
Comment thread aichat/settings.go
Comment thread aichat/threads_http.go
Comment on lines +82 to +84
if err := store.Delete(r.Context(), r.PathValue("id")); err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not map all delete failures to 404.

Line 82 currently treats every store.Delete error as not-found. That masks real backend failures and returns the wrong status to clients. Use a typed/sentinel not-found error for thread stores and return 500 for all non-not-found failures.

Suggested status split
- if err := store.Delete(r.Context(), r.PathValue("id")); err != nil {
- 	http.Error(w, err.Error(), http.StatusNotFound)
- 	return
- }
+ if err := store.Delete(r.Context(), r.PathValue("id")); err != nil {
+ 	if errors.Is(err, ErrThreadNotFound) {
+ 		http.Error(w, err.Error(), http.StatusNotFound)
+ 		return
+ 	}
+ 	http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ 	return
+ }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aichat/threads_http.go` around lines 82 - 84, The store.Delete call in the
delete handler currently maps all errors to HTTP 404, which incorrectly hides
actual backend failures. Define or use a typed/sentinel error in the store
package to distinguish "not found" errors from other failures. In the error
handling block after store.Delete, check if the returned error matches the
not-found error type and return http.StatusNotFound only in that case, while
returning http.StatusInternalServerError for all other non-nil errors. This
ensures actual failures are reported correctly to clients.

Comment thread cmd/clicky/main.go
Comment thread entity/dynamic_spec.go Outdated
Comment thread markdown/document.go
Comment thread markdown/options.go
Comment on lines +17 to +25
func defaultOptions() Options {
return Options{
GFM: true,
Footnotes: true,
Frontmatter: true,
Admonitions: true,
PreserveHTML: true,
SourceSpans: true,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Use a safe default for PreserveHTML to reduce XSS exposure.

Defaulting to PreserveHTML: true passes raw HTML through by default. If caller input is user-controlled, this is an unsafe default for HTML output paths.

Suggested fix
 func defaultOptions() Options {
 	return Options{
 		GFM:          true,
 		Footnotes:    true,
 		Frontmatter:  true,
 		Admonitions:  true,
-		PreserveHTML: true,
+		PreserveHTML: false,
 		SourceSpans:  true,
 	}
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func defaultOptions() Options {
return Options{
GFM: true,
Footnotes: true,
Frontmatter: true,
Admonitions: true,
PreserveHTML: true,
SourceSpans: true,
}
func defaultOptions() Options {
return Options{
GFM: true,
Footnotes: true,
Frontmatter: true,
Admonitions: true,
PreserveHTML: false,
SourceSpans: true,
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@markdown/options.go` around lines 17 - 25, The defaultOptions() function
currently sets PreserveHTML to true, which is an unsafe default that allows raw
HTML to pass through unfiltered and creates XSS exposure. Change the
PreserveHTML field in the defaultOptions() function from true to false to use a
safe default that prevents raw HTML from being preserved by default.

Comment thread rpc/cobra_command.go
Comment thread rpc/executor.go Outdated
Comment thread rpc/request_context.go
Comment on lines +21 to +23
func RequestFromContext(ctx context.Context) (*http.Request, bool) {
r, ok := ctx.Value(requestContextKey{}).(*http.Request)
return r, ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return ok=false when stored request is nil

A typed-nil *http.Request in context currently yields (nil, true). That violates the helper’s contract and can lead to downstream dereferences when callers trust ok.

Suggested change
 func RequestFromContext(ctx context.Context) (*http.Request, bool) {
 	r, ok := ctx.Value(requestContextKey{}).(*http.Request)
-	return r, ok
+	if !ok || r == nil {
+		return nil, false
+	}
+	return r, true
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func RequestFromContext(ctx context.Context) (*http.Request, bool) {
r, ok := ctx.Value(requestContextKey{}).(*http.Request)
return r, ok
func RequestFromContext(ctx context.Context) (*http.Request, bool) {
r, ok := ctx.Value(requestContextKey{}).(*http.Request)
if !ok || r == nil {
return nil, false
}
return r, true
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rpc/request_context.go` around lines 21 - 23, The RequestFromContext function
currently returns (nil, true) when a typed-nil *http.Request is stored in the
context, which violates the helper's contract and can cause downstream errors
when callers trust the ok value. After the type assertion in RequestFromContext,
add a check to verify that r is not nil; if r is nil despite ok being true, set
ok to false before returning to ensure the function correctly indicates when no
valid request is available.

moshloop added a commit that referenced this pull request Jun 23, 2026
… on PR #119

Apply 12 validated correctness/stability findings, with regression tests:

- aichat: trim explicit request model IDs; enforce runtime limits (402/413) before provider runtime init so they aren't masked by a 503

- entity: validate DynamicFilter.Options at registration; propagate RenderResult errors in generated commands; reject null property schemas and duplicate x-clicky-id/x-clicky-name markers

- markdown: deduplicate colliding column names so duplicate header labels don't silently drop cells

- rpc: silence usage/errors on the captured exec command; tolerate Content-Type charset params when parsing JSON bodies

- cmd/clicky: append the format extension to wildcard output paths

- lint: escalate a rule group's severity to the highest of its violations

Deferred items filed as #127 (thread-store sentinel error) and #128 (markdown HTML sanitization).
moshloop added 19 commits June 26, 2026 13:12
Add compiler and linker detection to distinguish compilation phase from startup phase. Introduces StatusCompiling to track when build tools are actively running, preventing premature promotion to StatusRunning. The watchPorts function now accepts a compilationDetector callback and manages three startup states: compiling → starting → running. Compiler activity resets the grace period timer, allowing long builds to complete without timing out. A detected port immediately promotes to running regardless of compilation state.

Refs: compiler detection for improved startup lifecycle management
…authoring guidance

Add a `make docs` target that serves Go package documentation locally using pkgsite, with configurable port (default 8089). This enables developers to browse package docs without publishing.

Enhance entity authoring guidance by adding documentation references to RegisterEntity and NewEntity functions, directing users to the entity package for best practices and examples.

Refactor example app to use RouterAdapter pattern from clicky-ui, consolidating router integration logic and improving separation of concerns. This replaces the previous renderLink prop with a unified adapter that handles link rendering, pathname tracking, and navigation.

Rename clicky_lookup.go to entity_lookup.go for better semantic clarity.

IMPACT: Developers can now easily browse local package documentation. Entity registration functions provide clearer guidance. Example app demonstrates improved router integration pattern.
Stop ignoring markdown files globally to allow committing documentation. Add CLAUDE.md (API guide for Claude Code), CONTRIBUTING.md (development guide), and example test fixtures (ANSI-FIXTURES.md, date-formatting-tests.md, simple-test.md, uber_demo/README.md, enitity/README.md). Also ignore build artifacts (.todos/, todos-bak/, specs/) that should not be committed.
…ped provider credentials

Introduce per-request tool filtering via ToolPreferences (enabled/ask/disabled modes), runtime settings for model defaults and token/cost budgets, and request-scoped provider credentials to support org-owned connection stores.

Key changes:
- ToolPreferences map allows clients to control tool availability per request
- ToolApprovalPolicy provides metadata-aware approval decisions with tool operation details
- RuntimeSettings and RuntimeSettingsProvider enable app-owned defaults and budget enforcement
- ProviderCredentialsProvider allows per-request upstream API keys instead of relying only on environment
- ChatRequest now carries context (serialized + structured) and tool preferences
- Custom tools via ToolDefinition for app-owned operations outside Cobra commands
- Thread deletion support in ThreadStore interface
- Tool registry refactored to track ToolInfo metadata alongside ToolRef for filtering and approval

BREAKING CHANGE: ApprovalPolicy signature unchanged but ToolApprovalPolicy takes precedence; initGenkit now accepts optional ProviderCredential args; ThreadStore.Delete method added to interface; ClickyToolset.DefineTools now wraps DefineRegisteredTools which returns registeredTool structs.
…te, footnotes)

Introduce new Textable types for markdown block-level elements:
- Heading: renders markdown-style section headings (h1-h6)
- Blockquote: renders quoted document blocks
- FootnoteRef: inline reference to footnote definitions
- Footnote: single GFM-style footnote definition
- Footnotes: ordered collection of footnote definitions

Each type implements the Textable interface with String, ANSI, HTML, and Markdown renderers. Helper functions added to format.go for convenient construction. HTML React formatter updated with conversion functions for all new types. Lint analyzer and test data updated to recognize these as helper-backed types.
Introduce comprehensive markdown parsing capabilities using Goldmark with support for:

- Parsing markdown source into structured semantic trees
- Exporting parsed documents as Clicky JSON format
- Support for GitHub Flavored Markdown, footnotes, frontmatter, and admonitions
- Preserving source spans (line numbers) and original markdown snippets
- Converting markdown nodes to Clicky's document format via ClickyDocumentProvider interface

Enhance ClickyDocument to support metadata and add ClickyDocumentProvider interface for rich producers to provide fully structured documents without flattening through PrettyData.

Extend ClickyNode with additional fields: Checked, Attributes, SourceMarkdown, LineStart, LineEnd for better semantic preservation.

Add goldmark v1.7.13 dependency for markdown parsing.

Refs: markdown parsing feature
Add comprehensive test case that validates markdown parsing, roundtrip conversion, and clicky JSON formatting. Includes verification of frontmatter metadata, all major markdown node types (headings, lists, tables, code blocks, etc.), task list state preservation, and table alignment. Also adds helper functions countKind and findNode for traversing and querying the document tree.
…y support

Introduce a new entity package that enables defining filters once and reusing them across multiple entities. Named filters are registered centrally and attached to static entities via the typed Use/As adapter or to dynamic (schema-driven) entities via x-clicky-filter annotations.

Key additions:
- FilterSource abstraction for type-agnostic option resolution (StaticOptions, FuncOptions, EntityOptions)
- NamedFilter registry with RegisterFilter/GetFilter APIs
- attachedFilter adapter to bind named filters to typed ListOpts structs
- DynamicEntityBuilder and DynamicFilter for schema-driven entities
- boundFilter and resolveLookupCore to unify lookup response building
- OpenAPI support: emit filter definitions in components.x-clicky-filters and reference them via x-clicky-lookup.$ref on filter parameters
- GetEntity helper to look up registered entities by name or alias
- entityFilterRefs tracking to map parameter keys to named filter names

This enables cascading filters, shared filter definitions across entity types, and proper OpenAPI documentation of filter relationships without duplicating definitions.
Move all entity-related source files from root directory into a new `entity` package subdirectory. This improves code organization and modularity by grouping related functionality together. Files are renamed to remove redundant prefixes now that they reside in the entity package namespace.
…ubpackage

Reorganize the codebase by moving the entity model, CLI generation, and command registry from the root clicky package to a dedicated entity subpackage. This establishes a clean one-way dependency: entity → clicky-subpackages (api, flags, formatters, task), never the reverse.

The root clicky package now imports entity and re-exports its types via aliases (entity_aliases.go), preserving the public API so callers continue using clicky.Entity, clicky.RegisterEntity, etc. unchanged.

Key changes:
- Rename all package declarations from 'package clicky' to 'package entity'
- Add Icon and Title fields to EntityInfo, DynamicEntitySpec, and CommandOpenAPIMeta for UI surface customization
- Add ToolGroup field to EntityInfo, ActionInfo, and ActionSpec for AI tool-preference grouping
- Introduce context-aware handlers: GetWithContext, CreateWithContext, UpdateWithContext, DeleteWithContext
- Rename actionSpec/bulkActionSpec to ActionSpec/BulkActionSpec (exported)
- Add WithToolGroup() builder methods for Entity and Action
- Extract render/parse hooks (RenderResult, ParseArgs) to render.go for host-owned globals injection
- Add operation.go with RPCOperation, ClickyOperationMeta, and related types
- Add types.go with ExecutableCommand interface and ExecuteOptions
- Update all internal imports to use entity package types directly
- Add PrettyRow() to dynamicItem for table formatter support
- Simplify command result rendering to use RenderResult hook

BREAKING CHANGE: Internal package reorganization; public API preserved via root clicky re-exports.
…mmand adapter

Move command execution logic from CommandExecutor into a new CobraExecutableCommand adapter that implements entity.ExecutableCommand. This decouples the RPC layer from cobra specifics and enables reuse across different command frameworks.

Key changes:
- New cobra_command.go with CobraExecutableCommand wrapper and captureGlobal function
- Consolidate global stdout/stderr capture into globalCaptureMu (replaces per-executor mutex)
- Move command state reset and flag handling into Execute method
- Update converter to wrap cobra.Command in NewCobraExecutableCommand
- Add support for Icon and Title metadata in ClickyOperationMeta and ClickySurface
- Add ToolGroup propagation to RPCOperation.Group and ClickyOperationMeta.Group
- Extract request context handling into request_context.go for nested JSON body preservation
- Move type definitions to entity package aliases in types.go
- Update all tests to use NewCobraExecutableCommand wrapper

BREAKING CHANGE: RPCOperation.Command is now entity.ExecutableCommand instead of *cobra.Command. Callers must wrap cobra commands with NewCobraExecutableCommand or use the new interface methods (Path, Name, RootName, Runnable, Hidden, IsBoolFlag, Execute).
Add a new markdown editor page to the example application that allows users to edit markdown and preview it through multiple formats (JSON, HTML, CSV, Excel, Markdown). Implements a new `/api/examples/markdown-preview` endpoint that parses markdown and renders it in the requested format. Includes comprehensive test coverage for different preview formats and Excel export functionality.

The markdown preview feature integrates with the Clicky formatting stack used by the CLI and executor API, providing a unified formatting experience across the application.
Introduce tool grouping functionality that allows tools to be organized into logical groups in the preferences UI. When a tool belongs to a group, the group's preference governs all member tools, and individual members are hidden from the UI.

Changes:
- Add Group field to ToolInfo and ToolDefinition structs
- Implement effectivePreference() to resolve tool mode considering group membership
- Add ToolEntry struct and ListToolEntries() to collapse grouped tools for UI presentation
- Update toolsForRequest() and shouldRequireApproval() to use group-aware preference resolution
- Add comprehensive test coverage for tool grouping behavior
- Fix cmd.Hidden property access in toolableOperation()
- Update go.mod/go.sum with goldmark v1.7.16 dependency
Introduce error and warning severity levels to distinguish structural violations from style preferences. Error-severity violations fail the lint run; warnings are advisory.

Add three new checks:
- checkManualCobraCommand: flags hand-rolled cobra.Command with Run/RunE handlers that should be registered entities
- checkHTTPHandlerRegistration: flags direct net/http handler registration that should use the entity/rpc layer
- checkEntityTableProvider: warns when registered entities lack api.TableProvider implementation for table rendering

Refactor all existing diagnostics to use the new report() function with explicit severity. Update Result to track error vs warning counts separately, with HasErrors() (not HasIssues()) driving exit status. Update summary views to display severity labels and color-code by error/warning/success.

Breaking change: Violation struct now includes Severity field; Result.Success now depends on HasErrors() rather than HasIssues().
…aml, and text

Add --input-format flag to enable parsing and rendering of markdown, JSON, YAML, and plain text files without requiring a schema. Supports auto-detection of input format based on file extension or content analysis.

Key changes:
- New renderInput() function handles schema-less input processing
- Auto-detection logic for markdown, JSON, YAML, and text formats
- Input format normalization and validation
- Output path resolution for multiple input files
- Stdin input detection for automatic format selection
- Remove parser provenance fields (sourceMarkdown, lineStart, lineEnd) from clicky-json output to reduce noise
- Update markdown document generation to include frontmatter in output
- Add comprehensive test coverage for input format handling

BREAKING CHANGE: Removed SourceMarkdown field from markdown Node and Document structures; removed PreserveSource option from markdown parser. Parser provenance fields are no longer included in clicky-json output.
…ky-ui development

Add --dev flag to serve-ui command that launches the Vite dev server alongside the Go API, enabling live development against a local clicky-ui checkout without rebuilding the embedded bundle.

Changes include:
- New serve-ui --dev flag and --ui-port option
- startViteDevServer() function to launch pnpm dev with proper process group handling
- webappDevDir() helper to locate webapp/ from source checkout
- Updated Vite config to exclude @flanksource/clicky-ui from prebundling and allow filesystem access to sibling clicky-ui dist
- Added react-grab dev dependency for development tooling
- New task dev and webapp:dev in Taskfile.yaml
- Procfile for convenient local development
- Comprehensive documentation in README

Requires source checkout with pnpm installed and `pnpm install` run in webapp/.
… unify command execution

Move the entity/operation registration model to a dedicated entity/ subpackage to reduce circular dependencies and improve modularity. Add entity_aliases.go to re-export the public API from clicky root, maintaining backward compatibility.

Introduce ExecutableCommand interface in entity package to abstract cobra.Command execution, enabling transport-neutral invocation (CLI, REST, MCP) with unified argument/flag handling and output capture. Simplify MCP server tool execution by delegating to this interface instead of manual flag manipulation and stdout/stderr redirection.

Enhance OpenAPI schema generation with SchemaDescriber interface for types that need custom JSON-schema representation (e.g., commons-db EnvVar), and add clicky:"..." struct tags to control form widget rendering (component, title, description, format, source, property, order, required). Merge vendor extensions (x-clicky-*) into marshalled schema.

Fix surface key generation to use singular entity name (no pluralization) so clicky-ui row-click routes resolve correctly against /api/v1/<entity> paths.

Improve task renderer's line-wrapping accounting: count physical terminal rows (accounting for soft-wrap) instead of logical newlines, preventing frame smear when output exceeds terminal width.

Update .gitignore to exclude examples/src and allow cmd/clicky/ and its test files. Add aichat and examples/enitity to GO_MODULES. Refactor Makefile to separate tidy and fmt targets.

Update CLAUDE.md and CONTRIBUTING.md to document the new render-code rules (errors vs warnings) and entity-registration linter behavior.
… comments

- rpc: pass a non-nil args slice to the executed cobra command so an empty request no longer falls back to os.Args[1:] and leaks the server's --port flag

- aichat: implement missing provider-credential helpers (configuredProviders, credentialMap, resolveProviderKey, firstNonEmptyString) and drop the unused strings import so the module compiles

- lint(e2e): update fixtures/expectations for severity levels — warnings are advisory, only error-severity violations fail the run; summary reports errors/warnings

- api: build footnote HTML via strings.Builder to clear the CodeQL unsafe-quoting alert without changing output

- exec: surface compiler-probe failures when detection has no visibility into the process tree
… on PR #119

Apply 12 validated correctness/stability findings, with regression tests:

- aichat: trim explicit request model IDs; enforce runtime limits (402/413) before provider runtime init so they aren't masked by a 503

- entity: validate DynamicFilter.Options at registration; propagate RenderResult errors in generated commands; reject null property schemas and duplicate x-clicky-id/x-clicky-name markers

- markdown: deduplicate colliding column names so duplicate header labels don't silently drop cells

- rpc: silence usage/errors on the captured exec command; tolerate Content-Type charset params when parsing JSON bodies

- cmd/clicky: append the format extension to wildcard output paths

- lint: escalate a rule group's severity to the highest of its violations

Deferred items filed as #127 (thread-store sentinel error) and #128 (markdown HTML sanitization).
Publish nested Go sub-modules (aichat, valkey, etc.) by pushing path-prefixed tags after semantic-release. Updates sub-module dependencies to the released version before tagging to ensure downstream consumers can install them via go get.
@moshloop moshloop force-pushed the feat/pluggable-live-renderer branch from 0836dd7 to fdd53f1 Compare June 26, 2026 10:12
@moshloop moshloop enabled auto-merge (rebase) June 26, 2026 10:14
…g for reader drain

Add a done channel to capturedPTY that signals when the reader goroutine has finished draining the PTY to EOF. This ensures that final output written by the helper process before exit is captured before assertions snapshot the buffer, eliminating a race condition observed on slower CI hosts. Update requireExitWithin to wait for the reader to drain before returning.
@moshloop moshloop force-pushed the feat/pluggable-live-renderer branch from c2bd972 to ddb09f9 Compare June 26, 2026 10:51
@moshloop moshloop merged commit 812891a into main Jun 26, 2026
13 checks passed
@moshloop moshloop deleted the feat/pluggable-live-renderer branch June 26, 2026 10:55
moshloop added a commit that referenced this pull request Jun 26, 2026
… comments

- rpc: pass a non-nil args slice to the executed cobra command so an empty request no longer falls back to os.Args[1:] and leaks the server's --port flag

- aichat: implement missing provider-credential helpers (configuredProviders, credentialMap, resolveProviderKey, firstNonEmptyString) and drop the unused strings import so the module compiles

- lint(e2e): update fixtures/expectations for severity levels — warnings are advisory, only error-severity violations fail the run; summary reports errors/warnings

- api: build footnote HTML via strings.Builder to clear the CodeQL unsafe-quoting alert without changing output

- exec: surface compiler-probe failures when detection has no visibility into the process tree
moshloop added a commit that referenced this pull request Jun 26, 2026
… on PR #119

Apply 12 validated correctness/stability findings, with regression tests:

- aichat: trim explicit request model IDs; enforce runtime limits (402/413) before provider runtime init so they aren't masked by a 503

- entity: validate DynamicFilter.Options at registration; propagate RenderResult errors in generated commands; reject null property schemas and duplicate x-clicky-id/x-clicky-name markers

- markdown: deduplicate colliding column names so duplicate header labels don't silently drop cells

- rpc: silence usage/errors on the captured exec command; tolerate Content-Type charset params when parsing JSON bodies

- cmd/clicky: append the format extension to wildcard output paths

- lint: escalate a rule group's severity to the highest of its violations

Deferred items filed as #127 (thread-store sentinel error) and #128 (markdown HTML sanitization).
flankbot pushed a commit that referenced this pull request Jun 26, 2026
## [1.21.29](v1.21.28...v1.21.29) (2026-06-26)

### ⚠ BREAKING CHANGES

* **cli:** Removed SourceMarkdown field from markdown Node and Document structures; removed PreserveSource option from markdown parser. Parser provenance fields are no longer included in clicky-json output.
* **lint:** Violation struct now includes Severity field; Result.Success now depends on HasErrors() rather than HasIssues().
* **rpc:** RPCOperation.Command is now entity.ExecutableCommand instead of *cobra.Command. Callers must wrap cobra commands with NewCobraExecutableCommand or use the new interface methods (Path, Name, RootName, Runnable, Hidden, IsBoolFlag, Execute).
* **entity:** Internal package reorganization; public API preserved via root clicky re-exports.
* **aichat:** ApprovalPolicy signature unchanged but ToolApprovalPolicy takes precedence; initGenkit now accepts optional ProviderCredential args; ThreadStore.Delete method added to interface; ClickyToolset.DefineTools now wraps DefineRegisteredTools which returns registeredTool structs.

### ♻️ Code Refactoring

* **entity,rpc,mcp,task:** extract entity model to subpackage and unify command execution ([074db76](074db76))
* **entity:** move entity package from root clicky to dedicated subpackage ([4a7a96b](4a7a96b))
* **entity:** reorganize entity-related files into dedicated package ([042e4f6](042e4f6))
* **rpc:** extract cobra command execution to entity.ExecutableCommand adapter ([de23c99](de23c99))

### ✅ Tests

* **markdown:** add kitchen sink roundtrip and clicky JSON test ([0b9045a](0b9045a))
* **prompt_test:** Fix race condition in PTY output capture by waiting for reader drain ([812891a](812891a))

### ✨ Features

* **aichat:** Add tool grouping support for preferences UI ([da7cc53](da7cc53))
* **aichat:** Add tool preferences, runtime settings, and request-scoped provider credentials ([c800642](c800642))
* **api:** add support for markdown block elements (heading, blockquote, footnotes) ([ebbb9ac](ebbb9ac))
* **cli:** add schema-less input format support for markdown, json, yaml, and text ([89e6d71](89e6d71))
* **docs,entity,examples:** Add local docs server and improve entity authoring guidance ([9679a4a](9679a4a))
* **entity:** add reusable named filters with typed and dynamic entity support ([7a830f3](7a830f3))
* **examples:** add markdown editor page with preview API ([c8076ea](c8076ea))
* **examples/entity:** add Vite HMR dev server support for local clicky-ui development ([9912ca1](9912ca1))
* **exec:** detect compiler activity during process startup ([dc6ebb8](dc6ebb8))
* **lint:** add severity levels and entity registration checks ([6c5ce9b](6c5ce9b))
* **markdown:** Add markdown parsing with structured document support ([656e8e4](656e8e4))

### 🐛 Bug Fixes

* **aichat,entity,markdown,rpc,cmd,lint:** address CodeRabbit findings on PR [#119](#119) ([1742312](1742312)), closes [#127](#127) [#128](#128)
* **rpc,aichat,lint,api,exec:** address PR [#119](#119) CI failures and review comments ([e5e0aea](e5e0aea))

### 👷 CI/CD

* **release:** add sub-module release workflow ([e273b40](e273b40))

### 📚 Documentation

* **gitignore:** Remove *.md from gitignore and add documentation files ([71862e0](71862e0))
@flankbot

Copy link
Copy Markdown

🎉 This PR is included in version 1.21.29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants