Skip to content

declick 0.3.0

Choose a tag to compare

@ucsandman ucsandman released this 04 Sep 14:31
· 48 commits to main since this release
  • remove <name> <verb> now resolves the verb before touching disk: exit 2 for an unknown verb, exit 1 for a spec-backed engine (openapi verbs come from the spec, not per-verb files; rebuild with --verbs instead), and --force is required to delete the last desktop recipe (it would otherwise delete the whole adapter silently). The response for the last-verb case carries adapterRemoved: true.
  • --dry-run works on every management command that writes: add, build, accept, import, skill, remove, path --install, desk arm|disarm. It compiles, lints and previews without writing anything, and sets meta.dryRun: true. author, repair and ui have no preview (they drive a live app or a server) and refuse --dry-run with an error, as does add --goal without --recipes.
  • Row projection: --rows <path> unwraps a dotted array inside a response object (meta.rows names the path used, meta.extra carries the sibling fields such as a cursor or total). Without --rows, a verb whose spec says where its rows live (returns.rowsPath) auto-unwraps them when --fields or --limit is passed; describe, manifest and other non-verb payloads are never auto-unwrapped.
  • --fields now takes dotted paths (--fields error.code,items.0.name) resolved per row. A field list that matches nothing on any row is exit 1 naming the available top-level keys; a partial miss is reported in meta.unknownFields instead of failing.
  • openapi verbs carry a compiled verb.returns ({shape: 'array'|'object'|'scalar'|'none', fields, rowsPath?}) read from the first 2xx (or default) JSON response schema, capped at 30 fields with truncated: true. describe --full prints it as a -> line; describe --json includes it on every verb (null when the spec has no response schema). Desktop verbs get a minimal returns: {shape:'text', from:<read alias>} when the recipe declares one.
  • import refuses to silently replace an adapter that already exists under a different source, engine or baseUrl: exit 1 naming what differs (data.diff), unless --force. The whole import is transactional: a mid-import failure rolls back only what that import created, leaving a prior adapter of the same name untouched. add/build preflight the launcher and skill name before writing anything, for the same reason.
  • Manifest validation (declick lint, and every add/build/import) now rejects a source, window, baseUrl, arg name/description, flag name/description, returns.rowsPath/field name, or auth.env entry that spans multiple lines, contains a backtick, starts with #, or exceeds its length bound. This is the rule already applied to verb descriptions, now applied everywhere spec or bundle text reaches an agent.
  • SKILL.md generation is fence-safe: any `` in an embedded description can no longer close the surrounding fenced block. writeSelfSkill no longer overwrites a hand-written `declick` skill in a skill dir; it only writes dirs where that file is absent or already carries the `Generated by declick` marker.
  • Seven new engines, all built in with no new dependency: mcp (stdio and streamable http), web (a real browser over CDP; a miss returns the page's elements, never a screenshot), graphql, postman (postman v2.1 and insomnia v4), har, sqlite (tables and views become list/get/insert/update/delete plus a parameterized query), and cli (compiled from a tool's own --help). Swagger 2.0 and YAML specs compile through the openapi engine. declick engines --source <x> says where a source would land before anything is written; declick add now also takes --host (which captured host is the API) and --url (the endpoint a GraphQL schema file does not carry).
  • New commands: declick commands and declick <cmd> --help (one row: flags, examples, whether it previews) render from the same table that generates the shipped declick skill, so the skill cannot drift from the CLI; declick audit reads the run log newest first; declick desk windows|tree|read|clipboard and declick web tree return the desktop and a web page as data; declick import --example and declick manifest --schema print a valid bundle and the manifest field reference; declick describe gained --grep and --offset; declick doctor separates blocking from warnings and probes each engine's tools.
  • Request flags on the HTTP engines: --header, --base-url, --server, --content-type, --body-file, --output, --retry, --timeout, --verbose and --curl, listed by describe --full. --retry and --timeout now require a value instead of silently falling back to the default.
  • An api key that lives in the query string is masked in --curl and --verbose on live calls, the same as a header one; only the fetch itself sees the real value. --curl on a live multipart request now carries the body and its boundary content type instead of dropping both.
  • The cli engine quotes every argument it hands to a .cmd or .bat tool, not only the ones containing a space: a value with &, |, >, < or ^ used to reach cmd.exe as a second command. Same fix for the mcp client's npx/npm shell path.
  • sqlite: --limit is the output contract's flag, so meta.count is the true row count and meta.truncated says when there is more; a column named like a contract flag (limit, fields, output) is renamed param-<name> and still reads and writes its own column, instead of making the whole table unaddressable.
  • A desktop recipe's read step re-resolves against a fresh tree before reading a property, so a read after a set, type or click reports what the action did instead of the value captured at find time.
  • meta.credentials now records scopedTo and sentTo when a key is released across origins (--base-url or DECLICK_ENV_ALLOW); the refusal on the blocked path no longer names the flag that would skip it.
  • Desktop recipes get a much larger step vocabulary: read-all (every match of a path as rows), wait-for/wait-for-text (poll for an element or text up to a timeout), assert (compare a live value with equals/matches), clipboard get|set, dismiss (Escape), launch (start the app inline, or from manifest.launch when the window is not open), scroll, expand, collapse, select, context (right-click), set (drive a toggle to a state), and optional: true on any step to skip instead of fail when its element is not there. declick desk windows|tree|read|clipboard exposes the same underlying reads as CLI commands.
  • Governance: once DASHCLAW_API_KEY is set, strict is now the default: an unreachable, timed-out, or non-decision guard response is exit 3, not a warn-and-proceed (DECLICK_GUARD=open restores the old fail-open behavior). DASHCLAW_URL has no default endpoint and is required alongside the key. Every envelope carries meta.governance:{enabled,decision,reason}, and every invocation appends a redacted line to ~/.declick/audit.jsonl (DECLICK_AUDIT=off to disable; declick audit reads it). declick ui now requires a per-start X-Declick-Token on every mutating POST.
  • deskclaw companion: declick 0.3 needs deskclaw 0.3.0 or newer for the attributed snapshot lines (value=, toggle=, selected=, expanded=, offscreen=) the new read/assert steps depend on.

Install: npm i -g declick@0.3.0 · npm · declick.dev