3119 Commits

Author SHA1 Message Date
Maxim bd2ccbd0fa refactor(core): extract logAndEmitError helper to deduplicate error handling
Consolidate the repeated console.error + emitError + .catch pattern
into a single private logAndEmitError method on CopilotKitCore. All 4
call sites (setDefaultThrottleMs, subscribeToAgentWithOptions validation,
safeCall reportError, unsupported-keys warning) now go through the helper.
2026-04-17 16:33:09 +02:00
Alem Tuzlak e6045758a4 fix(vscode-extension): HookPreviewPanel dispose race + stale-push token + typed onMessage
- pushBundle now increments a pushToken before awaiting bundleHookSite and
  re-checks it after the await; a second show() or handleFileChange() that
  races past (or a dispose during the await) silently drops the stale
  result instead of posting to a disposed webview. Deterministic
  last-writer-wins even when 'load' and 'reload' interleave.
- onMessage replaces the Record<string, unknown> cast with a discriminated
  union + isWebviewMsg guard. Eliminates four unchecked casts.
- Drop dead currentNonce field; the nonce is only needed when generating
  HTML and lives locally in show().
- Add CSP inline comment explaining the 'style-src unsafe-inline' tradeoff
  (React runtime style injection + CopilotKit transitive CSS-in-JS).
2026-04-17 15:30:47 +02:00
Alem Tuzlak ac8dc78812 feat(vscode-extension): hook preview panel host 2026-04-17 15:27:47 +02:00
Alem Tuzlak 8c8786c707 fix(vscode-extension): bundle error surfacing, ControlsDispatch extraction, mountError to host
- bundle-loader: inline scripts swallow exceptions thrown during execution;
  they fire as window 'error' events instead. Capture that event during the
  insert/remove window and re-throw so executeBundle's caller's try/catch
  actually sees bundle-time failures. Also assert __copilotkit_hookSite is
  set after execution — a malformed bundle now throws 'did not set hookSite'
  instead of stalling at 'Mounting host…'.
- Extract ControlsDispatch: a dedicated component containing the single
  kind-switch over render-props. App.tsx's 6-branch switch with 13 'as never'
  casts collapses to one dispatcher call with two typed casts per branch
  (localized and narrow).
- mountError now reaches the extension host via postMessage instead of only
  setting local state. Panel host (Task 20) can log these.
2026-04-17 15:24:37 +02:00
Alem Tuzlak 07f2423a48 build(vscode-extension): stub node builtins, CSS, and markdown chain for hook-preview bundle
Bundling @copilotkit/react-core for the hook-preview webview transitively
pulls in:
- node-fetch + its builtin deps (crypto, stream, string_decoder, zlib, http, ...)
- tailwind v4 CSS via the chat component styles
- streamdown / hast-util-to-html / decode-named-character-reference which
  statically name-import from JSON modules rolldown can't re-export

Rolldown 1.0.0-rc.16 removed experimental CSS bundling and refuses to load
Node builtins in a browser target. None of these paths are exercised on the
hook-preview runtime (we render user JSX directly; there's no chat UI,
markdown, or server fetch in scope), so we stub them to empty modules at
bundle time via a rolldown plugin.

The stub emits the specific named exports dependents statically import,
keeping rolldown's named-export analysis happy. Extend HOOK_PREVIEW_STUBBED_DEPS
if additional markdown-chain deps surface.
2026-04-17 15:20:52 +02:00
Alem Tuzlak 3d4c4fb4fc feat(vscode-extension): hook-preview webview App, bundle loader, and entry 2026-04-17 15:14:50 +02:00
Alem Tuzlak a796bbc84b fix(vscode-extension): RenderToolControls passes narrowed ActionValues, recombines toolCallId
Previously RenderToolControls passed the full {...values, toolCallId} down to
ActionControls and spread the onChange result back over values. If ActionControls
ever added a toolCallId field, the spreads would collide. Explicitly separate
the action-shape values from toolCallId and recombine only at the nested
onChange boundary.
2026-04-17 15:07:34 +02:00
Alem Tuzlak 5839f3871f feat(vscode-extension): per-hook controls components 2026-04-17 15:04:03 +02:00
Alem Tuzlak c2e00fb1be refactor(vscode-extension): flatten CapturedRegistry + widen harness error boundary + waitFor test
- CapturedRegistry: drop the misleading v1.actions field. Both V1
  useCopilotAction and V2 useRenderTool register into the same internal V2
  registry; expose it directly as renderToolCalls. Keep coAgentStateRenders
  and chatComponents (those are genuine V1 state) at the top level too.
  Downstream consumers (Task 19+) will read renderToolCalls for any
  action-shaped hook.
