Skip to content

Conversation

@acfranzen
Copy link
Owner

@acfranzen acfranzen commented Feb 4, 2026

Summary

Improves the agent experience when importing widgets by:

  1. Documenting the proper import flow in SKILL.md
  2. Auto-triggering refresh after import so widgets have data immediately

SKILL.md Changes

  • Added comprehensive "Agent Import Flow" section
  • Documents the dry_run → verify credentials → confirm pattern
  • Includes credential type reference table (api_key, agent, local_software)
  • Complete flow diagram showing all 6 steps
  • Example verification code for agents to follow

Import Route Changes

  • After successful import of agent_refresh widgets, automatically:
    • Queue a refresh request in the database
    • Send webhook notification to OpenClaw (if configured)
  • Widget shows data immediately instead of waiting for next heartbeat

The Problem This Solves

Previously, after importing a widget:

  1. Widget showed "Waiting for data..." spinner
  2. Agent had to manually trigger refresh or wait for heartbeat
  3. No clear guidance on checking credentials before import

Now:

  1. Clear dry_run flow to check requirements first
  2. Auto-refresh triggers immediately after import
  3. Widget populates within seconds of import

Note

Medium Risk
Modifies the widget import API to create DB state and perform outbound webhook calls, which could impact import latency/behavior or fail in unexpected network/env configurations.

Overview
Improves the widget import experience by documenting a best-practice agent import flow in SKILL.md (dry-run → verify credentials → confirm import), including credential verification guidance and an end-to-end flow diagram.

Updates POST /api/widgets/import so that after importing an agent_refresh widget it queues an initial refresh request in SQLite and, when OPENCLAW_WEBHOOK_URL/OPENCLAW_WEBHOOK_TOKEN are set, fires a webhook wake to prompt OpenClaw to populate data immediately (otherwise leaving it queued for the next heartbeat).

Written by Cursor Bugbot for commit 3443c31. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
glance Ready Ready Preview, Comment Feb 5, 2026 4:35pm

Request Review

};

if (isHttps && isLocalhost) {
options.rejectUnauthorized = false;

Check failure

Code scanning / CodeQL

Disabling certificate validation High

Disabling certificate validation is strongly discouraged.

Copilot Autofix

AI 5 days ago

In general, the fix is to avoid ever setting rejectUnauthorized = false. For localhost development, either (1) use http:// instead of https:// so TLS isn’t involved, or (2) configure a certificate that the Node process trusts (e.g., via ca/cert options or system trust), while keeping rejectUnauthorized at its secure default (true).

For this specific code in src/app/api/widgets/import/route.ts, the minimal change that keeps the current intent is:

  • Remove the special case that sets options.rejectUnauthorized = false.
  • Optionally, adjust the HTTP-module selection so that if someone sets OPENCLAW_WEBHOOK_URL to an https://localhost address, the code still works securely (i.e., use HTTPS without relaxing cert checks) or document that localhost must be http:// if using self-signed certs. Since we can’t change behavior outside this snippet, the safest small change is simply to drop the rejectUnauthorized override and leave everything else as-is. HTTPS requests (including to localhost) will now require a valid, trusted certificate.

Concretely:

  • In triggerInitialRefresh, delete the block:

    if (isHttps && isLocalhost) {
      options.rejectUnauthorized = false;
    }

No extra imports or helper methods are needed.

Suggested changeset 1
src/app/api/widgets/import/route.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/app/api/widgets/import/route.ts b/src/app/api/widgets/import/route.ts
--- a/src/app/api/widgets/import/route.ts
+++ b/src/app/api/widgets/import/route.ts
@@ -98,10 +98,6 @@
         timeout: 5000
       };
 
-      if (isHttps && isLocalhost) {
-        options.rejectUnauthorized = false;
-      }
-
       const httpModule = isHttps ? https : (await import('http')).default;
 
       await new Promise<void>((resolve) => {
EOF
@@ -98,10 +98,6 @@
timeout: 5000
};

if (isHttps && isLocalhost) {
options.rejectUnauthorized = false;
}

const httpModule = isHttps ? https : (await import('http')).default;

await new Promise<void>((resolve) => {
Copilot is powered by AI and may make mistakes. Always verify output.
}

return { queued: true, webhookSent };
}
Copy link

Choose a reason for hiding this comment

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

Duplicated webhook and refresh logic across routes

Medium Severity

The triggerInitialRefresh function duplicates ~90 lines of code that already exist in src/app/api/widgets/[slug]/refresh/route.ts. Both contain identical: table creation SQL, refresh request insertion, HTTP/HTTPS detection, webhook payload construction, and promise-based request handling. This should be extracted into a shared utility function in /lib.

Fix in Cursor Fix in Web

SKILL.md:
- Add comprehensive 'Agent Import Flow' section
- Document dry_run → verify credentials → confirm pattern
- Include credential type reference table
- Add complete flow diagram
- Show example verification code

Import route:
- Auto-trigger refresh for agent_refresh widgets after import
- Queue refresh request + send webhook notification
- Widget shows data immediately instead of waiting for heartbeat
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

`).run(slug, now);
} catch {
// Ignore duplicate key errors
}
Copy link

Choose a reason for hiding this comment

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

Return value incorrectly indicates queued even on failure

Low Severity

The triggerInitialRefresh function always returns queued: true at line 130, regardless of whether the database INSERT actually succeeded. The try-catch at lines 56-58 swallows all exceptions (not just duplicate key errors as the comment suggests), meaning if the INSERT fails for any reason, queued is still reported as true. When the webhook also isn't sent, the caller displays "Initial refresh queued (will process on next heartbeat)" even though nothing was actually queued.

Additional Locations (1)

Fix in Cursor Fix in Web

await new Promise<void>((resolve) => {
const req = httpModule.request(webhookUrl, options, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
Copy link

Choose a reason for hiding this comment

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

Unused variable accumulates response but is never read

Low Severity

The data variable accumulates the HTTP response body (let data = ''; res.on('data', chunk => data += chunk);) but is never used afterward. The similar code in [slug]/refresh/route.ts uses data for error logging. Either remove this dead store or add error logging for consistency.

Fix in Cursor Fix in Web

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant