@squadbase/vite-server 0.1.17-dev.a9ddcfa → 0.1.17-dev.e4768d1

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.
Files changed (80) hide show
  1. package/dist/cli/index.js +8941 -3700
  2. package/dist/connectors/airtable-oauth.js +87 -23
  3. package/dist/connectors/airtable.js +130 -23
  4. package/dist/connectors/amplitude.js +47 -23
  5. package/dist/connectors/anthropic.js +41 -17
  6. package/dist/connectors/asana.js +76 -25
  7. package/dist/connectors/attio.js +69 -28
  8. package/dist/connectors/aws-billing.js +47 -23
  9. package/dist/connectors/azure-sql.js +322 -25
  10. package/dist/connectors/backlog-api-key.js +79 -30
  11. package/dist/connectors/clickup.js +89 -25
  12. package/dist/connectors/cosmosdb.js +51 -27
  13. package/dist/connectors/customerio.js +47 -23
  14. package/dist/connectors/dbt.js +725 -40
  15. package/dist/connectors/freshdesk.js +121 -23
  16. package/dist/connectors/freshsales.js +47 -23
  17. package/dist/connectors/freshservice.js +47 -23
  18. package/dist/connectors/gamma.js +54 -30
  19. package/dist/connectors/gemini.js +41 -17
  20. package/dist/connectors/github.js +51 -27
  21. package/dist/connectors/gmail-oauth.js +42 -23
  22. package/dist/connectors/gmail.js +43 -19
  23. package/dist/connectors/google-ads.js +47 -23
  24. package/dist/connectors/google-analytics-oauth.js +191 -40
  25. package/dist/connectors/google-analytics.js +529 -111
  26. package/dist/connectors/google-audit-log.js +43 -19
  27. package/dist/connectors/google-calendar-oauth.js +100 -30
  28. package/dist/connectors/google-calendar.js +100 -26
  29. package/dist/connectors/google-docs.js +42 -23
  30. package/dist/connectors/google-drive.js +64 -23
  31. package/dist/connectors/google-search-console-oauth.js +165 -32
  32. package/dist/connectors/google-sheets.js +142 -199
  33. package/dist/connectors/google-slides.js +42 -23
  34. package/dist/connectors/grafana.js +84 -25
  35. package/dist/connectors/hackernews.d.ts +5 -0
  36. package/dist/connectors/hackernews.js +909 -0
  37. package/dist/connectors/hubspot-oauth.js +73 -22
  38. package/dist/connectors/hubspot.js +64 -24
  39. package/dist/connectors/influxdb.js +47 -23
  40. package/dist/connectors/intercom-oauth.js +104 -25
  41. package/dist/connectors/intercom.js +51 -27
  42. package/dist/connectors/jdbc.js +76 -25
  43. package/dist/connectors/jira-api-key.js +107 -26
  44. package/dist/connectors/kintone-api-token.js +105 -33
  45. package/dist/connectors/kintone.js +182 -26
  46. package/dist/connectors/linear.js +93 -27
  47. package/dist/connectors/linkedin-ads.js +80 -29
  48. package/dist/connectors/mailchimp-oauth.js +45 -21
  49. package/dist/connectors/mailchimp.js +45 -21
  50. package/dist/connectors/meta-ads-oauth.js +72 -29
  51. package/dist/connectors/meta-ads.js +74 -29
  52. package/dist/connectors/mixpanel.js +47 -23
  53. package/dist/connectors/monday.js +48 -24
  54. package/dist/connectors/mongodb.js +47 -23
  55. package/dist/connectors/notion-oauth.js +92 -24
  56. package/dist/connectors/notion.js +144 -26
  57. package/dist/connectors/openai.js +41 -17
  58. package/dist/connectors/oracle.js +316 -26
  59. package/dist/connectors/outlook-oauth.js +53 -34
  60. package/dist/connectors/powerbi-oauth.js +45 -26
  61. package/dist/connectors/salesforce.js +150 -24
  62. package/dist/connectors/semrush.js +45 -21
  63. package/dist/connectors/sentry.js +75 -25
  64. package/dist/connectors/shopify-oauth.js +75 -23
  65. package/dist/connectors/shopify.js +47 -23
  66. package/dist/connectors/sqlserver.js +322 -25
  67. package/dist/connectors/stripe-api-key.js +105 -30
  68. package/dist/connectors/stripe-oauth.js +102 -32
  69. package/dist/connectors/supabase.js +315 -21
  70. package/dist/connectors/tableau.js +54 -30
  71. package/dist/connectors/tiktok-ads.js +76 -31
  72. package/dist/connectors/wix-store.js +47 -23
  73. package/dist/connectors/x.d.ts +5 -0
  74. package/dist/connectors/x.js +951 -0
  75. package/dist/connectors/zendesk-oauth.js +87 -25
  76. package/dist/connectors/zendesk.js +51 -27
  77. package/dist/index.js +9005 -3709
  78. package/dist/main.js +9005 -3709
  79. package/dist/vite-plugin.js +8939 -3698
  80. package/package.json +12 -4
@@ -1,6 +1,11 @@
1
1
  var __getOwnPropNames = Object.getOwnPropertyNames;