- Harness: widen HarnessBoundary to also cover RegistryReader so a reader
  crash routes through onMountError instead of bubbling to React's default
  handler. A reader crash should block capture publishing, not leak.
- capture.test.tsx: replace the 20ms fixed setTimeout wait with testing-
  library waitFor. Polls for the final capture result until the action is
  present; robust on slow CI.
2026-04-17 14:59:20 +02:00
Alem Tuzlak b35413332f feat(vscode-extension): harness, registry reader, and capture flow 2026-04-17 14:54:34 +02:00
Alem Tuzlak 2cb31be9ab chore(vscode-extension): add @copilotkit/react-core as devDependency 2026-04-17 14:48:46 +02:00
Alem Tuzlak c9122b9101 feat(vscode-extension): fetch interceptor with disposer and double-install guard
- installFetchInterceptor now returns an uninstall function, so callers
  (tests, harness teardown) have an explicit restore path rather than
  racing against module-scoped mutation.
- Guard against stacked wrappers on double-install (relevant under React
  StrictMode and HMR remounts): uses a Symbol tag so the second call is
  a no-op and its disposer doesn't unwind the first.
- 4 tests: noop prefix match, passthrough, disposer restores original,
  double-install is a no-op.
2026-04-17 14:43:23 +02:00
Alem Tuzlak 9f8c440363 feat(vscode-extension): webview fetch interceptor for dummy runtime URL 2026-04-17 14:41:04 +02:00
Alem Tuzlak c27a5bd71d refactor(vscode-extension): clean up ArrayField seed logic + BooleanField toggle-off test
- ArrayField.add(): drop dead '?? null' fallback — defaultForField is total
  for required fields, and we force required:true on the seed clone. Inline
  comment explains the two separate uses of field.items (seed vs. render).
- primitive-fields.test.tsx: cover BooleanField checked→unchecked transition.
2026-04-17 14:37:38 +02:00
Alem Tuzlak dcd21e0ec1 refactor(vscode-extension): harden HookControlsStore.load + add robustness tests
- load() now rejects non-object / array / null values from the Memento
  (protects against hand-edited workspaceState containing junk) and returns
  undefined in those cases.
- JSDoc on the class documents the caller's path-normalization contract.
- Adds 4 tests: reset on a non-existent key (no-op), workspace-root scoping
  so two roots don't collide, save overwrites (does not merge), and the new
  load-rejects-scalar-junk defensive branch.
2026-04-17 14:37:33 +02:00
Alem Tuzlak abe27a5a45 refactor(vscode-extension): adapter cleanup and coverage
- human-in-the-loop: inline the body (8 lines) instead of the double-cast
  alias. Self-contained and avoids the 'as unknown as Adapter<K>' gymnastics.
- invokeRender: add JSDoc explaining why the ADAPTERS[kind] as Adapter<K>
  cast is runtime-sound despite being unsound at the type level.
- Tests: add coverage for render-tool (args → parameters rename, toolCallId),
  human-in-the-loop (matches action shape, status-gated result), custom-messages,
  activity-message, and the no-render no-op path (9 tests total).
2026-04-17 14:35:43 +02:00
Alem Tuzlak 705ccfa688 refactor(vscode-extension): schema converter cleanup
- v1-params: omit description field when undefined (cleaner output object);
  recursion on [] suffix now naturally handles nested arrays like string[][];
  add test for both.
- json-schema: JSDoc on JSONSchemaNode documenting MVP scope (no $ref, tuple
  items, allOf/anyOf/oneOf); add tests for integer type and array without items.
- normalize: treat empty-enum as unconstrained instead of rejecting every
  string (prevents a required field with enum:[] getting stuck); add comments
  on the shallow array/object match; add tests for array/object/raw-json
  defaults and the empty-enum path.
