@squadbase/vite-server 0.1.17-dev.d4fff69 → 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 (78) hide show
  1. package/dist/cli/index.js +4786 -3023
  2. package/dist/connectors/airtable-oauth.js +39 -15
  3. package/dist/connectors/airtable.js +86 -15
  4. package/dist/connectors/amplitude.js +39 -15
  5. package/dist/connectors/anthropic.js +39 -15
  6. package/dist/connectors/asana.js +39 -15
  7. package/dist/connectors/attio.js +39 -15
  8. package/dist/connectors/aws-billing.js +39 -15
  9. package/dist/connectors/azure-sql.js +275 -15
  10. package/dist/connectors/backlog-api-key.js +39 -15
  11. package/dist/connectors/clickup.js +39 -15
  12. package/dist/connectors/cosmosdb.js +39 -15
  13. package/dist/connectors/customerio.js +39 -15
  14. package/dist/connectors/dbt.js +39 -15
  15. package/dist/connectors/freshdesk.js +39 -15
  16. package/dist/connectors/freshsales.js +39 -15
  17. package/dist/connectors/freshservice.js +39 -15
  18. package/dist/connectors/gamma.js +39 -15
  19. package/dist/connectors/gemini.js +39 -15
  20. package/dist/connectors/github.js +39 -15
  21. package/dist/connectors/gmail-oauth.js +32 -13
  22. package/dist/connectors/gmail.js +39 -15
  23. package/dist/connectors/google-ads.js +39 -15
  24. package/dist/connectors/google-analytics-oauth.js +39 -15
  25. package/dist/connectors/google-analytics.js +39 -15
  26. package/dist/connectors/google-audit-log.js +39 -15
  27. package/dist/connectors/google-calendar-oauth.js +39 -15
  28. package/dist/connectors/google-calendar.js +39 -15
  29. package/dist/connectors/google-docs.js +32 -13
  30. package/dist/connectors/google-drive.js +32 -13
  31. package/dist/connectors/google-search-console-oauth.js +39 -15
  32. package/dist/connectors/google-sheets.js +138 -195
  33. package/dist/connectors/google-slides.js +32 -13
  34. package/dist/connectors/grafana.js +39 -15
  35. package/dist/connectors/hackernews.js +32 -13
  36. package/dist/connectors/hubspot-oauth.js +32 -13
  37. package/dist/connectors/hubspot.js +39 -15
  38. package/dist/connectors/influxdb.js +39 -15
  39. package/dist/connectors/intercom-oauth.js +32 -13
  40. package/dist/connectors/intercom.js +39 -15
  41. package/dist/connectors/jdbc.js +39 -15
  42. package/dist/connectors/jira-api-key.js +39 -15
  43. package/dist/connectors/kintone-api-token.js +39 -15
  44. package/dist/connectors/kintone.js +128 -15
  45. package/dist/connectors/linear.js +39 -15
  46. package/dist/connectors/linkedin-ads.js +39 -15
  47. package/dist/connectors/mailchimp-oauth.js +39 -15
  48. package/dist/connectors/mailchimp.js +39 -15
  49. package/dist/connectors/meta-ads-oauth.js +39 -15
  50. package/dist/connectors/meta-ads.js +39 -15
  51. package/dist/connectors/mixpanel.js +39 -15
  52. package/dist/connectors/monday.js +39 -15
  53. package/dist/connectors/mongodb.js +39 -15
  54. package/dist/connectors/notion-oauth.js +32 -13
  55. package/dist/connectors/notion.js +84 -15
  56. package/dist/connectors/openai.js +39 -15
  57. package/dist/connectors/oracle.js +277 -15
  58. package/dist/connectors/outlook-oauth.js +32 -13
  59. package/dist/connectors/powerbi-oauth.js +32 -13
  60. package/dist/connectors/salesforce.js +108 -15
  61. package/dist/connectors/semrush.js +39 -15
  62. package/dist/connectors/sentry.js +39 -15
  63. package/dist/connectors/shopify-oauth.js +32 -13
  64. package/dist/connectors/shopify.js +39 -15
  65. package/dist/connectors/sqlserver.js +275 -15
  66. package/dist/connectors/stripe-api-key.js +39 -15
  67. package/dist/connectors/stripe-oauth.js +32 -13
  68. package/dist/connectors/supabase.js +284 -15
  69. package/dist/connectors/tableau.js +39 -15
  70. package/dist/connectors/tiktok-ads.js +39 -15
  71. package/dist/connectors/wix-store.js +39 -15
  72. package/dist/connectors/x.js +39 -15
  73. package/dist/connectors/zendesk-oauth.js +32 -13
  74. package/dist/connectors/zendesk.js +39 -15
  75. package/dist/index.js +4832 -3034
  76. package/dist/main.js +4832 -3034
  77. package/dist/vite-plugin.js +4786 -3023
  78. package/package.json +4 -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
