@codeam/shared 2.61.76 → 2.61.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1423,6 +1423,41 @@ var INTEGRATION_REGISTRY = {
1423
1423
  }
1424
1424
  }
1425
1425
  },
1426
+ convex: {
1427
+ id: "convex",
1428
+ name: "Convex",
1429
+ icon: "convex",
1430
+ category: "database",
1431
+ // LIVE — OAuth 2.0 (authorization code, Confidential). authorize
1432
+ // dashboard.convex.dev/oauth/authorize/team (the scope is the URL PATH —
1433
+ // `team` for team-wide access — NOT a query param); token
1434
+ // api.convex.dev/oauth/token (form-urlencoded, client creds in the BODY).
1435
+ // ⚠️ Convex issues NO refresh token and the team-scoped application token
1436
+ // does not expire, so there is nothing to rotate (refresh() is a re-link
1437
+ // surface). The OAuth app (Team Settings → OAuth Applications) is registered
1438
+ // and CONVEX_OAUTH_CLIENT_ID/SECRET/REDIRECT_URI are in Secret Manager
1439
+ // (prod+dev); the config-gated 503 keeps this safe mid-rollout.
1440
+ enabled: true,
1441
+ auth: {
1442
+ kind: "oauth_redirect",
1443
+ // ⚠️ Convex's scope is the authorize URL path (`/team`), NOT sent in the
1444
+ // authorize URL as a query param — this list is informational.
1445
+ scopes: []
1446
+ },
1447
+ delivery: {
1448
+ mcp: {
1449
+ // Convex's OFFICIAL MCP server ships inside the `convex` npm package
1450
+ // (`convex mcp start`). The team-scoped OAuth application token doubles
1451
+ // as the CLI/MCP deploy key → fed via CONVEX_DEPLOY_KEY (env only, never
1452
+ // argv). Version PINNED; bump only after re-verifying headless.
1453
+ command: "npx",
1454
+ args: ["-y", "convex@1.42.3", "mcp", "start"],
1455
+ envMapping: {
1456
+ CONVEX_DEPLOY_KEY: "accessToken"
1457
+ }
1458
+ }
1459
+ }
1460
+ },
1426
1461
  confluence: {
1427
1462
  id: "confluence",
1428
1463
  name: "Confluence",
@@ -1760,6 +1795,14 @@ var INTEGRATION_BRANDING = {
1760
1795
  brandColor: "#3FCF8E",
1761
1796
  logoSvg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Supabase</title><path fill="#FFFFFF" d="M11.9 1.036c-.015-.986-1.26-1.41-1.874-.637L.764 12.05C-.33 13.427.65 15.455 2.409 15.455h9.579l.113 7.51c.014.985 1.259 1.408 1.873.636l9.262-11.653c1.093-1.375.113-3.403-1.645-3.403h-9.642z"/></svg>'
1762
1797
  },
1798
+ convex: {
1799
+ id: "convex",
1800
+ name: "Convex",
1801
+ vendor: "Convex",
1802
+ tagline: "Reactive database & backend",
1803
+ brandColor: "#EE342F",
1804
+ logoSvg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Convex</title><path fill="#FFFFFF" d="M15.09 18.916c3.488-.387 6.776-2.246 8.586-5.348-.857 7.673-9.247 12.522-16.095 9.545a3.47 3.47 0 0 1-1.547-1.314c-1.539-2.417-2.044-5.492-1.318-8.282 2.077 3.584 6.3 5.78 10.374 5.399m-10.501-7.65c-1.414 3.266-1.475 7.092.258 10.24-6.1-4.59-6.033-14.41-.074-18.953a3.44 3.44 0 0 1 1.893-.707c2.825-.15 5.695.942 7.708 2.977-4.09.04-8.073 2.66-9.785 6.442m11.757-5.437C14.283 2.951 11.053.992 7.515.933c6.84-3.105 15.253 1.929 16.17 9.37a3.6 3.6 0 0 1-.334 2.02c-1.278 2.594-3.647 4.607-6.416 5.352 2.029-3.763 1.778-8.36-.589-11.847"/></svg>'
1805
+ },
1763
1806
  cloudflare: {
1764
1807
  id: "cloudflare",
1765
1808
  name: "Cloudflare",
@@ -1853,6 +1896,145 @@ function getIntegrationBranding(id) {
1853
1896
  return INTEGRATION_BRANDING[id] ?? null;
1854
1897
  }
1855
1898
 
1899
+ // src/integrations/stack-detect.ts
1900
+ var DEP_TO_INTEGRATION = {
1901
+ // errors / observability
1902
+ "@sentry/node": "sentry",
1903
+ "@sentry/react": "sentry",
1904
+ "@sentry/nextjs": "sentry",
1905
+ "@sentry/browser": "sentry",
1906
+ "sentry-sdk": "sentry",
1907
+ "dd-trace": "datadog",
1908
+ "datadog-api-client": "datadog",
1909
+ "datadog-metrics": "datadog",
1910
+ // analytics
1911
+ "posthog-js": "posthog",
1912
+ "posthog-node": "posthog",
1913
+ posthog: "posthog",
1914
+ mixpanel: "mixpanel",
1915
+ "mixpanel-browser": "mixpanel",
1916
+ // database / backend platforms
1917
+ convex: "convex",
1918
+ "@supabase/supabase-js": "supabase",
1919
+ "supabase": "supabase",
1920
+ // infra / deploy
1921
+ vercel: "vercel",
1922
+ "@vercel/node": "vercel",
1923
+ wrangler: "cloudflare",
1924
+ // comms
1925
+ "@slack/web-api": "slack",
1926
+ "@slack/bolt": "slack",
1927
+ "discord.js": "discord",
1928
+ "discord-py": "discord",
1929
+ "discord": "discord",
1930
+ // trackers / docs / design
1931
+ "@linear/sdk": "linear",
1932
+ "@notionhq/client": "notion",
1933
+ "jira.js": "jira",
1934
+ jira: "jira",
1935
+ newman: "postman",
1936
+ "figma-api": "figma",
1937
+ "figma-js": "figma",
1938
+ // email / automation
1939
+ resend: "resend",
1940
+ n8n: "n8n"
1941
+ };
1942
+ var DEP_PREFIX_TO_INTEGRATION = [
1943
+ ["@sentry/", "sentry"],
1944
+ ["@vercel/", "vercel"],
1945
+ ["@cloudflare/", "cloudflare"],
1946
+ ["@supabase/", "supabase"],
1947
+ ["@slack/", "slack"],
1948
+ ["@datadog/", "datadog"],
1949
+ ["@linear/", "linear"],
1950
+ ["@notionhq/", "notion"]
1951
+ ];
1952
+ var FRONTEND_MARKERS = [
1953
+ "react",
1954
+ "react-dom",
1955
+ "next",
1956
+ "vue",
1957
+ "nuxt",
1958
+ "@angular/core",
1959
+ "svelte",
1960
+ "@sveltejs/kit",
1961
+ "solid-js",
1962
+ "astro",
1963
+ "gatsby",
1964
+ "remix",
1965
+ "@remix-run/react"
1966
+ ];
1967
+ var MOBILE_MARKERS = ["react-native", "expo", "@react-native/core", "@ionic/core", "flutter"];
1968
+ var BACKEND_MARKERS = [
1969
+ "express",
1970
+ "fastify",
1971
+ "@nestjs/core",
1972
+ "koa",
1973
+ "@hapi/hapi",
1974
+ "django",
1975
+ "flask",
1976
+ "fastapi",
1977
+ "rails",
1978
+ "sinatra",
1979
+ "gin-gonic",
1980
+ "laravel/framework",
1981
+ "actix-web",
1982
+ "spring-boot"
1983
+ ];
1984
+ function hasAny(deps, markers) {
1985
+ for (const m of markers) if (deps.has(m)) return true;
1986
+ return false;
1987
+ }
1988
+ function classifyStack(depNames) {
1989
+ const deps = new Set(depNames);
1990
+ const mobile = hasAny(deps, MOBILE_MARKERS);
1991
+ if (mobile) return "mobile";
1992
+ const frontend = hasAny(deps, FRONTEND_MARKERS);
1993
+ const backend = hasAny(deps, BACKEND_MARKERS);
1994
+ if (frontend && backend) return "fullstack";
1995
+ if (frontend) return "frontend";
1996
+ if (backend) return "backend";
1997
+ return "unknown";
1998
+ }
1999
+ function detectedIntegrationsFromDeps(depNames) {
2000
+ const out = [];
2001
+ const seen = /* @__PURE__ */ new Set();
2002
+ const push = (id) => {
2003
+ if (!seen.has(id)) {
2004
+ seen.add(id);
2005
+ out.push(id);
2006
+ }
2007
+ };
2008
+ for (const name of depNames) {
2009
+ const exact = DEP_TO_INTEGRATION[name];
2010
+ if (exact) {
2011
+ push(exact);
2012
+ continue;
2013
+ }
2014
+ for (const [prefix, id] of DEP_PREFIX_TO_INTEGRATION) {
2015
+ if (name.startsWith(prefix)) {
2016
+ push(id);
2017
+ break;
2018
+ }
2019
+ }
2020
+ }
2021
+ return out;
2022
+ }
2023
+ var STACK_TO_RECOMMENDED = {
2024
+ frontend: ["figma", "sentry", "posthog", "vercel"],
2025
+ backend: ["sentry", "datadog", "supabase", "convex", "cloudflare"],
2026
+ fullstack: ["sentry", "posthog", "vercel", "supabase", "convex"],
2027
+ mobile: ["sentry", "posthog"],
2028
+ unknown: []
2029
+ };
2030
+ function recommendForDeps(depNames) {
2031
+ const stack = classifyStack(depNames);
2032
+ const detected = detectedIntegrationsFromDeps(depNames);
2033
+ const detectedSet = new Set(detected);
2034
+ const recommended = STACK_TO_RECOMMENDED[stack].filter((id) => !detectedSet.has(id));
2035
+ return { stack, detected, recommended, source: "scan" };
2036
+ }
2037
+
1856
2038
  // src/skills/code-review.ts
1857
2039
  var CODE_REVIEW_BODY = `Use this skill when reviewing a pull request. It defines what a high-signal
1858
2040
  review looks like so your inline comments are worth the author's time.
@@ -2287,6 +2469,14 @@ var USER_EVENTS = {
2287
2469
  INTEGRATION_LINKED: "integration_linked",
2288
2470
  INTEGRATION_UNLINKED: "integration_unlinked",
2289
2471
  INTEGRATION_CREDENTIAL_INVALID: "integration_credential_invalid",
2472
+ // Session Tools — add/remove Agent Toolkit integrations on an ALREADY-ACTIVE
2473
+ // session. The backend publishes SESSION_INTEGRATIONS_CHANGED after it persists
2474
+ // the new attached set + relays `integrations_sync` to the box (the CLI rewrites
2475
+ // the manifest + reprovisions the live agent, answered synchronously via the
2476
+ // command result). Drives live UI on the sending device AND any other paired
2477
+ // device on the same session. Mirrored in repo A. (`integrations_detect` is a
2478
+ // pure request/response over the relay — no event.)
2479
+ SESSION_INTEGRATIONS_CHANGED: "session_integrations_changed",
2290
2480
  // CodeRabbit reviewer — the CLI posts these to /api/coderabbit/events; the
2291
2481
  // backend re-publishes them on the per-user SSE bus (mirrored in repo A).
2292
2482
  CODERABBIT_PROGRESS: "coderabbit_progress",
@@ -2352,6 +2542,7 @@ OUTPUT JSON ONLY. NO MARKDOWN. NO COMMENTARY.
2352
2542
  export {
2353
2543
  AGENT_REGISTRY,
2354
2544
  DEFAULT_API_BASE_URL,
2545
+ DEP_TO_INTEGRATION,
2355
2546
  DEV_API_BASE_URL,
2356
2547
  HEADROOM_BACKEND_ENV,
2357
2548
  HEADROOM_EXTRAS_BY_SURFACE,
@@ -2376,10 +2567,13 @@ export {
2376
2567
  PUBLIC_TO_INTERNAL,
2377
2568
  SKILL_REGISTRY,
2378
2569
  SSE_SOCKET_TIMEOUT_MS,
2570
+ STACK_TO_RECOMMENDED,
2379
2571
  TERMINAL_AGENT_PREFIX,
2380
2572
  UNKNOWN_MODEL_PRICING,
2381
2573
  UPCOMING_INTEGRATION_IDS,
2382
2574
  USER_EVENTS,
2575
+ classifyStack,
2576
+ detectedIntegrationsFromDeps,
2383
2577
  getAgent,
2384
2578
  getContextWindow,
2385
2579
  getEnabledAgents,
@@ -2402,6 +2596,7 @@ export {
2402
2596
  isSkillId,
2403
2597
  normalizeAgentId,
2404
2598
  publicToInternal,
2599
+ recommendForDeps,
2405
2600
  renderToLines,
2406
2601
  resolveApiBaseUrl,
2407
2602
  skillHasRail,