2026-04-17 14:34:22 +02:00
Maxim 5b5ecde69a Merge branch 'main' into fix/inspector-state-on-direct-setState 2026-04-17 14:31:32 +02:00
Alem Tuzlak 07c46ebe53 feat(vscode-extension): Memento-backed controls persistence 2026-04-17 14:26:21 +02:00
Alem Tuzlak d7b4b0d649 feat(vscode-extension): hook adapters for every render-props kind 2026-04-17 14:22:45 +02:00
Alem Tuzlak 6048aa24ab fix(vscode-extension): FormRenderer drops undefined keys instead of leaving them as undefined
When a field emits undefined (e.g. NumberField with an optional field cleared),
previously the merged payload would contain { count: undefined } which
downstream render callbacks would see as a present-but-null property.
Now the key is removed entirely, matching the runtime contract for
'optional field not provided'.

Also adds three tests: nested object change, array add, and the
undefined-drop behavior.
2026-04-17 14:19:04 +02:00
Alem Tuzlak fcc6e7082d feat(vscode-extension): FormRenderer and full FieldRenderer dispatcher 2026-04-17 14:16:35 +02:00
Alem Tuzlak 8f4e34cf05 fix(vscode-extension): RawJsonField skips onChange on empty input; adds aria-invalid and error-clear test
- Empty textarea no longer clobbers prior value with {}. Fields representing
  arrays, strings, or null would previously be silently overwritten; now empty
  input means 'no change' and clears any prior parse error.
- Adds aria-invalid={!!error} on the textarea.
- Adds two tests: empty-input path (no onChange, no alert) and error-recovery
  path (alert disappears + onChange fires with the new valid JSON).
- Documents the mount-only local-state contract so future callers aren't
  surprised that external value resets don't propagate.
2026-04-17 14:13:23 +02:00
Alem Tuzlak 64eee33c8f feat(vscode-extension): ObjectField and RawJsonField 2026-04-17 14:10:09 +02:00
Alem Tuzlak f060998a2c feat(vscode-extension): ArrayField with partial FieldRenderer 2026-04-17 14:04:22 +02:00
Alem Tuzlak f055cddfe0 fix(vscode-extension): primitive field a11y + NumberField empty-emits-undefined
- NumberField: emit undefined for empty / non-finite input instead of silently
  coercing to 0, matching the value: number | undefined type. Widens onChange
  to (v: number | undefined) => void. Adds a test for the empty-input path.
- All three fields: drop redundant aria-label (wrapping <label> + htmlFor/id
  provides the accessible name; the aria-label was double-announcing in
  screen readers).
- Set native required attribute on input/select/checkbox so assistive tech
  exposes the constraint alongside the (optional) suffix.
2026-04-17 13:59:42 +02:00
Alem Tuzlak 9609f911bf feat(vscode-extension): primitive form fields (string, number, boolean) 2026-04-17 13:55:56 +02:00
Alem Tuzlak b2341078c9 feat(vscode-extension): schema value defaults and merge logic 2026-04-17 13:52:18 +02:00
Alem Tuzlak 0ec195bf44 refactor(vscode-extension): export JSONSchemaNode and drop as-any cast in standard-schema 2026-04-17 13:50:35 +02:00
Alem Tuzlak a0dedd201d feat(vscode-extension): Standard Schema to FormSchema via zod-to-json-schema 2026-04-17 13:47:57 +02:00
Alem Tuzlak 7f5e960a21 feat(vscode-extension): JSON Schema to FormSchema converter 2026-04-17 13:44:07 +02:00
Alem Tuzlak 95bcf855e9 feat(vscode-extension): v1 parameters to FormSchema converter 2026-04-17 13:40:32 +02:00
Alem Tuzlak 8d95caeadc refactor(vscode-extension): extract shared IIFE bundler helper
Previously bundler.ts (catalog) and hook-bundler.ts duplicated ~80 lines of
rolldown + nodeResolveFallback wiring. Extracts the common shell into
extension/shared/iife-bundler.ts exposing bundleIife() and IifeBundleResult.
bundler.ts and hook-bundler.ts are now thin wrappers supplying their specific
iifeName, externals, globals, and skip prefixes. Catalog and hook bundler
tests still pass unchanged; type aliases (BundleResult, HookBundleResult)
preserved for call-site source compatibility.
2026-04-17 13:28:23 +02:00
Alem Tuzlak 785bcb64b4 refactor(vscode-extension): single-pass scanWorkspace with inherited gitignore stack
- Replaces the separate loadGitignore() walk + per-file isIgnored() loop with a
  single directory walk that inherits gitignore scopes from parent to child.
  For a workspace with G gitignore files and F source files, cuts syscalls
  from O(2*(F+G)) to O(F+G) and ignore-checks from O(F*G) to O(F*depth).