@@ -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);
@@ -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];
@@ -1,7 +1,12 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __esm = (fn, res) => function __init() {
4
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
3
+ var __esm = (fn, res, err) => function __init() {
4
+ if (err) throw err[0];
5
+ try {
6
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
+ } catch (e) {
8
+ throw err = [e], e;
9
+ }
5
10
  };
6
11
  var __export = (target, all) => {
7
12
  for (var name in all)
@@ -474,6 +479,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
474
479
  * `runSetupFlow` from `setup-flow.ts`.
475
480
  */
476
481
  setup;
482
+ /**
483
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
484
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
485
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
486
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
487
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
488
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
489
+ */
490
+ introspect;
477
491
  /**
478
492
  * Opt-out of the default "verify before save" behavior on connection
479
493
  * creation. The backend invokes `checkConnection` synchronously while
@@ -488,6 +502,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
488
502
  * the default verify-on-create behavior without opt-in.
489
503
  */
490
504
  skipConnectionCheckOnCreate;
505
+ /**
506
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
507
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
508
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
509
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
510
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
511
+ */
512
+ surveyProbes;
491
513
  constructor(config) {
492
514
  this.slug = config.slug;
493
515
  this.authType = config.authType;
@@ -505,7 +527,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
505
527
  this.query = config.query;
506
528
  this.checkConnection = config.checkConnection;
507
529
  this.setup = config.setup;
530
+ this.introspect = config.introspect;
508
531
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
532
+ this.surveyProbes = config.surveyProbes;
509
533
  }
510
534
  get connectorKey() {
511
535
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -543,25 +567,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
543
567
  if (authType) return `${slug}-${authType}`;
544
568
  const LEGACY_NULL_AUTH_TYPE_MAP = {
545
569
  // user-password
546
- "postgresql": "user-password",
547
- "mysql": "user-password",
548
- "clickhouse": "user-password",
549
- "kintone": "user-password",
570
+ postgresql: "user-password",
571
+ mysql: "user-password",
572
+ clickhouse: "user-password",
573
+ kintone: "user-password",
550
574
  "squadbase-db": "user-password",
551
575
  // service-account
552
- "snowflake": "service-account",
553
- "bigquery": "service-account",
576
+ snowflake: "service-account",
577
+ bigquery: "service-account",
554
578
  "google-analytics": "service-account",
555
579
  "google-calendar": "service-account",
556
580
  "aws-athena": "service-account",
557
- "redshift": "service-account",
581
+ redshift: "service-account",
558
582
  // api-key
559
- "databricks": "api-key",
560
- "dbt": "api-key",
561
- "airtable": "api-key",
562
- "openai": "api-key",
563
- "gemini": "api-key",
564
- "anthropic": "api-key",
583
+ databricks: "api-key",
584
+ dbt: "api-key",
585
+ airtable: "api-key",
586
+ openai: "api-key",
587
+ gemini: "api-key",
588
+ anthropic: "api-key",
565
589
  "wix-store": "api-key"
566
590
  };
567
591
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -570,6 +594,84 @@ var ConnectorPlugin = class _ConnectorPlugin {
570
594
  }
571
595
  };
572
596
 
597
+ // ../connectors/src/survey-probe.ts
598
+ function rowsOf(output) {
599
+ if (!output || typeof output !== "object") return [];
600
+ const o = output;
601
+ if (o.success === false) return [];
602
+ return Array.isArray(o.rows) ? o.rows : [];
603
+ }
604
+ function pickString(row, candidates) {
605
+ for (const key of candidates) {
606
+ const v = row[key] ?? row[key.toUpperCase()] ?? row[key.toLowerCase()];
607
+ if (typeof v === "string" && v.length > 0) return v;
608
+ }
609
+ return void 0;
610
+ }
611
+ var TABLE_NAME_FIELDS = [
612
+ "table_name",
613
+ "name",
614
+ "tableName",
615
+ "tab_name",
616
+ "Table",
617
+ "table"
618
+ ];
619
+ function makeQuoteIdent(opts) {
620
+ if (opts.bracket) {
621
+ return (name) => `[${name.replaceAll("]", "]]")}]`;
622
+ }
623
+ const q = opts.quote ?? '"';
624
+ return (name) => `${q}${name.replaceAll(q, q + q)}${q}`;
625
+ }
626
+ function sampleSql(ref, limit) {
627
+ return `SELECT * FROM (SELECT * FROM ${ref}) AS _sq LIMIT ${limit}`;
628
+ }
629
+ function distinctTables(prior, max) {
630
+ const names = [];
631
+ const seen = /* @__PURE__ */ new Set();
632
+ for (const row of rowsOf(prior[0]?.output)) {
633
+ const name = pickString(row, TABLE_NAME_FIELDS);
634
+ if (!name || seen.has(name)) continue;
635
+ seen.add(name);
636
+ names.push(name);
637
+ if (names.length >= max) break;
638
+ }
639
+ return names;
640
+ }
641
+ function makeStandardSqlSurveyProbes(opts) {
642
+ const queryTool = opts.queryTool ?? "executeQuery";
643
+ const sampleLimit = opts.sampleLimit ?? 5;
644
+ const maxSampleTables = opts.maxSampleTables ?? 4;
645
+ const quoteIdent = makeQuoteIdent(opts);
646
+ const whereSchema = opts.schemaLiteral ? ` WHERE table_schema = '${opts.schemaLiteral.replaceAll("'", "''")}'` : opts.schemaExpr ? ` WHERE table_schema = ${opts.schemaExpr}` : "";
647
+ return (_connectionId, prior) => {
648
+ if (prior.length === 0) {
649
+ return [
650
+ {
651
+ tool: queryTool,
652
+ input: {
653
+ toolUseIntent: "Survey table/column metadata",
654
+ sql: `SELECT table_name, column_name, data_type FROM information_schema.columns${whereSchema} ORDER BY table_name, ordinal_position LIMIT 1000`
655
+ }
656
+ }
657
+ ];
658
+ }
659
+ if (prior.length === 1) {
660
+ return distinctTables(prior, maxSampleTables).map((name) => {
661
+ const ref = opts.schemaLiteral ? `${quoteIdent(opts.schemaLiteral)}.${quoteIdent(name)}` : quoteIdent(name);
662
+ return {
663
+ tool: queryTool,
664
+ input: {
665
+ toolUseIntent: `Sample ${name}`,
666
+ sql: sampleSql(ref, sampleLimit)
667
+ }
668
+ };
669
+ });
670
+ }
671
+ return [];
672
+ };
673
+ }
674
+
573
675
  // ../connectors/src/setup-flow.ts
574
676
  async function runSetupFlow(flow, params, ctx, config) {
575
677
  const runtime = {
@@ -640,6 +742,55 @@ async function resolveSetupSelection(params) {
640
742
  return resolved.slice(0, limit);
641
743
  }
642
744
 
745
+ // ../connectors/src/introspect-concurrency.ts
746
+ async function mapWithConcurrency(items, limit, fn) {
747
+ const results = new Array(items.length);
748
+ let next = 0;
749
+ const workers = Array.from(
750
+ { length: Math.min(Math.max(limit, 1), items.length) },
751
+ async () => {
752
+ for (; ; ) {
753
+ const i = next++;
754
+ if (i >= items.length) return;
755
+ results[i] = await fn(items[i]);
756
+ }
757
+ }
758
+ );
759
+ await Promise.all(workers);
760
+ return results;
761
+ }
762
+
763
+ // ../connectors/src/introspect-profile.ts
764
+ var DEFAULT_MAX_TABLES = 200;
765
+ var DEFAULT_CONCURRENCY = 5;
766
+ var quoteBracket = (schema, name) => `[${schema.replace(/\]/g, "]]")}].[${name.replace(/\]/g, "]]")}]`;
767
+ async function withRowCounts(ctx, schemaPromise, quoteRef, opts = {}) {
768
+ const schema = await schemaPromise;
769
+ if (!ctx.profile || !ctx.query) return schema;
770
+ return attachRowCounts(ctx.query, schema, quoteRef, opts);
771
+ }
772
+ async function attachRowCounts(run, schema, quoteRef, opts = {}) {
773
+ const targets = schema.tables.slice(0, opts.maxTables ?? DEFAULT_MAX_TABLES);
774
+ await mapWithConcurrency(
775
+ targets,
776
+ opts.concurrency ?? DEFAULT_CONCURRENCY,
777
+ async (table) => {
778
+ try {
779
+ const { rows } = await run(
780
+ `SELECT COUNT(*) AS row_count FROM ${quoteRef(table.schema, table.name)}`
781
+ );
782
+ const first = rows[0] ? Object.values(rows[0])[0] : void 0;
783
+ const rowCount = Number(first);
784
+ if (Number.isFinite(rowCount)) {
785
+ table.profile = { ...table.profile ?? {}, rowCount };
786
+ }
787
+ } catch {
788
+ }
789
+ }
790
+ );
791
+ return schema;
792
+ }
793
+
643
794
  // ../connectors/src/auth-types.ts
644
795
  var AUTH_TYPES = {
645
796
  OAUTH: "oauth",
@@ -650,6 +801,63 @@ var AUTH_TYPES = {
650
801
  USER_PASSWORD: "user-password"
651
802
  };
652
803
 
804
+ // ../connectors/src/introspect-information-schema.ts
805
+ function pickCI(row, key) {
806
+ if (key in row) return String(row[key] ?? "");
807
+ const lower = key.toLowerCase();
808
+ for (const k of Object.keys(row)) {
809
+ if (k.toLowerCase() === lower) return String(row[k] ?? "");
810
+ }
811
+ return "";
812
+ }
813
+ function assembleIntrospectedSchema(input) {
814
+ const { colRows, pkRows = [], fkRows = [] } = input;
815
+ const pkSet = /* @__PURE__ */ new Set();
816
+ for (const r of pkRows) {
817
+ pkSet.add(
818
+ `${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`
819
+ );
820
+ }
821
+ const fkMap = /* @__PURE__ */ new Map();
822
+ for (const r of fkRows) {
823
+ fkMap.set(
824
+ `${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`,
825
+ {
826
+ schema: pickCI(r, "foreign_table_schema"),
827
+ table: pickCI(r, "foreign_table_name"),
828
+ column: pickCI(r, "foreign_column_name")
829
+ }
830
+ );
831
+ }
832
+ const tableMap = /* @__PURE__ */ new Map();
833
+ for (const r of colRows) {
834
+ const schema = pickCI(r, "table_schema");
835
+ const name = pickCI(r, "table_name");
836
+ const key = `${schema}.${name}`;
837
+ let table = tableMap.get(key);
838
+ if (!table) {
839
+ table = {
840
+ schema,
841
+ name,
842
+ type: pickCI(r, "table_type").toUpperCase() === "VIEW" ? "view" : "table",
843
+ columns: []
844
+ };
845
+ tableMap.set(key, table);
846
+ }
847
+ const colKey = `${schema}.${name}.${pickCI(r, "column_name")}`;
848
+ const column = {
849
+ name: pickCI(r, "column_name"),
850
+ dataType: pickCI(r, "data_type"),
851
+ nullable: pickCI(r, "is_nullable").toUpperCase() === "YES"
852
+ };
853
+ if (pkSet.has(colKey)) column.isPrimaryKey = true;
854
+ const fk = fkMap.get(colKey);
855
+ if (fk) column.foreignKey = fk;
856
+ table.columns.push(column);
857
+ }
858
+ return { tables: [...tableMap.values()] };
859
+ }
860
+
653
861
  // ../connectors/src/lib/sql-dml.ts
654
862
  function isDmlStatement(sql) {
655
863
  const stripped = sql.replace(/^(\s*(--[^\n]*\n|\/\*[\s\S]*?\*\/))+/, "").trimStart();
@@ -828,6 +1036,52 @@ var sqlserverSetupFlow = createSqlServerSetupFlow({
828
1036
  forceEncrypt: false
829
1037
  });
830
1038
 
1039
+ // ../connectors/src/connectors/sqlserver/introspect.ts
1040
+ async function introspectMssql(run) {
1041
+ const [{ rows: colRows }, { rows: pkRows }, { rows: fkRows }] = await Promise.all([
1042
+ // 1) 全カラム(型 / nullable)+ テーブル種別(BASE TABLE / VIEW)
1043
+ run(
1044
+ `SELECT c.TABLE_SCHEMA AS table_schema, c.TABLE_NAME AS table_name,
1045
+ c.COLUMN_NAME AS column_name, c.DATA_TYPE AS data_type,
1046
+ c.IS_NULLABLE AS is_nullable, c.ORDINAL_POSITION AS ordinal_position,
1047
+ t.TABLE_TYPE AS table_type
1048
+ FROM INFORMATION_SCHEMA.COLUMNS c
1049
+ JOIN INFORMATION_SCHEMA.TABLES t
1050
+ ON t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.TABLE_NAME = c.TABLE_NAME
1051
+ WHERE c.TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')
1052
+ ORDER BY c.TABLE_SCHEMA, c.TABLE_NAME, c.ORDINAL_POSITION`
1053
+ ),
1054
+ // 2) 主キー
1055
+ run(
1056
+ `SELECT tc.TABLE_SCHEMA AS table_schema, tc.TABLE_NAME AS table_name,
1057
+ kcu.COLUMN_NAME AS column_name
1058
+ FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
1059
+ JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
1060
+ ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
1061
+ AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
1062
+ AND kcu.TABLE_NAME = tc.TABLE_NAME
1063
+ WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
1064
+ AND tc.TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')`
1065
+ ),
1066
+ // 3) 外部キー(参照元列 → 参照先列)。sys カタログで複合 FK も 1:1 に解決する。
1067
+ run(
1068
+ `SELECT sch.name AS table_schema, tab.name AS table_name, col.name AS column_name,
1069
+ rsch.name AS foreign_table_schema, rtab.name AS foreign_table_name,
1070
+ rcol.name AS foreign_column_name
1071
+ FROM sys.foreign_key_columns fkc
1072
+ JOIN sys.tables tab ON tab.object_id = fkc.parent_object_id
1073
+ JOIN sys.schemas sch ON sch.schema_id = tab.schema_id
1074
+ JOIN sys.columns col ON col.object_id = fkc.parent_object_id
1075
+ AND col.column_id = fkc.parent_column_id
1076
+ JOIN sys.tables rtab ON rtab.object_id = fkc.referenced_object_id
1077
+ JOIN sys.schemas rsch ON rsch.schema_id = rtab.schema_id
1078
+ JOIN sys.columns rcol ON rcol.object_id = fkc.referenced_object_id
1079
+ AND rcol.column_id = fkc.referenced_column_id`
1080
+ )
1081
+ ]);
1082
+ return assembleIntrospectedSchema({ colRows, pkRows, fkRows });
1083
+ }
1084
+
831
1085
  // ../connectors/src/connectors/azure-sql/index.ts
832
1086
  init_mssql_runner();
833
1087
  init_utils();
@@ -986,6 +1240,12 @@ The business logic type for this connector is "sql".
986
1240
  - \u884C\u6570\u5236\u9650\u306E\u4E92\u63DB\u6027: \u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u306E server-logic \u30B9\u30AD\u30FC\u30DE\u63A8\u8AD6\u306F\u3001\u30AF\u30A8\u30EA\u3092 \`SELECT * FROM (<inner>) AS _sq LIMIT N\` \u306E\u5F62\u3067\u30E9\u30C3\u30D7\u3057\u3066\u304F\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002T-SQL \u306B\u306F \`LIMIT\` \u304C\u7121\u3044\u305F\u3081\u3001\u30B3\u30CD\u30AF\u30BF\u306F \`query()\` \u5185\u3067\u3053\u306E\u30E9\u30C3\u30D1\u3092\u691C\u51FA\u3057\u3001\`<inner>\` \u3092\u305D\u306E\u307E\u307E\u5B9F\u884C\u3057\u3066 JS \u5074\u3067\u5148\u982D N \u884C\u306B\u5207\u308A\u8A70\u3081\u307E\u3059\u3002\u5229\u7528\u8005\u5074\u3067\u5BFE\u51E6\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u304C\u3001\u81EA\u5206\u3067\u66F8\u304F SQL \u3067\u306F \`LIMIT\` \u3092\u4F7F\u308F\u305A \`TOP\` / \`OFFSET ... FETCH NEXT\` \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
987
1241
  },
988
1242
  tools,
1243
+ // 決定論的な立ち上げ survey(ルールベース prewarm)。Azure SQL はユーザーオブジェクトが既定 `dbo`、識別子は `[ ]`。
1244
+ surveyProbes: makeStandardSqlSurveyProbes({
1245
+ schemaLiteral: "dbo",
1246
+ bracket: true
1247
+ }),
1248
+ introspect: (ctx) => withRowCounts(ctx, introspectMssql(ctx.query), quoteBracket),
989
1249
  setup: (params, ctx, config) => runSetupFlow(azureSqlSetupFlow, params, ctx, config),
990
1250
  async checkConnection(params, _config) {
991
1251
  return checkMssqlConnection(
@@ -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
@@ -173,6 +178,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
173
178
  * `runSetupFlow` from `setup-flow.ts`.
174
179
  */
175
180
  setup;
181
+ /**
182
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
183
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
184
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
185
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
186
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
187
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
188
+ */
189
+ introspect;
176
190
  /**
177
191
  * Opt-out of the default "verify before save" behavior on connection
178
192
  * creation. The backend invokes `checkConnection` synchronously while
@@ -187,6 +201,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
187
201
  * the default verify-on-create behavior without opt-in.
188
202
  */
189
203
  skipConnectionCheckOnCreate;
204
+ /**
205
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
206
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
207
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
208
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
209
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
210
+ */
211
+ surveyProbes;
190
212
  constructor(config) {
191
213
  this.slug = config.slug;
192
214
  this.authType = config.authType;
@@ -204,7 +226,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
204
226
  this.query = config.query;
205
227
  this.checkConnection = config.checkConnection;
206
228
  this.setup = config.setup;
229
+ this.introspect = config.introspect;
207
230
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
231
+ this.surveyProbes = config.surveyProbes;
208
232
  }
209
233
  get connectorKey() {
210
234
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -242,25 +266,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
242
266
  if (authType) return `${slug}-${authType}`;
243
267
  const LEGACY_NULL_AUTH_TYPE_MAP = {
244
268
  // user-password
245
- "postgresql": "user-password",
246
- "mysql": "user-password",
247
- "clickhouse": "user-password",
248
- "kintone": "user-password",
269
+ postgresql: "user-password",
270
+ mysql: "user-password",
271
+ clickhouse: "user-password",
272
+ kintone: "user-password",
249
273
  "squadbase-db": "user-password",
250
274
  // service-account
251
- "snowflake": "service-account",
252
- "bigquery": "service-account",
275
+ snowflake: "service-account",
276
+ bigquery: "service-account",
253
277
  "google-analytics": "service-account",
254
278
  "google-calendar": "service-account",
255
279
  "aws-athena": "service-account",
256
- "redshift": "service-account",
280
+ redshift: "service-account",
257
281
  // api-key
258
- "databricks": "api-key",
259
- "dbt": "api-key",
260
- "airtable": "api-key",
261
- "openai": "api-key",
262
- "gemini": "api-key",
263
- "anthropic": "api-key",
282
+ databricks: "api-key",
283
+ dbt: "api-key",
284
+ airtable: "api-key",
285
+ openai: "api-key",
286
+ gemini: "api-key",
287
+ anthropic: "api-key",
264
288
  "wix-store": "api-key"
265
289
  };
266
290
  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
@@ -309,6 +314,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
309
314
  * `runSetupFlow` from `setup-flow.ts`.
310
315
  */
311
316
  setup;
317
+ /**
318
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
319
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
320
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
321
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
322
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
323
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
324
+ */
325
+ introspect;
312
326
  /**
313
327
  * Opt-out of the default "verify before save" behavior on connection
314
328
  * creation. The backend invokes `checkConnection` synchronously while
@@ -323,6 +337,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
323
337
  * the default verify-on-create behavior without opt-in.
324
338
  */
325
339
  skipConnectionCheckOnCreate;
340
+ /**
341
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
342
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
343
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
344
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
345
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
346
+ */
347
+ surveyProbes;
326
348
  constructor(config) {
327
349
  this.slug = config.slug;
328
350
  this.authType = config.authType;
@@ -340,7 +362,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
340
362
  this.query = config.query;
341
363
  this.checkConnection = config.checkConnection;
342
364
  this.setup = config.setup;
365
+ this.introspect = config.introspect;
343
366
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
367
+ this.surveyProbes = config.surveyProbes;
344
368
  }
345
369
  get connectorKey() {
346
370
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -378,25 +402,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
378
402
  if (authType) return `${slug}-${authType}`;
379
403
  const LEGACY_NULL_AUTH_TYPE_MAP = {
380
404
  // user-password
381
- "postgresql": "user-password",
382
- "mysql": "user-password",
383
- "clickhouse": "user-password",
384
- "kintone": "user-password",
405
+ postgresql: "user-password",
406
+ mysql: "user-password",
407
+ clickhouse: "user-password",
408
+ kintone: "user-password",
385
409
  "squadbase-db": "user-password",
386
410
  // service-account
387
- "snowflake": "service-account",
388
- "bigquery": "service-account",
411
+ snowflake: "service-account",
412
+ bigquery: "service-account",
389
413
  "google-analytics": "service-account",
390
414
  "google-calendar": "service-account",
391
415
  "aws-athena": "service-account",
392
- "redshift": "service-account",
416
+ redshift: "service-account",
393
417
  // api-key
394
- "databricks": "api-key",
395
- "dbt": "api-key",
396
- "airtable": "api-key",
397
- "openai": "api-key",
398
- "gemini": "api-key",
399
- "anthropic": "api-key",
418
+ databricks: "api-key",
419
+ dbt: "api-key",
420
+ airtable: "api-key",
421
+ openai: "api-key",
422
+ gemini: "api-key",
423
+ anthropic: "api-key",
400
424
  "wix-store": "api-key"
401
425
  };
402
426
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];