@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
@@ -105,6 +110,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
105
110
  * `runSetupFlow` from `setup-flow.ts`.
106
111
  */
107
112
  setup;
113
+ /**
114
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
115
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
116
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
117
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
118
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
119
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
120
+ */
121
+ introspect;
108
122
  /**
109
123
  * Opt-out of the default "verify before save" behavior on connection
110
124
  * creation. The backend invokes `checkConnection` synchronously while
@@ -119,6 +133,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
119
133
  * the default verify-on-create behavior without opt-in.
120
134
  */
121
135
  skipConnectionCheckOnCreate;
136
+ /**
137
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
138
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
139
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
140
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
141
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
142
+ */
143
+ surveyProbes;
122
144
  constructor(config) {
123
145
  this.slug = config.slug;
124
146
  this.authType = config.authType;
@@ -136,7 +158,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
136
158
  this.query = config.query;
137
159
  this.checkConnection = config.checkConnection;
138
160
  this.setup = config.setup;
161
+ this.introspect = config.introspect;
139
162
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
163
+ this.surveyProbes = config.surveyProbes;
140
164
  }
141
165
  get connectorKey() {
142
166
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -144,7 +168,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
144
168
  /**
145
169
  * Create tools for connections that belong to this connector.
146
170
  * Filters connections by connectorKey internally.
147
- * Returns tools keyed as `${connectorKey}_${toolName}`.
171
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
148
172
  */
149
173
  createTools(connections, config, opts) {
150
174
  const myConnections = connections.filter(
@@ -154,7 +178,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
154
178
  for (const t of Object.values(this.tools)) {
155
179
  const tool = t.createTool(myConnections, config);
156
180
  const originalToModelOutput = tool.toModelOutput;
157
- result[`${this.connectorKey}_${t.name}`] = {
181
+ result[`connector_${this.connectorKey}_${t.name}`] = {
158
182
  ...tool,
159
183
  toModelOutput: async (options) => {
160
184
  if (!originalToModelOutput) {
@@ -174,25 +198,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
174
198
  if (authType) return `${slug}-${authType}`;
175
199
  const LEGACY_NULL_AUTH_TYPE_MAP = {
176
200
  // user-password
177
- "postgresql": "user-password",
178
- "mysql": "user-password",
179
- "clickhouse": "user-password",
180
- "kintone": "user-password",
201
+ postgresql: "user-password",
202
+ mysql: "user-password",
203
+ clickhouse: "user-password",
204
+ kintone: "user-password",
181
205
  "squadbase-db": "user-password",
182
206
  // service-account
183
- "snowflake": "service-account",
184
- "bigquery": "service-account",
207
+ snowflake: "service-account",
208
+ bigquery: "service-account",
185
209
  "google-analytics": "service-account",
186
210
  "google-calendar": "service-account",
187
211
  "aws-athena": "service-account",
188
- "redshift": "service-account",
212
+ redshift: "service-account",
189
213
  // api-key
190
- "databricks": "api-key",
191
- "dbt": "api-key",
192
- "airtable": "api-key",
193
- "openai": "api-key",
194
- "gemini": "api-key",
195
- "anthropic": "api-key",
214
+ databricks: "api-key",
215
+ dbt: "api-key",
216
+ airtable: "api-key",
217
+ openai: "api-key",
218
+ gemini: "api-key",
219
+ anthropic: "api-key",
196
220
  "wix-store": "api-key"
197
221
  };
198
222
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -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
@@ -275,6 +280,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
275
280
  * `runSetupFlow` from `setup-flow.ts`.
276
281
  */
277
282
  setup;
283
+ /**
284
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
285
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
286
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
287
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
288
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
289
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
290
+ */
291
+ introspect;
278
292
  /**
279
293
  * Opt-out of the default "verify before save" behavior on connection
280
294
  * creation. The backend invokes `checkConnection` synchronously while
@@ -289,6 +303,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
289
303
  * the default verify-on-create behavior without opt-in.
290
304
  */
291
305
  skipConnectionCheckOnCreate;
306
+ /**
307
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
308
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
309
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
310
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
311
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
312
+ */
313
+ surveyProbes;
292
314
  constructor(config) {
293
315
  this.slug = config.slug;
294
316
  this.authType = config.authType;
@@ -306,7 +328,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
306
328
  this.query = config.query;
307
329
  this.checkConnection = config.checkConnection;
308
330
  this.setup = config.setup;
331
+ this.introspect = config.introspect;
309
332
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
333
+ this.surveyProbes = config.surveyProbes;
310
334
  }
311
335
  get connectorKey() {
312
336
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -314,7 +338,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
314
338
  /**
315
339
  * Create tools for connections that belong to this connector.
316
340
  * Filters connections by connectorKey internally.
317
- * Returns tools keyed as `${connectorKey}_${toolName}`.
341
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
318
342
  */
319
343
  createTools(connections, config, opts) {
320
344
  const myConnections = connections.filter(
@@ -324,7 +348,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
324
348
  for (const t of Object.values(this.tools)) {
325
349
  const tool = t.createTool(myConnections, config);
326
350
  const originalToModelOutput = tool.toModelOutput;
327
- result[`${this.connectorKey}_${t.name}`] = {
351
+ result[`connector_${this.connectorKey}_${t.name}`] = {
328
352
  ...tool,
329
353
  toModelOutput: async (options) => {
330
354
  if (!originalToModelOutput) {
@@ -344,25 +368,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
344
368
  if (authType) return `${slug}-${authType}`;
345
369
  const LEGACY_NULL_AUTH_TYPE_MAP = {
346
370
  // user-password
347
- "postgresql": "user-password",
348
- "mysql": "user-password",
349
- "clickhouse": "user-password",
350
- "kintone": "user-password",
371
+ postgresql: "user-password",
372
+ mysql: "user-password",
373
+ clickhouse: "user-password",
374
+ kintone: "user-password",
351
375
  "squadbase-db": "user-password",
352
376
  // service-account
353
- "snowflake": "service-account",
354
- "bigquery": "service-account",
377
+ snowflake: "service-account",
378
+ bigquery: "service-account",
355
379
  "google-analytics": "service-account",
356
380
  "google-calendar": "service-account",
357
381
  "aws-athena": "service-account",
358
- "redshift": "service-account",
382
+ redshift: "service-account",
359
383
  // api-key
360
- "databricks": "api-key",
361
- "dbt": "api-key",
362
- "airtable": "api-key",
363
- "openai": "api-key",
364
- "gemini": "api-key",
365
- "anthropic": "api-key",
384
+ databricks: "api-key",
385
+ dbt: "api-key",
386
+ airtable: "api-key",
387
+ openai: "api-key",
388
+ gemini: "api-key",
389
+ anthropic: "api-key",
366
390
  "wix-store": "api-key"
367
391
  };
368
392
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -464,13 +488,13 @@ function normalizeRequestPath(path2, basePathSegment) {
464
488
  // ../connectors/src/connectors/asana/setup.ts
465
489
  var asanaOnboarding = new ConnectorOnboarding({
466
490
  dataOverviewInstructions: {
467
- en: `1. Call asana_request with GET /workspaces to list all available workspaces
468
- 2. Pick the first workspace and call asana_request with GET /projects?workspace=WORKSPACE_GID&opt_fields=name,archived,created_at to list projects
469
- 3. Pick one project and call asana_request with GET /tasks?project=PROJECT_GID&opt_fields=name,completed,assignee.name,due_on,created_at&limit=10 to sample tasks
491
+ en: `1. Call connector_asana_request with GET /workspaces to list all available workspaces
492
+ 2. Pick the first workspace and call connector_asana_request with GET /projects?workspace=WORKSPACE_GID&opt_fields=name,archived,created_at to list projects
493
+ 3. Pick one project and call connector_asana_request with GET /tasks?project=PROJECT_GID&opt_fields=name,completed,assignee.name,due_on,created_at&limit=10 to sample tasks
470
494
  4. Explore sections via GET /sections?project=PROJECT_GID if the project uses board or section-based workflows`,
471
- ja: `1. asana_request \u3067 GET /workspaces \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97
472
- 2. \u6700\u521D\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092\u9078\u3073\u3001asana_request \u3067 GET /projects?workspace=WORKSPACE_GID&opt_fields=name,archived,created_at \u3092\u547C\u3073\u51FA\u3057\u3066\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
473
- 3. \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30921\u3064\u9078\u3073\u3001asana_request \u3067 GET /tasks?project=PROJECT_GID&opt_fields=name,completed,assignee.name,due_on,created_at&limit=10 \u3092\u547C\u3073\u51FA\u3057\u3066\u30BF\u30B9\u30AF\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
495
+ ja: `1. connector_asana_request \u3067 GET /workspaces \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97
496
+ 2. \u6700\u521D\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092\u9078\u3073\u3001connector_asana_request \u3067 GET /projects?workspace=WORKSPACE_GID&opt_fields=name,archived,created_at \u3092\u547C\u3073\u51FA\u3057\u3066\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
497
+ 3. \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30921\u3064\u9078\u3073\u3001connector_asana_request \u3067 GET /tasks?project=PROJECT_GID&opt_fields=name,completed,assignee.name,due_on,created_at&limit=10 \u3092\u547C\u3073\u51FA\u3057\u3066\u30BF\u30B9\u30AF\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
474
498
  4. \u30DC\u30FC\u30C9\u3084\u30BB\u30AF\u30B7\u30E7\u30F3\u30D9\u30FC\u30B9\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E\u5834\u5408\u306F GET /sections?project=PROJECT_GID \u3067\u30BB\u30AF\u30B7\u30E7\u30F3\u3092\u78BA\u8A8D`
475
499
  }
476
500
  });
@@ -501,6 +525,26 @@ async function listWorkspaces(params) {
501
525
  const data = await res.json();
502
526
  return data.data ?? [];
503
527
  }
528
+ async function getTaskBreakdown(params, projectGid) {
529
+ try {
530
+ const res = await apiFetch(
531
+ params,
532
+ `/projects/${encodeURIComponent(projectGid)}/tasks?limit=100&opt_fields=completed`
533
+ );
534
+ if (!res.ok) return null;
535
+ const data = await res.json();
536
+ const tasks = data.data ?? [];
537
+ const completed = tasks.filter((t) => t.completed).length;
538
+ const hasMore = !!data.next_page?.offset;
539
+ return {
540
+ total: tasks.length + (hasMore ? 100 : 0),
541
+ completed,
542
+ incomplete: tasks.length - completed
543
+ };
544
+ } catch {
545
+ return null;
546
+ }
547
+ }
504
548
  async function listProjects(params, workspaceGid) {
505
549
  const all = [];
506
550
  const fields = encodeURIComponent("name,team.name,current_status");
@@ -589,6 +633,13 @@ var asanaSetupFlow = {
589
633
  const status = project.current_status?.title ?? project.current_status?.text ?? "-";
590
634
  sections.push(`- Team: ${team}`);
591
635
  sections.push(`- Current status: ${status}`);
636
+ const tasks = await getTaskBreakdown(rt.params, gid);
637
+ if (tasks) {
638
+ const suffix = tasks.total >= 100 ? "+" : "";
639
+ sections.push(
640
+ `- Tasks: ${tasks.total}${suffix} (${tasks.completed} completed, ${tasks.incomplete} incomplete)`
641
+ );
642
+ }
592
643
  sections.push("");
593
644
  }
594
645
  return sections.join("\n");
@@ -710,7 +761,7 @@ var asanaConnector = new ConnectorPlugin({
710
761
  systemPrompt: {
711
762
  en: `### Tools
712
763
 
713
- - \`asana_request\`: The only way to call the Asana REST API. Use it to list workspaces, projects, tasks, users, sections, tags, and more. Authentication (Bearer token with Personal Access Token) is configured automatically. Provide the API path and optionally append query parameters like opt_fields for field selection.
764
+ - \`connector_asana_request\`: The only way to call the Asana REST API. Use it to list workspaces, projects, tasks, users, sections, tags, and more. Authentication (Bearer token with Personal Access Token) is configured automatically. Provide the API path and optionally append query parameters like opt_fields for field selection.
714
765
 
715
766
  ### Business Logic
716
767
 
@@ -797,7 +848,7 @@ export default async function handler(c: Context) {
797
848
  - Users: name, email, photo`,
798
849
  ja: `### \u30C4\u30FC\u30EB
799
850
 
800
- - \`asana_request\`: Asana REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3001\u30BF\u30B9\u30AF\u3001\u30E6\u30FC\u30B6\u30FC\u3001\u30BB\u30AF\u30B7\u30E7\u30F3\u3001\u30BF\u30B0\u306A\u3069\u306E\u4E00\u89A7\u53D6\u5F97\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Personal Access Token\u3092\u4F7F\u7528\u3057\u305FBearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002API\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u3001\u5FC5\u8981\u306B\u5FDC\u3058\u3066opt_fields\u306A\u3069\u306E\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4ED8\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002
851
+ - \`connector_asana_request\`: Asana REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3001\u30BF\u30B9\u30AF\u3001\u30E6\u30FC\u30B6\u30FC\u3001\u30BB\u30AF\u30B7\u30E7\u30F3\u3001\u30BF\u30B0\u306A\u3069\u306E\u4E00\u89A7\u53D6\u5F97\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Personal Access Token\u3092\u4F7F\u7528\u3057\u305FBearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002API\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u3001\u5FC5\u8981\u306B\u5FDC\u3058\u3066opt_fields\u306A\u3069\u306E\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4ED8\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002
801
852
 
802
853
  ### Business Logic
803
854
 
@@ -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
@@ -411,6 +416,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
411
416
  * `runSetupFlow` from `setup-flow.ts`.
412
417
  */
413
418
  setup;
419
+ /**
420
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
421
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
422
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
423
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
424
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
425
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
426
+ */
427
+ introspect;
414
428
  /**
415
429
  * Opt-out of the default "verify before save" behavior on connection
416
430
  * creation. The backend invokes `checkConnection` synchronously while
@@ -425,6 +439,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
425
439
  * the default verify-on-create behavior without opt-in.
426
440
  */
427
441
  skipConnectionCheckOnCreate;
442
+ /**
443
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
444
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
445
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
446
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
447
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
448
+ */
449
+ surveyProbes;
428
450
  constructor(config) {
429
451
  this.slug = config.slug;
430
452
  this.authType = config.authType;
@@ -442,7 +464,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
442
464
  this.query = config.query;
443
465
  this.checkConnection = config.checkConnection;
444
466
  this.setup = config.setup;
467
+ this.introspect = config.introspect;
445
468
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
469
+ this.surveyProbes = config.surveyProbes;
446
470
  }
447
471
  get connectorKey() {
448
472
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -450,7 +474,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
450
474
  /**
451
475
  * Create tools for connections that belong to this connector.
452
476
  * Filters connections by connectorKey internally.
453
- * Returns tools keyed as `${connectorKey}_${toolName}`.
477
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
454
478
  */
455
479
  createTools(connections, config, opts) {
456
480
  const myConnections = connections.filter(
@@ -460,7 +484,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
460
484
  for (const t of Object.values(this.tools)) {
461
485
  const tool = t.createTool(myConnections, config);
462
486
  const originalToModelOutput = tool.toModelOutput;
463
- result[`${this.connectorKey}_${t.name}`] = {
487
+ result[`connector_${this.connectorKey}_${t.name}`] = {
464
488
  ...tool,
465
489
  toModelOutput: async (options) => {
466
490
  if (!originalToModelOutput) {
@@ -480,25 +504,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
480
504
  if (authType) return `${slug}-${authType}`;
481
505
  const LEGACY_NULL_AUTH_TYPE_MAP = {
482
506
  // user-password
483
- "postgresql": "user-password",
484
- "mysql": "user-password",
485
- "clickhouse": "user-password",
486
- "kintone": "user-password",
507
+ postgresql: "user-password",
508
+ mysql: "user-password",
509
+ clickhouse: "user-password",
510
+ kintone: "user-password",
487
511
  "squadbase-db": "user-password",
488
512
  // service-account
489
- "snowflake": "service-account",
490
- "bigquery": "service-account",
513
+ snowflake: "service-account",
514
+ bigquery: "service-account",
491
515
  "google-analytics": "service-account",
492
516
  "google-calendar": "service-account",
493
517
  "aws-athena": "service-account",
494
- "redshift": "service-account",
518
+ redshift: "service-account",
495
519
  // api-key
496
- "databricks": "api-key",
497
- "dbt": "api-key",
498
- "airtable": "api-key",
499
- "openai": "api-key",
500
- "gemini": "api-key",
501
- "anthropic": "api-key",
520
+ databricks: "api-key",
521
+ dbt: "api-key",
522
+ airtable: "api-key",
523
+ openai: "api-key",
524
+ gemini: "api-key",
525
+ anthropic: "api-key",
502
526
  "wix-store": "api-key"
503
527
  };
504
528
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -590,16 +614,16 @@ var AUTH_TYPES = {
590
614
  // ../connectors/src/connectors/attio/setup.ts
591
615
  var attioOnboarding = new ConnectorOnboarding({
592
616
  dataOverviewInstructions: {
593
- en: `1. Call attio_request with GET /objects to discover the object slugs actually configured in this workspace (typically people, companies, deals, plus any custom objects).
594
- 2. For each object you plan to use, call attio_request with GET /objects/{slug}/attributes to explore its attributes
595
- 3. Call attio_request with POST /objects/{slug}/records/query with { "limit": 5 } to sample records
596
- 4. Call attio_request with GET /workspace_members (top-level, snake_case) to list team members. The response shape is \`{ data: [{ id: { workspace_member_id }, first_name, last_name, email_address, ... }] }\`. You need this mapping in dashboard handlers to resolve \`owner\` and other actor-reference fields (which return \`referenced_actor_id\`, not a name). Sample one record that has an \`owner\` and confirm the shape \`{ referenced_actor_type, referenced_actor_id }\`, then use \`client.getWorkspaceMemberMap()\` in handlers to resolve IDs to names.
617
+ en: `1. Call connector_attio_request with GET /objects to discover the object slugs actually configured in this workspace (typically people, companies, deals, plus any custom objects).
618
+ 2. For each object you plan to use, call connector_attio_request with GET /objects/{slug}/attributes to explore its attributes
619
+ 3. Call connector_attio_request with POST /objects/{slug}/records/query with { "limit": 5 } to sample records
620
+ 4. Call connector_attio_request with GET /workspace_members (top-level, snake_case) to list team members. The response shape is \`{ data: [{ id: { workspace_member_id }, first_name, last_name, email_address, ... }] }\`. You need this mapping in dashboard handlers to resolve \`owner\` and other actor-reference fields (which return \`referenced_actor_id\`, not a name). Sample one record that has an \`owner\` and confirm the shape \`{ referenced_actor_type, referenced_actor_id }\`, then use \`client.getWorkspaceMemberMap()\` in handlers to resolve IDs to names.
597
621
  5. If an endpoint later returns 403 (tasks / threads / webhooks / meetings require specific scopes), call GET /self to inspect the token's active scopes.
598
622
  6. Explore lists via GET /lists as needed, and use /notes, /tasks, /threads, /comments, /webhooks, /meetings when the question requires them.`,
599
- ja: `1. attio_request \u3067 GET /objects \u3092\u547C\u3073\u51FA\u3057\u3001\u3053\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B\u5B9F\u5728\u3059\u308B\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8slug\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u901A\u5E38\u306F people / companies / deals\u3001\u52A0\u3048\u3066\u8A2D\u5B9A\u6E08\u307F\u306E\u30AB\u30B9\u30BF\u30E0\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\uFF09
600
- 2. \u4F7F\u3046\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3054\u3068\u306B attio_request \u3067 GET /objects/{slug}/attributes \u3092\u547C\u3073\u51FA\u3057\u3001\u5C5E\u6027\u3092\u78BA\u8A8D
601
- 3. attio_request \u3067 POST /objects/{slug}/records/query \u3092 { "limit": 5 } \u3067\u547C\u3073\u51FA\u3057\u3001\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
602
- 4. attio_request \u3067 GET /workspace_members\uFF08\u30C8\u30C3\u30D7\u30EC\u30D9\u30EB\u3001\u30B9\u30CD\u30FC\u30AF\u30B1\u30FC\u30B9\uFF09\u3092\u547C\u3073\u51FA\u3057\u3001\u30C1\u30FC\u30E0\u30E1\u30F3\u30D0\u30FC\u4E00\u89A7\u3092\u53D6\u5F97\u3002\u30EC\u30B9\u30DD\u30F3\u30B9\u306F \`{ data: [{ id: { workspace_member_id }, first_name, last_name, email_address, ... }] }\` \u306E\u5F62\u5F0F\u3067\u3059\u3002\u3053\u306E\u30DE\u30C3\u30D4\u30F3\u30B0\u306F\u3001\`owner\` \u306A\u3069\u306E actor-reference \u30D5\u30A3\u30FC\u30EB\u30C9\uFF08\`referenced_actor_id\` \u3092\u8FD4\u3059\uFF09\u3092\u540D\u524D\u306B\u89E3\u6C7A\u3059\u308B\u305F\u3081\u306B\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u30CF\u30F3\u30C9\u30E9\u3067\u5FC5\u9808\u3067\u3059\u3002\`owner\` \u3092\u6301\u3064\u30EC\u30B3\u30FC\u30C9\u30921\u4EF6\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u3001\`{ referenced_actor_type, referenced_actor_id }\` \u306E\u5F62\u3092\u78BA\u8A8D\u3057\u305F\u4E0A\u3067\u3001\u30CF\u30F3\u30C9\u30E9\u3067\u306F \`client.getWorkspaceMemberMap()\` \u3092\u4F7F\u3063\u3066 ID \u2192 \u540D\u524D \u306B\u89E3\u6C7A\u3057\u3066\u304F\u3060\u3055\u3044
623
+ ja: `1. connector_attio_request \u3067 GET /objects \u3092\u547C\u3073\u51FA\u3057\u3001\u3053\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B\u5B9F\u5728\u3059\u308B\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8slug\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u901A\u5E38\u306F people / companies / deals\u3001\u52A0\u3048\u3066\u8A2D\u5B9A\u6E08\u307F\u306E\u30AB\u30B9\u30BF\u30E0\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\uFF09
624
+ 2. \u4F7F\u3046\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3054\u3068\u306B connector_attio_request \u3067 GET /objects/{slug}/attributes \u3092\u547C\u3073\u51FA\u3057\u3001\u5C5E\u6027\u3092\u78BA\u8A8D
625
+ 3. connector_attio_request \u3067 POST /objects/{slug}/records/query \u3092 { "limit": 5 } \u3067\u547C\u3073\u51FA\u3057\u3001\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
626
+ 4. connector_attio_request \u3067 GET /workspace_members\uFF08\u30C8\u30C3\u30D7\u30EC\u30D9\u30EB\u3001\u30B9\u30CD\u30FC\u30AF\u30B1\u30FC\u30B9\uFF09\u3092\u547C\u3073\u51FA\u3057\u3001\u30C1\u30FC\u30E0\u30E1\u30F3\u30D0\u30FC\u4E00\u89A7\u3092\u53D6\u5F97\u3002\u30EC\u30B9\u30DD\u30F3\u30B9\u306F \`{ data: [{ id: { workspace_member_id }, first_name, last_name, email_address, ... }] }\` \u306E\u5F62\u5F0F\u3067\u3059\u3002\u3053\u306E\u30DE\u30C3\u30D4\u30F3\u30B0\u306F\u3001\`owner\` \u306A\u3069\u306E actor-reference \u30D5\u30A3\u30FC\u30EB\u30C9\uFF08\`referenced_actor_id\` \u3092\u8FD4\u3059\uFF09\u3092\u540D\u524D\u306B\u89E3\u6C7A\u3059\u308B\u305F\u3081\u306B\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u30CF\u30F3\u30C9\u30E9\u3067\u5FC5\u9808\u3067\u3059\u3002\`owner\` \u3092\u6301\u3064\u30EC\u30B3\u30FC\u30C9\u30921\u4EF6\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u3001\`{ referenced_actor_type, referenced_actor_id }\` \u306E\u5F62\u3092\u78BA\u8A8D\u3057\u305F\u4E0A\u3067\u3001\u30CF\u30F3\u30C9\u30E9\u3067\u306F \`client.getWorkspaceMemberMap()\` \u3092\u4F7F\u3063\u3066 ID \u2192 \u540D\u524D \u306B\u89E3\u6C7A\u3057\u3066\u304F\u3060\u3055\u3044
603
627
  5. \u5F8C\u6BB5\u3067 403 \u304C\u51FA\u305F\u5834\u5408\uFF08tasks / threads / webhooks / meetings \u306A\u3069\u306F\u500B\u5225\u306E scope \u304C\u5FC5\u8981\uFF09\u306F\u3001GET /self \u3092\u547C\u3073\u51FA\u3057\u3066API\u30C8\u30FC\u30AF\u30F3\u306E\u6709\u52B9 scope \u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044
604
628
  6. \u5FC5\u8981\u306B\u5FDC\u3058\u3066 GET /lists \u3067\u30EA\u30B9\u30C8\u3092\u63A2\u7D22\u3057\u3001/notes\u3001/tasks\u3001/threads\u3001/comments\u3001/webhooks\u3001/meetings \u3082\u6D3B\u7528\u3057\u3066\u304F\u3060\u3055\u3044`
605
629
  }
@@ -642,6 +666,21 @@ async function listAttributes(params, slug) {
642
666
  const data = await res.json();
643
667
  return data.data ?? [];
644
668
  }
669
+ async function probeRecordCount(params, slug) {
670
+ try {
671
+ const res = await apiFetch(params, `/objects/${slug}/records/query`, {
672
+ method: "POST",
673
+ headers: { "Content-Type": "application/json" },
674
+ body: JSON.stringify({ limit: 1 })
675
+ });
676
+ if (!res.ok) return null;
677
+ const data = await res.json();
678
+ const found = (data.data ?? []).length;
679
+ return found > 0 ? "1+" : "0";
680
+ } catch {
681
+ return null;
682
+ }
683
+ }
645
684
  var attioSetupFlow = {
646
685
  initialState: () => ({}),
647
686
  steps: [
@@ -677,7 +716,9 @@ var attioSetupFlow = {
677
716
  });
678
717
  const sections = ["## Attio", ""];
679
718
  for (const slug of targetObjects) {
680
- sections.push(`### Object: ${slug}`, "");
719
+ const recordIndicator = await probeRecordCount(rt.params, slug);
720
+ const heading = recordIndicator ? `### Object: ${slug} (records: ${recordIndicator})` : `### Object: ${slug}`;
721
+ sections.push(heading, "");
681
722
  const attrs = await listAttributes(rt.params, slug);
682
723
  const limited = attrs.slice(0, ATTIO_SETUP_MAX_ATTRIBUTES);
683
724
  sections.push("| Attribute | Type | Title |");
@@ -793,7 +834,7 @@ var attioConnector = new ConnectorPlugin({
793
834
  systemPrompt: {
794
835
  en: `### Tools
795
836
 
796
- - \`attio_request\`: The only way to call the Attio REST API. Use it for every Attio resource \u2014 records (people, companies, deals, and any custom objects configured in the workspace), their attributes, lists and entries, workspace members, notes, tasks, threads, comments, webhooks, and meetings. Authentication (Bearer token) is configured automatically. Querying records uses POST \`/objects/{object}/records/query\` with a JSON body. Use PATCH for partial updates (append multiselect) and PUT for full updates (overwrite multiselect). Always call GET \`/objects\` first to discover the actual object slugs in this workspace.
837
+ - \`connector_attio_request\`: The only way to call the Attio REST API. Use it for every Attio resource \u2014 records (people, companies, deals, and any custom objects configured in the workspace), their attributes, lists and entries, workspace members, notes, tasks, threads, comments, webhooks, and meetings. Authentication (Bearer token) is configured automatically. Querying records uses POST \`/objects/{object}/records/query\` with a JSON body. Use PATCH for partial updates (append multiselect) and PUT for full updates (overwrite multiselect). Always call GET \`/objects\` first to discover the actual object slugs in this workspace.
797
838
 
798
839
  ### Business Logic
799
840
 
@@ -940,7 +981,7 @@ export default async function handler(c: Context) {
940
981
  - \`offset\` \u2014 pagination offset`,
941
982
  ja: `### \u30C4\u30FC\u30EB
942
983
 
943
- - \`attio_request\`: Attio REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EC\u30B3\u30FC\u30C9\uFF08people\u3001companies\u3001deals\u3001\u304A\u3088\u3073\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30AB\u30B9\u30BF\u30E0\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\uFF09\u3068\u305D\u306E\u5C5E\u6027\u3001\u30EA\u30B9\u30C8\u3068\u30A8\u30F3\u30C8\u30EA\u3001\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u30E1\u30F3\u30D0\u30FC\u3001\u30CE\u30FC\u30C8\u3001\u30BF\u30B9\u30AF\u3001\u30B9\u30EC\u30C3\u30C9\u3001\u30B3\u30E1\u30F3\u30C8\u3001Webhook\u3001\u30DF\u30FC\u30C6\u30A3\u30F3\u30B0\u306A\u3069\u3001\u3059\u3079\u3066\u306EAttio\u30EA\u30BD\u30FC\u30B9\u306E\u64CD\u4F5C\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30EC\u30B3\u30FC\u30C9\u306E\u30AF\u30A8\u30EA\u306B\u306F POST \`/objects/{object}/records/query\` \u3092\u30D5\u30A3\u30EB\u30BF\u4ED8\u304D\u306EJSON\u30DC\u30C7\u30A3\u3067\u4F7F\u7528\u3057\u307E\u3059\u3002\u90E8\u5206\u66F4\u65B0\uFF08multiselect\u306E\u8FFD\u52A0\uFF09\u306B\u306FPATCH\u3001\u5168\u7F6E\u63DB\uFF08multiselect\u306E\u4E0A\u66F8\u304D\uFF09\u306B\u306FPUT\u3092\u4F7F\u3044\u307E\u3059\u3002**\u5FC5\u305A** \u6700\u521D\u306B GET \`/objects\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u3053\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B\u5B9F\u5728\u3059\u308B\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8slug\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
984
+ - \`connector_attio_request\`: Attio REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EC\u30B3\u30FC\u30C9\uFF08people\u3001companies\u3001deals\u3001\u304A\u3088\u3073\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30AB\u30B9\u30BF\u30E0\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\uFF09\u3068\u305D\u306E\u5C5E\u6027\u3001\u30EA\u30B9\u30C8\u3068\u30A8\u30F3\u30C8\u30EA\u3001\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u30E1\u30F3\u30D0\u30FC\u3001\u30CE\u30FC\u30C8\u3001\u30BF\u30B9\u30AF\u3001\u30B9\u30EC\u30C3\u30C9\u3001\u30B3\u30E1\u30F3\u30C8\u3001Webhook\u3001\u30DF\u30FC\u30C6\u30A3\u30F3\u30B0\u306A\u3069\u3001\u3059\u3079\u3066\u306EAttio\u30EA\u30BD\u30FC\u30B9\u306E\u64CD\u4F5C\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30EC\u30B3\u30FC\u30C9\u306E\u30AF\u30A8\u30EA\u306B\u306F POST \`/objects/{object}/records/query\` \u3092\u30D5\u30A3\u30EB\u30BF\u4ED8\u304D\u306EJSON\u30DC\u30C7\u30A3\u3067\u4F7F\u7528\u3057\u307E\u3059\u3002\u90E8\u5206\u66F4\u65B0\uFF08multiselect\u306E\u8FFD\u52A0\uFF09\u306B\u306FPATCH\u3001\u5168\u7F6E\u63DB\uFF08multiselect\u306E\u4E0A\u66F8\u304D\uFF09\u306B\u306FPUT\u3092\u4F7F\u3044\u307E\u3059\u3002**\u5FC5\u305A** \u6700\u521D\u306B GET \`/objects\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u3053\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B\u5B9F\u5728\u3059\u308B\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8slug\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
944
985
 
945
986
  ### Business Logic
946
987
 
@@ -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
@@ -177,6 +182,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
177
182
  * `runSetupFlow` from `setup-flow.ts`.
178
183
  */
179
184
  setup;
185
+ /**
186
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
187
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
188
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
189
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
190
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
191
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
192
+ */
193
+ introspect;
180
194
  /**
181
195
  * Opt-out of the default "verify before save" behavior on connection
182
196
  * creation. The backend invokes `checkConnection` synchronously while
@@ -191,6 +205,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
191
205
  * the default verify-on-create behavior without opt-in.
192
206
  */
193
207
  skipConnectionCheckOnCreate;
208
+ /**
209
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
210
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
211
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
212
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
213
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
214
+ */
215
+ surveyProbes;
194
216
  constructor(config) {
195
217
  this.slug = config.slug;
196
218
  this.authType = config.authType;
@@ -208,7 +230,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
208
230
  this.query = config.query;
209
231
  this.checkConnection = config.checkConnection;
210
232
  this.setup = config.setup;
233
+ this.introspect = config.introspect;
211
234
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
235
+ this.surveyProbes = config.surveyProbes;
212
236
  }
213
237
  get connectorKey() {
214
238
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -216,7 +240,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
216
240
  /**
217
241
  * Create tools for connections that belong to this connector.
218
242
  * Filters connections by connectorKey internally.
219
- * Returns tools keyed as `${connectorKey}_${toolName}`.
243
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
220
244
  */
221
245
  createTools(connections, config, opts) {
222
246
  const myConnections = connections.filter(
@@ -226,7 +250,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
226
250
  for (const t of Object.values(this.tools)) {
227
251
  const tool = t.createTool(myConnections, config);
228
252
  const originalToModelOutput = tool.toModelOutput;
229
- result[`${this.connectorKey}_${t.name}`] = {
253
+ result[`connector_${this.connectorKey}_${t.name}`] = {
230
254
  ...tool,
231
255
  toModelOutput: async (options) => {
232
256
  if (!originalToModelOutput) {
@@ -246,25 +270,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
246
270
  if (authType) return `${slug}-${authType}`;
247
271
  const LEGACY_NULL_AUTH_TYPE_MAP = {
248
272
  // user-password
249
- "postgresql": "user-password",
250
- "mysql": "user-password",
251
- "clickhouse": "user-password",
252
- "kintone": "user-password",
273
+ postgresql: "user-password",
274
+ mysql: "user-password",
275
+ clickhouse: "user-password",
276
+ kintone: "user-password",
253
277
  "squadbase-db": "user-password",
254
278
  // service-account
255
- "snowflake": "service-account",
256
- "bigquery": "service-account",
279
+ snowflake: "service-account",
280
+ bigquery: "service-account",
257
281
  "google-analytics": "service-account",
258
282
  "google-calendar": "service-account",
259
283
  "aws-athena": "service-account",
260
- "redshift": "service-account",
284
+ redshift: "service-account",
261
285
  // api-key
262
- "databricks": "api-key",
263
- "dbt": "api-key",
264
- "airtable": "api-key",
265
- "openai": "api-key",
266
- "gemini": "api-key",
267
- "anthropic": "api-key",
286
+ databricks: "api-key",
287
+ dbt: "api-key",
288
+ airtable: "api-key",
289
+ openai: "api-key",
290
+ gemini: "api-key",
291
+ anthropic: "api-key",
268
292
  "wix-store": "api-key"
269
293
  };
270
294
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -880,9 +904,9 @@ var awsBillingConnector = new ConnectorPlugin({
880
904
  systemPrompt: {
881
905
  en: `### Tools
882
906
 
883
- - \`aws-billing-service-account_getCostAndUsage\`: Primary tool for querying historical AWS cost and usage. Use it for spend breakdowns by service/account/region/usage-type, month-over-month comparisons, and identifying cost drivers. Pass a TimePeriod (YYYY-MM-DD), Granularity (DAILY/MONTHLY/HOURLY), Metrics, and optionally GroupBy / Filter. See the Cost Explorer Reference below for valid keys.
884
- - \`aws-billing-service-account_getDimensionValues\`: Enumerate the valid values for a single Cost Explorer dimension (e.g., list all SERVICE names, LINKED_ACCOUNT IDs, REGIONS). Use this before constructing a Filter so the Filter Expression contains valid values.
885
- - \`aws-billing-service-account_getCostForecast\`: Forecast future cost or usage. Use this for "what will spend look like next month" questions. The TimePeriod must be in the future.
907
+ - \`connector_aws-billing-service-account_getCostAndUsage\`: Primary tool for querying historical AWS cost and usage. Use it for spend breakdowns by service/account/region/usage-type, month-over-month comparisons, and identifying cost drivers. Pass a TimePeriod (YYYY-MM-DD), Granularity (DAILY/MONTHLY/HOURLY), Metrics, and optionally GroupBy / Filter. See the Cost Explorer Reference below for valid keys.
908
+ - \`connector_aws-billing-service-account_getDimensionValues\`: Enumerate the valid values for a single Cost Explorer dimension (e.g., list all SERVICE names, LINKED_ACCOUNT IDs, REGIONS). Use this before constructing a Filter so the Filter Expression contains valid values.
909
+ - \`connector_aws-billing-service-account_getCostForecast\`: Forecast future cost or usage. Use this for "what will spend look like next month" questions. The TimePeriod must be in the future.
886
910
 
887
911
  ### Cost Explorer Reference
888
912
 
@@ -965,9 +989,9 @@ export default async function handler(c: Context) {
965
989
  \`\`\``,
966
990
  ja: `### \u30C4\u30FC\u30EB
967
991
 
968
- - \`aws-billing-service-account_getCostAndUsage\`: AWS\u306E\u904E\u53BB\u306E\u30B3\u30B9\u30C8\u30FB\u4F7F\u7528\u91CF\u3092\u53D6\u5F97\u3059\u308B\u30E1\u30A4\u30F3\u30C4\u30FC\u30EB\u3002\u30B5\u30FC\u30D3\u30B9\u5225\u30FB\u30A2\u30AB\u30A6\u30F3\u30C8\u5225\u30FB\u30EA\u30FC\u30B8\u30E7\u30F3\u5225\u30FB\u5229\u7528\u30BF\u30A4\u30D7\u5225\u306E\u652F\u51FA\u5185\u8A33\u3001\u524D\u6708\u6BD4\u8F03\u3001\u4E3B\u8981\u30B3\u30B9\u30C8\u8981\u56E0\u306E\u7279\u5B9A\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002TimePeriod (YYYY-MM-DD)\u3001Granularity (DAILY/MONTHLY/HOURLY)\u3001Metrics\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u3067 GroupBy / Filter \u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u6709\u52B9\u306A\u30AD\u30FC\u306F\u4E0B\u8A18\u300CCost Explorer \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3002
969
- - \`aws-billing-service-account_getDimensionValues\`: \u5358\u4E00\u306ECost Explorer\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u306B\u3064\u3044\u3066\u6709\u52B9\u306A\u5024\u3092\u5217\u6319\u3057\u307E\u3059\uFF08\u4F8B: \u5168 SERVICE \u540D\u3001LINKED_ACCOUNT ID\u3001REGION \u306E\u53D6\u5F97\uFF09\u3002Filter \u3092\u69CB\u7BC9\u3059\u308B\u524D\u306B\u3053\u306E\u30C4\u30FC\u30EB\u3067\u6709\u52B9\u5024\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
970
- - \`aws-billing-service-account_getCostForecast\`: \u5C06\u6765\u306E\u30B3\u30B9\u30C8\u30FB\u4F7F\u7528\u91CF\u3092\u4E88\u6E2C\u3057\u307E\u3059\u3002\u300C\u6765\u6708\u306E\u652F\u51FA\u898B\u8FBC\u307F\u306F\uFF1F\u300D\u306E\u3088\u3046\u306A\u8CEA\u554F\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002TimePeriod \u306F\u672A\u6765\u306E\u65E5\u4ED8\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
992
+ - \`connector_aws-billing-service-account_getCostAndUsage\`: AWS\u306E\u904E\u53BB\u306E\u30B3\u30B9\u30C8\u30FB\u4F7F\u7528\u91CF\u3092\u53D6\u5F97\u3059\u308B\u30E1\u30A4\u30F3\u30C4\u30FC\u30EB\u3002\u30B5\u30FC\u30D3\u30B9\u5225\u30FB\u30A2\u30AB\u30A6\u30F3\u30C8\u5225\u30FB\u30EA\u30FC\u30B8\u30E7\u30F3\u5225\u30FB\u5229\u7528\u30BF\u30A4\u30D7\u5225\u306E\u652F\u51FA\u5185\u8A33\u3001\u524D\u6708\u6BD4\u8F03\u3001\u4E3B\u8981\u30B3\u30B9\u30C8\u8981\u56E0\u306E\u7279\u5B9A\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002TimePeriod (YYYY-MM-DD)\u3001Granularity (DAILY/MONTHLY/HOURLY)\u3001Metrics\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u3067 GroupBy / Filter \u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u6709\u52B9\u306A\u30AD\u30FC\u306F\u4E0B\u8A18\u300CCost Explorer \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3002
993
+ - \`connector_aws-billing-service-account_getDimensionValues\`: \u5358\u4E00\u306ECost Explorer\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u306B\u3064\u3044\u3066\u6709\u52B9\u306A\u5024\u3092\u5217\u6319\u3057\u307E\u3059\uFF08\u4F8B: \u5168 SERVICE \u540D\u3001LINKED_ACCOUNT ID\u3001REGION \u306E\u53D6\u5F97\uFF09\u3002Filter \u3092\u69CB\u7BC9\u3059\u308B\u524D\u306B\u3053\u306E\u30C4\u30FC\u30EB\u3067\u6709\u52B9\u5024\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
994
+ - \`connector_aws-billing-service-account_getCostForecast\`: \u5C06\u6765\u306E\u30B3\u30B9\u30C8\u30FB\u4F7F\u7528\u91CF\u3092\u4E88\u6E2C\u3057\u307E\u3059\u3002\u300C\u6765\u6708\u306E\u652F\u51FA\u898B\u8FBC\u307F\u306F\uFF1F\u300D\u306E\u3088\u3046\u306A\u8CEA\u554F\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002TimePeriod \u306F\u672A\u6765\u306E\u65E5\u4ED8\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
971
995
 
972
996
  ### Cost Explorer \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
973
997