- Drops unused ScanWorkspaceOptions.roots and unused rootDir param.
- HARDCODED_EXCLUDES is now a case-insensitive Set.
2026-04-17 13:26:31 +02:00
Alem Tuzlak 484ef82dad test(vscode-extension): drop string-key fixture (formatter rewrites quoted keys, making test redundant) 2026-04-17 13:25:26 +02:00
Alem Tuzlak cfc2608dc1 refactor(vscode-extension): tighten hook-scanner AST visitor + pin loc.line + cover string-keyed name prop 2026-04-17 13:24:24 +02:00
Alem Tuzlak 0f393a7aa9 feat(vscode-extension): add hook-site bundler with only React externalized 2026-04-17 13:18:21 +02:00
Alem Tuzlak 4d454ee004 feat(vscode-extension): add workspace walker with gitignore support 2026-04-17 13:14:21 +02:00
Alem Tuzlak ea8ffb76c0 fix(vscode-extension): widen RENDER_HOOK_NAMES to Set<string> for correct .has() typing 2026-04-17 13:10:00 +02:00
Alem Tuzlak 0f46a6167f feat(vscode-extension): add static hook scanner with oxc AST parsing 2026-04-17 13:08:04 +02:00
Alem Tuzlak 03c0ac08c1 feat(vscode-extension): add hook registry metadata 2026-04-17 13:00:33 +02:00
Alem Tuzlak 0d361448a2 feat(vscode-extension): scaffold hook explorer (view, commands, webview entry) 2026-04-17 12:41:36 +02:00
AlemTuzlak 9d00b01ccd chore: release monorepo v1.56.2 2026-04-16 16:04:38 +00:00
Alem Tuzlak 8182470f35 fix: remove unused @langchain/community peer dep from sdk-js (#3960)
## Summary

- Remove `@langchain/community` from `@copilotkit/sdk-js`
peerDependencies — it's declared as `^0.3.58` but never imported
anywhere in the package
- This was the only constraint blocking `@langchain/core@1.x` resolution
for consumers using the LangGraph JS starter

## Context

`@copilotkit/sdk-js` has zero imports from `@langchain/community`. The
`^0.3.58` peer dep forced npm to resolve `@langchain/community@0.3.x`,
which transitively pulled in `@getzep/zep-cloud` → `langchain@0.3.x`,
conflicting with `sdk-js`'s own `langchain@>=1.0.0` peer requirement.

Removing the unused peer dep eliminates this resolution conflict
entirely.

## Test plan

- [ ] `npm install` in a fresh project using `@copilotkit/sdk-js`
resolves without peer dep warnings for `@langchain/community`
- [ ] Existing LangGraph JS starter installs cleanly
- [ ] No runtime behavior change (nothing imported from the removed dep)
2026-04-16 18:02:53 +02:00
AlemTuzlak a6e8a48189 chore: release monorepo v1.56.1 2026-04-16 15:38:24 +00:00
Alem Tuzlak dbb89e3ff8 fix: remove unused @langchain/community peer dep from sdk-js
@copilotkit/sdk-js declares @langchain/community as a peer dependency
but never imports from it. The ^0.3.58 constraint was the only thing
blocking @langchain/core@1.x resolution for consumers. Remove it
entirely since it serves no purpose.
2026-04-16 17:21:05 +02:00
github-actions[bot] 0fe4d87edf style: auto-fix formatting 2026-04-16 14:43:21 +00:00
Alem Tuzlak 0e38bb6bc9 fix(ci): rename package to copilotkit-vscode-extension for vsce compatibility 2026-04-16 16:41:11 +02:00
Alem Tuzlak acb6ade4da fix(ci): fix vscode-extension type check — add es2022 target, fix missing error prop in tests, run tsc directly 2026-04-16 16:36:02 +02:00
github-actions[bot] 0ee8f18462 style: auto-fix formatting 2026-04-16 14:24:32 +00:00