2
- var __esm = (fn, res) => function __init() {
3
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
2
+ var __esm = (fn, res, err) => function __init() {
3
+ if (err) throw err[0];
4
+ try {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ } catch (e) {
7
+ throw err = [e], e;
8
+ }
4
9
  };
5
10
 
6
11
  // ../connectors/src/parameter-definition.ts
@@ -258,6 +263,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
258
263
  * `runSetupFlow` from `setup-flow.ts`.
259
264
  */
260
265
  setup;
266
+ /**
267
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
268
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
269
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
270
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
271
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
272
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
273
+ */
274
+ introspect;
261
275
  /**
262
276
  * Opt-out of the default "verify before save" behavior on connection
263
277
  * creation. The backend invokes `checkConnection` synchronously while
@@ -272,6 +286,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
272
286
  * the default verify-on-create behavior without opt-in.
273
287
  */
274
288
  skipConnectionCheckOnCreate;
289
+ /**
290
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
291
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
292
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
293
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
294
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
295
+ */
296
+ surveyProbes;
275
297
  constructor(config) {
276
298
  this.slug = config.slug;
277
299
  this.authType = config.authType;
@@ -289,7 +311,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
289
311
  this.query = config.query;
290
312
  this.checkConnection = config.checkConnection;
291
313
  this.setup = config.setup;
314
+ this.introspect = config.introspect;
292
315
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
316
+ this.surveyProbes = config.surveyProbes;
293
317
  }
294
318
  get connectorKey() {
295
319
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -297,7 +321,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
297
321
  /**
298
322
  * Create tools for connections that belong to this connector.
299
323
  * Filters connections by connectorKey internally.
300
- * Returns tools keyed as `${connectorKey}_${toolName}`.
324
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
301
325
  */
302
326
  createTools(connections, config, opts) {
303
327
  const myConnections = connections.filter(
@@ -307,7 +331,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
307
331
  for (const t of Object.values(this.tools)) {
308
332
  const tool = t.createTool(myConnections, config);
309
333
  const originalToModelOutput = tool.toModelOutput;
310
- result[`${this.connectorKey}_${t.name}`] = {
334
+ result[`connector_${this.connectorKey}_${t.name}`] = {
311
335
  ...tool,
312
336
  toModelOutput: async (options) => {
313
337
  if (!originalToModelOutput) {
@@ -327,25 +351,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
327
351
  if (authType) return `${slug}-${authType}`;
328
352
  const LEGACY_NULL_AUTH_TYPE_MAP = {
329
353
  // user-password
330
- "postgresql": "user-password",
331
- "mysql": "user-password",
332
- "clickhouse": "user-password",
333
- "kintone": "user-password",
354
+ postgresql: "user-password",
355
+ mysql: "user-password",
356
+ clickhouse: "user-password",
357
+ kintone: "user-password",
334
358
  "squadbase-db": "user-password",
335
359
  // service-account
336
- "snowflake": "service-account",
337
- "bigquery": "service-account",
360
+ snowflake: "service-account",
361
+ bigquery: "service-account",
338
362
  "google-analytics": "service-account",
339
363
  "google-calendar": "service-account",
340
364
  "aws-athena": "service-account",
341
- "redshift": "service-account",
365
+ redshift: "service-account",
342
366
  // api-key
343
- "databricks": "api-key",
344
- "dbt": "api-key",
345
- "airtable": "api-key",
346
- "openai": "api-key",
347
- "gemini": "api-key",
348
- "anthropic": "api-key",
367
+ databricks: "api-key",
368
+ dbt: "api-key",
369
+ airtable: "api-key",
370
+ openai: "api-key",
371
+ gemini: "api-key",
372
+ anthropic: "api-key",
349
373
  "wix-store": "api-key"
350
374
  };
351
375
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -1067,7 +1091,7 @@ var semrushConnector = new ConnectorPlugin({
1067
1091
  systemPrompt: {
1068
1092
  en: `### Tools
1069
1093
 
1070
- - \`semrush-api-key_request\`: The only way to call the Semrush API. Use it for the Standard Analytics API (\`/?type=...\` reports), the Trends API (\`/analytics/v1/...\`), and the Projects API (\`/management/v1/...\`). Authentication is handled automatically \u2014 the API key is appended as the \`key\` query parameter; never include it yourself. The Standard Analytics API returns semicolon-separated CSV with the first row as the header (use \`responseFormat="text"\`); the Trends and Projects APIs return JSON (use \`responseFormat="json"\`). Errors from the Standard API are returned as a body that starts with \`ERROR\`, often with HTTP 200 \u2014 the tool surfaces these as \`success: false\` automatically.
1094
+ - \`connector_semrush-api-key_request\`: The only way to call the Semrush API. Use it for the Standard Analytics API (\`/?type=...\` reports), the Trends API (\`/analytics/v1/...\`), and the Projects API (\`/management/v1/...\`). Authentication is handled automatically \u2014 the API key is appended as the \`key\` query parameter; never include it yourself. The Standard Analytics API returns semicolon-separated CSV with the first row as the header (use \`responseFormat="text"\`); the Trends and Projects APIs return JSON (use \`responseFormat="json"\`). Errors from the Standard API are returned as a body that starts with \`ERROR\`, often with HTTP 200 \u2014 the tool surfaces these as \`success: false\` automatically.
1071
1095
 
1072
1096
  ### Business Logic
1073
1097
 
@@ -1080,7 +1104,7 @@ SDK methods (client created via \`connection(connectionId)\`):
1080
1104
  - \`client.trends(path, query?)\` \u2014 call a Trends API endpoint (\`/analytics/v1/...\`) and return parsed JSON
1081
1105
  - \`client.projects(path, init?)\` \u2014 call a Projects API endpoint (\`/management/v1/...\`) and return parsed JSON
1082
1106
 
1083
- \u{1F6A8} **MANDATORY pre-flight before creating any server logic that calls \`report()\`.** Before authoring a TypeScript handler that invokes \`client.report(...)\` (Standard Analytics \u2014 \`domain_ranks\`, \`domain_organic\`, \`phrase_this\`, etc.), you MUST first call the \`semrush-api-key_request\` tool with \`path: "https://www.semrush.com/users/countapiunits.html"\`, no \`queryParams\`, \`responseFormat: "text"\` to confirm the unit balance is greater than 0. If the balance is 0, **stop, do not create the server logic**, and report the issue to the user (the account owner needs to top up API units in the Semrush console). \`testFetchServerLogic\` will execute the handler and consume units; creating handlers when the balance is 0 produces \`ERROR 132 :: API UNITS BALANCE IS ZERO\` failures across every server logic.
1107
+ \u{1F6A8} **MANDATORY pre-flight before creating any server logic that calls \`report()\`.** Before authoring a TypeScript handler that invokes \`client.report(...)\` (Standard Analytics \u2014 \`domain_ranks\`, \`domain_organic\`, \`phrase_this\`, etc.), you MUST first call the \`connector_semrush-api-key_request\` tool with \`path: "https://www.semrush.com/users/countapiunits.html"\`, no \`queryParams\`, \`responseFormat: "text"\` to confirm the unit balance is greater than 0. If the balance is 0, **stop, do not create the server logic**, and report the issue to the user (the account owner needs to top up API units in the Semrush console). \`testFetchServerLogic\` will execute the handler and consume units; creating handlers when the balance is 0 produces \`ERROR 132 :: API UNITS BALANCE IS ZERO\` failures across every server logic.
1084
1108
 
1085
1109
  \u{1F6A8} **Always set a small \`display_limit\` explicitly \u2014 never rely on the default.** Semrush computes "required units = display_limit \xD7 per-row cost" up front, and rejects the request with \`ERROR 132 :: API UNITS BALANCE IS ZERO\` when the *estimated* cost exceeds the remaining balance, **even when the actual balance is non-zero** (e.g. balance \u2248 40,950 still fails for \`display_limit=10000\` on costly reports). Default to \`display_limit: "1000"\` (or smaller \u2014 \`"100"\` is plenty for most dashboards), and only increase it when the user explicitly asks for a larger sample AND \`checkUnits()\` confirms enough headroom. If you truly need all rows, paginate with \`display_offset\` in chunks of 1000 instead of bumping \`display_limit\`. Treat \`ERROR 132\` as "request too large for the current balance" first, and only as "balance is literally zero" after re-checking units.
1086
1110
 
@@ -1170,7 +1194,7 @@ To check remaining API units (free, does NOT consume units), call the request to
1170
1194
  - Date strings in historical endpoints must be the 15th of the month (\`YYYYMM15\`)`,
1171
1195
  ja: `### \u30C4\u30FC\u30EB
1172
1196
 
1173
- - \`semrush-api-key_request\`: Semrush API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002Standard Analytics API\uFF08\`/?type=...\` \u5F62\u5F0F\u306E\u30EC\u30DD\u30FC\u30C8\uFF09\u3001Trends API\uFF08\`/analytics/v1/...\`\uFF09\u3001Projects API\uFF08\`/management/v1/...\`\uFF09\u3059\u3079\u3066\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306F\u81EA\u52D5\u7684\u306B\u884C\u308F\u308C\u3001API\u30AD\u30FC\u306F \`key\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u4ED8\u4E0E\u3055\u308C\u308B\u305F\u3081\u3001\u81EA\u5206\u3067\u542B\u3081\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002Standard Analytics API \u306F1\u884C\u76EE\u304C\u30D8\u30C3\u30C0\u30FC\u306E\u30BB\u30DF\u30B3\u30ED\u30F3\u533A\u5207\u308ACSV\u3092\u8FD4\u3059\u305F\u3081 \`responseFormat="text"\` \u3092\u4F7F\u7528\u3057\u3001Trends/Projects API \u306F JSON \u3092\u8FD4\u3059\u305F\u3081 \`responseFormat="json"\` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002Standard API \u306E\u30A8\u30E9\u30FC\u306F HTTP 200 \u3067\u3082\u672C\u6587\u304C \`ERROR\` \u3067\u59CB\u307E\u308B\u5F62\u5F0F\u3067\u8FD4\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u304C\u3001\u30C4\u30FC\u30EB\u306F\u81EA\u52D5\u7684\u306B \`success: false\` \u3068\u3057\u3066\u8FD4\u3057\u307E\u3059\u3002
1197
+ - \`connector_semrush-api-key_request\`: Semrush API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002Standard Analytics API\uFF08\`/?type=...\` \u5F62\u5F0F\u306E\u30EC\u30DD\u30FC\u30C8\uFF09\u3001Trends API\uFF08\`/analytics/v1/...\`\uFF09\u3001Projects API\uFF08\`/management/v1/...\`\uFF09\u3059\u3079\u3066\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306F\u81EA\u52D5\u7684\u306B\u884C\u308F\u308C\u3001API\u30AD\u30FC\u306F \`key\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u4ED8\u4E0E\u3055\u308C\u308B\u305F\u3081\u3001\u81EA\u5206\u3067\u542B\u3081\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002Standard Analytics API \u306F1\u884C\u76EE\u304C\u30D8\u30C3\u30C0\u30FC\u306E\u30BB\u30DF\u30B3\u30ED\u30F3\u533A\u5207\u308ACSV\u3092\u8FD4\u3059\u305F\u3081 \`responseFormat="text"\` \u3092\u4F7F\u7528\u3057\u3001Trends/Projects API \u306F JSON \u3092\u8FD4\u3059\u305F\u3081 \`responseFormat="json"\` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002Standard API \u306E\u30A8\u30E9\u30FC\u306F HTTP 200 \u3067\u3082\u672C\u6587\u304C \`ERROR\` \u3067\u59CB\u307E\u308B\u5F62\u5F0F\u3067\u8FD4\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u304C\u3001\u30C4\u30FC\u30EB\u306F\u81EA\u52D5\u7684\u306B \`success: false\` \u3068\u3057\u3066\u8FD4\u3057\u307E\u3059\u3002
1174
1198
 
1175
1199
  ### Business Logic
1176
1200
 
@@ -1183,7 +1207,7 @@ SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u30
1183
1207
  - \`client.trends(path, query?)\` \u2014 Trends API \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\`/analytics/v1/...\`\uFF09\u3092\u547C\u3073\u51FA\u3057 JSON \u3092\u8FD4\u3059
1184
1208
  - \`client.projects(path, init?)\` \u2014 Projects API \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\`/management/v1/...\`\uFF09\u3092\u547C\u3073\u51FA\u3057 JSON \u3092\u8FD4\u3059
1185
1209
 
1186
- \u{1F6A8} **\`report()\` \u3092\u547C\u3076\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u3092\u4F5C\u6210\u3059\u308B\u524D\u306E\u5FC5\u9808\u30D7\u30EA\u30D5\u30E9\u30A4\u30C8\u3002** Standard Analytics\uFF08\`domain_ranks\`\u3001\`domain_organic\`\u3001\`phrase_this\` \u306A\u3069\uFF09\u306E \`client.report(...)\` \u3092\u542B\u3080 TypeScript \u30CF\u30F3\u30C9\u30E9\u3092\u4F5C\u6210\u3059\u308B\u524D\u306B\u3001\u5FC5\u305A \`semrush-api-key_request\` \u30C4\u30FC\u30EB\u3092 \`path: "https://www.semrush.com/users/countapiunits.html"\`\u3001\`queryParams\` \u7121\u3057\u3001\`responseFormat: "text"\` \u3067\u547C\u3073\u51FA\u3057\u3066\u30E6\u30CB\u30C3\u30C8\u6B8B\u91CF\u304C 0 \u3088\u308A\u5927\u304D\u3044\u3053\u3068\u3092\u78BA\u8A8D\u3059\u308B\u3053\u3068\u3002\u6B8B\u91CF\u304C 0 \u306E\u5834\u5408\u306F **\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u3092\u4F5C\u6210\u305B\u305A\u306B\u505C\u6B62\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u5831\u544A**\u3059\u308B\uFF08Semrush \u306E\u7BA1\u7406\u30B3\u30F3\u30BD\u30FC\u30EB\u304B\u3089 API \u30E6\u30CB\u30C3\u30C8\u3092\u88DC\u5145\u3059\u308B\u5FC5\u8981\u304C\u3042\u308B\uFF09\u3002\`testFetchServerLogic\` \u306F\u30CF\u30F3\u30C9\u30E9\u3092\u5B9F\u884C\u3057\u3066\u30E6\u30CB\u30C3\u30C8\u3092\u6D88\u8CBB\u3059\u308B\u305F\u3081\u3001\u6B8B\u91CF 0 \u306E\u307E\u307E\u4F5C\u6210\u3059\u308B\u3068\u5168\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u304C \`ERROR 132 :: API UNITS BALANCE IS ZERO\` \u3067\u5931\u6557\u3059\u308B\u3002
1210
+ \u{1F6A8} **\`report()\` \u3092\u547C\u3076\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u3092\u4F5C\u6210\u3059\u308B\u524D\u306E\u5FC5\u9808\u30D7\u30EA\u30D5\u30E9\u30A4\u30C8\u3002** Standard Analytics\uFF08\`domain_ranks\`\u3001\`domain_organic\`\u3001\`phrase_this\` \u306A\u3069\uFF09\u306E \`client.report(...)\` \u3092\u542B\u3080 TypeScript \u30CF\u30F3\u30C9\u30E9\u3092\u4F5C\u6210\u3059\u308B\u524D\u306B\u3001\u5FC5\u305A \`connector_semrush-api-key_request\` \u30C4\u30FC\u30EB\u3092 \`path: "https://www.semrush.com/users/countapiunits.html"\`\u3001\`queryParams\` \u7121\u3057\u3001\`responseFormat: "text"\` \u3067\u547C\u3073\u51FA\u3057\u3066\u30E6\u30CB\u30C3\u30C8\u6B8B\u91CF\u304C 0 \u3088\u308A\u5927\u304D\u3044\u3053\u3068\u3092\u78BA\u8A8D\u3059\u308B\u3053\u3068\u3002\u6B8B\u91CF\u304C 0 \u306E\u5834\u5408\u306F **\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u3092\u4F5C\u6210\u305B\u305A\u306B\u505C\u6B62\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u5831\u544A**\u3059\u308B\uFF08Semrush \u306E\u7BA1\u7406\u30B3\u30F3\u30BD\u30FC\u30EB\u304B\u3089 API \u30E6\u30CB\u30C3\u30C8\u3092\u88DC\u5145\u3059\u308B\u5FC5\u8981\u304C\u3042\u308B\uFF09\u3002\`testFetchServerLogic\` \u306F\u30CF\u30F3\u30C9\u30E9\u3092\u5B9F\u884C\u3057\u3066\u30E6\u30CB\u30C3\u30C8\u3092\u6D88\u8CBB\u3059\u308B\u305F\u3081\u3001\u6B8B\u91CF 0 \u306E\u307E\u307E\u4F5C\u6210\u3059\u308B\u3068\u5168\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u304C \`ERROR 132 :: API UNITS BALANCE IS ZERO\` \u3067\u5931\u6557\u3059\u308B\u3002
1187
1211
 
1188
1212
  \u{1F6A8} **\`display_limit\` \u306F\u5FC5\u305A\u660E\u793A\u7684\u306B\u5C0F\u3055\u3044\u5024\u3092\u6307\u5B9A\u3057\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306B\u983C\u3089\u306A\u3044\u3053\u3068\u3002** Semrush \u306F\u4E8B\u524D\u306B\u300C\u5FC5\u8981\u30E6\u30CB\u30C3\u30C8 = display_limit \xD7 \u884C\u3042\u305F\u308A\u5358\u4FA1\u300D\u3092\u8A08\u7B97\u3057\u3001\u305D\u306E**\u898B\u7A4D\u984D**\u304C\u6B8B\u91CF\u3092\u8D85\u3048\u308B\u3068\u30EA\u30AF\u30A8\u30B9\u30C8\u3092 \`ERROR 132 :: API UNITS BALANCE IS ZERO\` \u3067\u62D2\u5426\u3059\u308B\u3002**\u5B9F\u6B8B\u91CF\u304C\u30BC\u30ED\u3067\u306A\u304F\u3066\u3082**\u8D77\u3053\u308B\uFF08\u4F8B\uFF1A\u6B8B\u91CF\u7D04 40,950 \u3067\u3082\u3001\u30B3\u30B9\u30C8\u306E\u9AD8\u3044\u30EC\u30DD\u30FC\u30C8\u3067 \`display_limit=10000\` \u3060\u3068\u5931\u6557\u3059\u308B\uFF09\u3002\u539F\u5247\u3068\u3057\u3066 \`display_limit: "1000"\`\uFF08\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u7528\u9014\u306A\u3089 \`"100"\` \u3067\u3082\u5341\u5206\uFF09\u3092\u6307\u5B9A\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u304C\u660E\u793A\u7684\u306B\u5927\u304D\u306A\u30B5\u30F3\u30D7\u30EB\u3092\u8981\u6C42\u3057\u3001\u304B\u3064 \`checkUnits()\` \u3067\u6B8B\u91CF\u306B\u5341\u5206\u306A\u4F59\u88D5\u304C\u3042\u308B\u3053\u3068\u3092\u78BA\u8A8D\u3067\u304D\u305F\u5834\u5408\u306E\u307F\u5897\u3084\u3059\u3002\u5168\u884C\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F \`display_limit\` \u3092\u4E0A\u3052\u308B\u306E\u3067\u306F\u306A\u304F\u3001\`display_offset\` \u3067 1000 \u4EF6\u523B\u307F\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u5B9F\u88C5\u3059\u308B\u3053\u3068\u3002\`ERROR 132\` \u306F\u300C\u6B8B\u91CF\u304C\u6587\u5B57\u901A\u308A\u30BC\u30ED\u300D\u3088\u308A\u5148\u306B\u300C\u73FE\u5728\u306E\u6B8B\u91CF\u306B\u5BFE\u3057\u3066\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u5927\u304D\u3059\u304E\u308B\u300D\u3092\u7591\u3044\u3001\u30E6\u30CB\u30C3\u30C8\u3092\u518D\u78BA\u8A8D\u3057\u3066\u304B\u3089\u5224\u65AD\u3059\u308B\u3053\u3068\u3002
1189
1213
 
@@ -1,6 +1,11 @@
1
1
  var __getOwnPropNames = Object.getOwnPropertyNames;
2
- var __esm = (fn, res) => function __init() {
3
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
2
+ var __esm = (fn, res, err) => function __init() {
3
+ if (err) throw err[0];
4
+ try {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ } catch (e) {
7
+ throw err = [e], e;
8
+ }
4
9
  };
5
10
 
6
11
  // ../connectors/src/parameter-definition.ts
@@ -249,6 +254,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
249
254
  * `runSetupFlow` from `setup-flow.ts`.
250
255
  */
251
256
  setup;
257
+ /**
258
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
259
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
260
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
261
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
262
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
263
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
264
+ */
265
+ introspect;
252
266
  /**
253
267
  * Opt-out of the default "verify before save" behavior on connection
254
268
  * creation. The backend invokes `checkConnection` synchronously while
@@ -263,6 +277,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
263
277
  * the default verify-on-create behavior without opt-in.
264
278
  */
265
279
  skipConnectionCheckOnCreate;
280
+ /**
281
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
282
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
283
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
284
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
285
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
286
+ */
287
+ surveyProbes;
266
288
  constructor(config) {
267
289
  this.slug = config.slug;
268
290
  this.authType = config.authType;
@@ -280,7 +302,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
280
302
  this.query = config.query;
281
303
  this.checkConnection = config.checkConnection;
282
304
  this.setup = config.setup;
305
+ this.introspect = config.introspect;
283
306
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
307
+ this.surveyProbes = config.surveyProbes;
284
308
  }
285
309
  get connectorKey() {
286
310
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -288,7 +312,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
288
312
  /**
289
313
  * Create tools for connections that belong to this connector.
290
314
  * Filters connections by connectorKey internally.
291
- * Returns tools keyed as `${connectorKey}_${toolName}`.
315
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
292
316
  */
293
317
  createTools(connections, config, opts) {
294
318
  const myConnections = connections.filter(
@@ -298,7 +322,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
298
322
  for (const t of Object.values(this.tools)) {
299
323
  const tool = t.createTool(myConnections, config);
300
324
  const originalToModelOutput = tool.toModelOutput;
301
- result[`${this.connectorKey}_${t.name}`] = {
325
+ result[`connector_${this.connectorKey}_${t.name}`] = {
302
326
  ...tool,
303
327
  toModelOutput: async (options) => {
304
328
  if (!originalToModelOutput) {
@@ -318,25 +342,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
318
342
  if (authType) return `${slug}-${authType}`;
319
343
  const LEGACY_NULL_AUTH_TYPE_MAP = {
320
344
  // user-password
321
- "postgresql": "user-password",
322
- "mysql": "user-password",
323
- "clickhouse": "user-password",
324
- "kintone": "user-password",
345
+ postgresql: "user-password",
346
+ mysql: "user-password",
347
+ clickhouse: "user-password",
348
+ kintone: "user-password",
325
349
  "squadbase-db": "user-password",
326
350
  // service-account
327
- "snowflake": "service-account",
328
- "bigquery": "service-account",
351
+ snowflake: "service-account",
352
+ bigquery: "service-account",
329
353
  "google-analytics": "service-account",
330
354
  "google-calendar": "service-account",
331
355
  "aws-athena": "service-account",
332
- "redshift": "service-account",
356
+ redshift: "service-account",
333
357
  // api-key
334
- "databricks": "api-key",
335
- "dbt": "api-key",
336
- "airtable": "api-key",
337
- "openai": "api-key",
338
- "gemini": "api-key",
339
- "anthropic": "api-key",
358
+ databricks: "api-key",
359
+ dbt: "api-key",
360
+ airtable: "api-key",
361
+ openai: "api-key",
362
+ gemini: "api-key",
363
+ anthropic: "api-key",
340
364
  "wix-store": "api-key"
341
365
  };
342
366
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -428,12 +452,12 @@ var AUTH_TYPES = {
428
452
  // ../connectors/src/connectors/sentry/setup.ts
429
453
  var sentryOnboarding = new ConnectorOnboarding({
430
454
  dataOverviewInstructions: {
431
- en: `1. Call sentry_request with GET /organizations/{organizationSlug}/projects/ to list all projects
432
- 2. Call sentry_request with GET /organizations/{organizationSlug}/issues/?sort=date&query=is:unresolved to get recent unresolved issues
433
- 3. For a specific issue, call sentry_request with GET /organizations/{organizationSlug}/issues/{issueId}/ to get details`,
434
- ja: `1. sentry_request \u3067 GET /organizations/{organizationSlug}/projects/ \u3092\u547C\u3073\u51FA\u3057\u3001\u5168\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u4E00\u89A7\u8868\u793A
435
- 2. sentry_request \u3067 GET /organizations/{organizationSlug}/issues/?sort=date&query=is:unresolved \u3092\u547C\u3073\u51FA\u3057\u3001\u6700\u8FD1\u306E\u672A\u89E3\u6C7A\u30A4\u30B7\u30E5\u30FC\u3092\u53D6\u5F97
436
- 3. \u7279\u5B9A\u306E\u30A4\u30B7\u30E5\u30FC\u306B\u3064\u3044\u3066 sentry_request \u3067 GET /organizations/{organizationSlug}/issues/{issueId}/ \u3092\u547C\u3073\u51FA\u3057\u3001\u8A73\u7D30\u3092\u53D6\u5F97`
455
+ en: `1. Call connector_sentry_request with GET /organizations/{organizationSlug}/projects/ to list all projects
456
+ 2. Call connector_sentry_request with GET /organizations/{organizationSlug}/issues/?sort=date&query=is:unresolved to get recent unresolved issues
457
+ 3. For a specific issue, call connector_sentry_request with GET /organizations/{organizationSlug}/issues/{issueId}/ to get details`,
458
+ ja: `1. connector_sentry_request \u3067 GET /organizations/{organizationSlug}/projects/ \u3092\u547C\u3073\u51FA\u3057\u3001\u5168\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u4E00\u89A7\u8868\u793A
459
+ 2. connector_sentry_request \u3067 GET /organizations/{organizationSlug}/issues/?sort=date&query=is:unresolved \u3092\u547C\u3073\u51FA\u3057\u3001\u6700\u8FD1\u306E\u672A\u89E3\u6C7A\u30A4\u30B7\u30E5\u30FC\u3092\u53D6\u5F97
460
+ 3. \u7279\u5B9A\u306E\u30A4\u30B7\u30E5\u30FC\u306B\u3064\u3044\u3066 connector_sentry_request \u3067 GET /organizations/{organizationSlug}/issues/{issueId}/ \u3092\u547C\u3073\u51FA\u3057\u3001\u8A73\u7D30\u3092\u53D6\u5F97`
437
461
  }
438
462
  });
439
463
 
@@ -463,6 +487,19 @@ async function listOrganizations(params) {
463
487
  const data = await res.json();
464
488
  return data ?? [];
465
489
  }
490
+ async function listRecentIssues(params, orgSlug, projectSlug) {
491
+ try {
492
+ const res = await apiFetch(
493
+ params,
494
+ `/projects/${orgSlug}/${projectSlug}/issues/?limit=5&query=is:unresolved`
495
+ );
496
+ if (!res.ok) return [];
497
+ const data = await res.json();
498
+ return data ?? [];
499
+ } catch {
500
+ return [];
501
+ }
502
+ }
466
503
  async function listProjects(params, orgSlug) {
467
504
  const res = await apiFetch(params, `/organizations/${orgSlug}/projects/`);
468
505
  if (!res.ok) {
@@ -544,6 +581,19 @@ var sentrySetupFlow = {
544
581
  sections.push(`| First event | ${project.firstEvent ?? "-"} |`);
545
582
  sections.push(`| Created | ${project.dateCreated ?? "-"} |`);
546
583
  sections.push("");
584
+ const issues = await listRecentIssues(rt.params, orgSlug, project.slug);
585
+ if (issues.length > 0) {
586
+ sections.push("##### Recent unresolved issues", "");
587
+ sections.push("| ID | Title | Level | Events | Users | Last seen |");
588
+ sections.push("|----|-------|-------|--------|-------|-----------|");
589
+ for (const issue of issues) {
590
+ const title = (issue.title ?? "").replace(/\|/g, "\\|").slice(0, 60);
591
+ sections.push(
592
+ `| ${issue.shortId ?? "-"} | ${title || "-"} | ${issue.level ?? "-"} | ${issue.count ?? "-"} | ${issue.userCount ?? "-"} | ${issue.lastSeen ?? "-"} |`
593
+ );
594
+ }
595
+ sections.push("");
596
+ }
547
597
  }
548
598
  return sections.join("\n");
549
599
  }
@@ -646,7 +696,7 @@ var sentryConnector = new ConnectorPlugin({
646
696
  systemPrompt: {
647
697
  en: `### Tools
648
698
 
649
- - \`sentry_request\`: Send authenticated requests to the Sentry API. Supports GET, POST, PUT, and DELETE methods. Authentication is handled automatically via Bearer token. The {organizationSlug} placeholder in paths is automatically replaced with the configured organization slug.
699
+ - \`connector_sentry_request\`: Send authenticated requests to the Sentry API. Supports GET, POST, PUT, and DELETE methods. Authentication is handled automatically via Bearer token. The {organizationSlug} placeholder in paths is automatically replaced with the configured organization slug.
650
700
 
651
701
  ### Sentry API Reference
652
702
 
@@ -729,7 +779,7 @@ await sentry.updateIssue("12345", { status: "resolved" });
729
779
  \`\`\``,
730
780
  ja: `### \u30C4\u30FC\u30EB
731
781
 
732
- - \`sentry_request\`: Sentry API\u3078\u306E\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002GET, POST, PUT, DELETE\u30E1\u30BD\u30C3\u30C9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002Bearer token\u306B\u3088\u308B\u8A8D\u8A3C\u306F\u81EA\u52D5\u3067\u884C\u308F\u308C\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{organizationSlug}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u8A2D\u5B9A\u6E08\u307F\u306E\u7D44\u7E54\u30B9\u30E9\u30C3\u30B0\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002
782
+ - \`connector_sentry_request\`: Sentry API\u3078\u306E\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002GET, POST, PUT, DELETE\u30E1\u30BD\u30C3\u30C9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002Bearer token\u306B\u3088\u308B\u8A8D\u8A3C\u306F\u81EA\u52D5\u3067\u884C\u308F\u308C\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{organizationSlug}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u8A2D\u5B9A\u6E08\u307F\u306E\u7D44\u7E54\u30B9\u30E9\u30C3\u30B0\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002
733
783
 
734
784
  ### Sentry API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
735
785
 
@@ -73,6 +73,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
73
73
  * `runSetupFlow` from `setup-flow.ts`.
74
74
  */
75
75
  setup;
76
+ /**
77
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
78
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
79
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
80
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
81
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
82
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
83
+ */
84
+ introspect;
76
85
  /**
77
86
  * Opt-out of the default "verify before save" behavior on connection
78
87
  * creation. The backend invokes `checkConnection` synchronously while
@@ -87,6 +96,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
87
96
  * the default verify-on-create behavior without opt-in.
88
97
  */
89
98
  skipConnectionCheckOnCreate;
99
+ /**
100
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
101
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
102
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
103
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
104
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
105
+ */
106
+ surveyProbes;
90
107
  constructor(config) {
91
108
  this.slug = config.slug;
92
109
  this.authType = config.authType;
@@ -104,7 +121,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
104
121
  this.query = config.query;
105
122
  this.checkConnection = config.checkConnection;
106
123
  this.setup = config.setup;
124
+ this.introspect = config.introspect;
107
125
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
126
+ this.surveyProbes = config.surveyProbes;
108
127
  }
109
128
  get connectorKey() {
110
129
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -112,7 +131,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
112
131
  /**
113
132
  * Create tools for connections that belong to this connector.
114
133
  * Filters connections by connectorKey internally.
115
- * Returns tools keyed as `${connectorKey}_${toolName}`.
134
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
116
135
  */
117
136
  createTools(connections, config, opts) {
118
137
  const myConnections = connections.filter(
@@ -122,7 +141,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
122
141
  for (const t of Object.values(this.tools)) {
123
142
  const tool = t.createTool(myConnections, config);
124
143
  const originalToModelOutput = tool.toModelOutput;
125
- result[`${this.connectorKey}_${t.name}`] = {
144
+ result[`connector_${this.connectorKey}_${t.name}`] = {
126
145
  ...tool,
127
146
  toModelOutput: async (options) => {
128
147
  if (!originalToModelOutput) {
@@ -142,25 +161,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
142
161
  if (authType) return `${slug}-${authType}`;
143
162
  const LEGACY_NULL_AUTH_TYPE_MAP = {
144
163
  // user-password
145
- "postgresql": "user-password",
146
- "mysql": "user-password",
147
- "clickhouse": "user-password",
148
- "kintone": "user-password",
164
+ postgresql: "user-password",
165
+ mysql: "user-password",
166
+ clickhouse: "user-password",
167
+ kintone: "user-password",
149
168
  "squadbase-db": "user-password",
150
169
  // service-account
151
- "snowflake": "service-account",
152
- "bigquery": "service-account",
170
+ snowflake: "service-account",
171
+ bigquery: "service-account",
153
172
  "google-analytics": "service-account",
154
173
  "google-calendar": "service-account",
155
174
  "aws-athena": "service-account",
156
- "redshift": "service-account",
175
+ redshift: "service-account",
157
176
  // api-key
158
- "databricks": "api-key",
159
- "dbt": "api-key",
160
- "airtable": "api-key",
161
- "openai": "api-key",
162
- "gemini": "api-key",
163
- "anthropic": "api-key",
177
+ databricks: "api-key",
178
+ dbt: "api-key",
179
+ airtable: "api-key",
180
+ openai: "api-key",
181
+ gemini: "api-key",
182
+ anthropic: "api-key",
164
183
  "wix-store": "api-key"
165
184
  };
166
185
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -384,11 +403,11 @@ var shopifyOauthOnboarding = new ConnectorOnboarding({
384
403
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
385
404
  },
386
405
  dataOverviewInstructions: {
387
- en: `1. Call shopify-oauth_request with GET /admin/api/2024-10/products.json?limit=5 to explore products structure
388
- 2. Call shopify-oauth_request with GET /admin/api/2024-10/orders.json?limit=5 to explore orders structure
406
+ en: `1. Call connector_shopify-oauth_request with GET /admin/api/2024-10/products.json?limit=5 to explore products structure
407
+ 2. Call connector_shopify-oauth_request with GET /admin/api/2024-10/orders.json?limit=5 to explore orders structure
389
408
  3. Explore other endpoints (customers, inventory, collections) as needed`,
390
- ja: `1. shopify-oauth_request \u3067 GET /admin/api/2024-10/products.json?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u5546\u54C1\u306E\u69CB\u9020\u3092\u78BA\u8A8D
391
- 2. shopify-oauth_request \u3067 GET /admin/api/2024-10/orders.json?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u6CE8\u6587\u306E\u69CB\u9020\u3092\u78BA\u8A8D
409
+ ja: `1. connector_shopify-oauth_request \u3067 GET /admin/api/2024-10/products.json?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u5546\u54C1\u306E\u69CB\u9020\u3092\u78BA\u8A8D
410
+ 2. connector_shopify-oauth_request \u3067 GET /admin/api/2024-10/orders.json?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u6CE8\u6587\u306E\u69CB\u9020\u3092\u78BA\u8A8D
392
411
  3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\u9867\u5BA2\u3001\u5728\u5EAB\u3001\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\uFF09\u3092\u63A2\u7D22`
393
412
  }
394
413
  });
@@ -450,6 +469,9 @@ var shopifyOauthSetupFlow = {
450
469
  (e) => ENTITY_VALUES.includes(e)
451
470
  ).slice(0, SHOPIFY_OAUTH_SETUP_MAX_ENTITIES);
452
471
  const sections = ["## Shopify", ""];
472
+ sections.push("### Entity counts", "");
473
+ sections.push("| Entity | Count |");
474
+ sections.push("|--------|-------|");
453
475
  for (const entity of selected) {
454
476
  const path2 = COUNT_PATHS[entity];
455
477
  let count = "available";
@@ -460,8 +482,38 @@ var shopifyOauthSetupFlow = {
460
482
  if (typeof data.count === "number") count = String(data.count);
461
483
  }
462
484
  }
463
- sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
464
- sections.push(`Count: ${count}`, "");
485
+ sections.push(`| ${ENTITY_LABELS[entity].en} | ${count} |`);
486
+ }
487
+ sections.push("");
488
+ if (selected.includes("orders")) {
489
+ try {
490
+ const ordersRes = await rt.config.proxyFetch(
491
+ `/admin/api/${SHOPIFY_API_VERSION}/orders.json?limit=5&status=any&order=created_at+desc`,
492
+ { method: "GET" }
493
+ );
494
+ if (ordersRes.ok) {
495
+ const ordersData = await ordersRes.json();
496
+ const orders = ordersData.orders ?? [];
497
+ if (orders.length > 0) {
498
+ sections.push("### Recent orders (sample)", "");
499
+ sections.push(
500
+ "| Order | Total | Status | Created |"
501
+ );
502
+ sections.push(
503
+ "|-------|-------|--------|---------|"
504
+ );
505
+ for (const o of orders.slice(0, 5)) {
506
+ const name = (o.name ?? `#${o.order_number ?? "?"}`).replace(/\|/g, "\\|");
507
+ const total = o.total_price ? `${o.total_price} ${o.currency ?? ""}`.trim() : "-";
508
+ const status = o.financial_status ?? "-";
509
+ const created = o.created_at ? o.created_at.slice(0, 10) : "-";
510
+ sections.push(`| ${name} | ${total} | ${status} | ${created} |`);
511
+ }
512
+ sections.push("");
513
+ }
514
+ }
515
+ } catch {
516
+ }
465
517
  }
466
518
  return sections.join("\n");
467
519
  }
@@ -491,7 +543,7 @@ var shopifyOauthConnector = new ConnectorPlugin({
491
543
  systemPrompt: {
492
544
  en: `### Tools
493
545
 
494
- - \`shopify-oauth_request\`: The only way to call the Shopify Admin REST API. Use it to query products, orders, customers, inventory, collections, and more. Authentication is configured automatically via OAuth proxy. Shopify uses cursor-based pagination via the \`page_info\` query parameter (obtained from the Link header in the response).
546
+ - \`connector_shopify-oauth_request\`: The only way to call the Shopify Admin REST API. Use it to query products, orders, customers, inventory, collections, and more. Authentication is configured automatically via OAuth proxy. Shopify uses cursor-based pagination via the \`page_info\` query parameter (obtained from the Link header in the response).
495
547
 
496
548
  ### Shopify Admin REST API Reference
497
549
 
@@ -538,7 +590,7 @@ const data = await res.json();
538
590
  \`\`\``,
539
591
  ja: `### \u30C4\u30FC\u30EB
540
592
 
541
- - \`shopify-oauth_request\`: Shopify Admin REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u5546\u54C1\u3001\u6CE8\u6587\u3001\u9867\u5BA2\u3001\u5728\u5EAB\u3001\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Shopify\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E Link \u30D8\u30C3\u30C0\u30FC\u304B\u3089\u53D6\u5F97\u3059\u308B \`page_info\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
593
+ - \`connector_shopify-oauth_request\`: Shopify Admin REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u5546\u54C1\u3001\u6CE8\u6587\u3001\u9867\u5BA2\u3001\u5728\u5EAB\u3001\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Shopify\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E Link \u30D8\u30C3\u30C0\u30FC\u304B\u3089\u53D6\u5F97\u3059\u308B \`page_info\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
542
594
 
543
595
  ### Shopify Admin REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
544
596