@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,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)
@@ -514,6 +519,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
514
519
  * `runSetupFlow` from `setup-flow.ts`.
515
520
  */
516
521
  setup;
522
+ /**
523
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
524
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
525
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
526
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
527
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
528
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
529
+ */
530
+ introspect;
517
531
  /**
518
532
  * Opt-out of the default "verify before save" behavior on connection
519
533
  * creation. The backend invokes `checkConnection` synchronously while
@@ -528,6 +542,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
528
542
  * the default verify-on-create behavior without opt-in.
529
543
  */
530
544
  skipConnectionCheckOnCreate;
545
+ /**
546
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
547
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
548
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
549
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
550
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
551
+ */
552
+ surveyProbes;
531
553
  constructor(config) {
532
554
  this.slug = config.slug;
533
555
  this.authType = config.authType;
@@ -545,7 +567,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
545
567
  this.query = config.query;
546
568
  this.checkConnection = config.checkConnection;
547
569
  this.setup = config.setup;
570
+ this.introspect = config.introspect;
548
571
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
572
+ this.surveyProbes = config.surveyProbes;
549
573
  }
550
574
  get connectorKey() {
551
575
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -583,25 +607,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
583
607
  if (authType) return `${slug}-${authType}`;
584
608
  const LEGACY_NULL_AUTH_TYPE_MAP = {
585
609
  // user-password
586
- "postgresql": "user-password",
587
- "mysql": "user-password",
588
- "clickhouse": "user-password",
589
- "kintone": "user-password",
610
+ postgresql: "user-password",
611
+ mysql: "user-password",
612
+ clickhouse: "user-password",
613
+ kintone: "user-password",
590
614
  "squadbase-db": "user-password",
591
615
  // service-account
592
- "snowflake": "service-account",
593
- "bigquery": "service-account",
616
+ snowflake: "service-account",
617
+ bigquery: "service-account",
594
618
  "google-analytics": "service-account",
595
619
  "google-calendar": "service-account",
596
620
  "aws-athena": "service-account",
597
- "redshift": "service-account",
621
+ redshift: "service-account",
598
622
  // api-key
599
- "databricks": "api-key",
600
- "dbt": "api-key",
601
- "airtable": "api-key",
602
- "openai": "api-key",
603
- "gemini": "api-key",
604
- "anthropic": "api-key",
623
+ databricks: "api-key",
624
+ dbt: "api-key",
625
+ airtable: "api-key",
626
+ openai: "api-key",
627
+ gemini: "api-key",
628
+ anthropic: "api-key",
605
629
  "wix-store": "api-key"
606
630
  };
607
631
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -610,6 +634,80 @@ var ConnectorPlugin = class _ConnectorPlugin {
610
634
  }
611
635
  };
612
636
 
637
+ // ../connectors/src/survey-probe.ts
638
+ function rowsOf(output) {
639
+ if (!output || typeof output !== "object") return [];
640
+ const o = output;
641
+ if (o.success === false) return [];
642
+ return Array.isArray(o.rows) ? o.rows : [];
643
+ }
644
+ function pickString(row, candidates) {
645
+ for (const key of candidates) {
646
+ const v = row[key] ?? row[key.toUpperCase()] ?? row[key.toLowerCase()];
647
+ if (typeof v === "string" && v.length > 0) return v;
648
+ }
649
+ return void 0;
650
+ }
651
+ var TABLE_NAME_FIELDS = [
652
+ "table_name",
653
+ "name",
654
+ "tableName",
655
+ "tab_name",
656
+ "Table",
657
+ "table"
658
+ ];
659
+ function makeQuoteIdent(opts) {
660
+ if (opts.bracket) {
661
+ return (name) => `[${name.replaceAll("]", "]]")}]`;
662
+ }
663
+ const q = opts.quote ?? '"';
664
+ return (name) => `${q}${name.replaceAll(q, q + q)}${q}`;
665
+ }
666
+ function sampleSql(ref, limit) {
667
+ return `SELECT * FROM (SELECT * FROM ${ref}) AS _sq LIMIT ${limit}`;
668
+ }
669
+ function distinctTables(prior, max) {
670
+ const names = [];
671
+ const seen = /* @__PURE__ */ new Set();
672
+ for (const row of rowsOf(prior[0]?.output)) {
673
+ const name = pickString(row, TABLE_NAME_FIELDS);
674
+ if (!name || seen.has(name)) continue;
675
+ seen.add(name);
676
+ names.push(name);
677
+ if (names.length >= max) break;
678
+ }
679
+ return names;
680
+ }
681
+ function makeOracleSurveyProbes(opts) {
682
+ const queryTool = opts?.queryTool ?? "executeQuery";
683
+ const sampleLimit = opts?.sampleLimit ?? 5;
684
+ const maxSampleTables = opts?.maxSampleTables ?? 4;
685
+ const quoteIdent = makeQuoteIdent({ quote: '"' });
686
+ return (_connectionId, prior) => {
687
+ if (prior.length === 0) {
688
+ return [
689
+ {
690
+ tool: queryTool,
691
+ input: {
692
+ toolUseIntent: "Survey table/column metadata",
693
+ sql: "SELECT table_name, column_name, data_type FROM user_tab_columns ORDER BY table_name, column_id FETCH FIRST 1000 ROWS ONLY"
694
+ }
695
+ }
696
+ ];
697
+ }
698
+ if (prior.length === 1) {
699
+ return distinctTables(prior, maxSampleTables).map((name) => ({
700
+ tool: queryTool,
701
+ input: {
702
+ toolUseIntent: `Sample ${name}`,
703
+ sql: sampleSql(quoteIdent(name), sampleLimit)
704
+ }
705
+ }));
706
+ }
707
+ return [];
708
+ };
709
+ }
710
+
613
711
  // ../connectors/src/setup-flow.ts
614
712
  async function runSetupFlow(flow, params, ctx, config) {
615
713
  const runtime = {
@@ -680,6 +778,58 @@ async function resolveSetupSelection(params) {
680
778
  return resolved.slice(0, limit);
681
779
  }
682
780
 
781
+ // ../connectors/src/introspect-concurrency.ts
782
+ async function mapWithConcurrency(items, limit, fn) {
783
+ const results = new Array(items.length);
784
+ let next = 0;
785
+ const workers = Array.from(
786
+ { length: Math.min(Math.max(limit, 1), items.length) },
787
+ async () => {
788
+ for (; ; ) {
789
+ const i = next++;
790
+ if (i >= items.length) return;
791
+ results[i] = await fn(items[i]);
792
+ }
793
+ }
794
+ );
795
+ await Promise.all(workers);
796
+ return results;
797
+ }
798
+
799
+ // ../connectors/src/introspect-profile.ts
800
+ var DEFAULT_MAX_TABLES = 200;
801
+ var DEFAULT_CONCURRENCY = 5;
802
+ function dq(ident) {
803
+ return `"${ident.replace(/"/g, '""')}"`;
804
+ }
805
+ var quoteAnsi = (schema, name) => [...schema.split("."), name].map(dq).join(".");
806
+ async function withRowCounts(ctx, schemaPromise, quoteRef, opts = {}) {
807
+ const schema = await schemaPromise;
808
+ if (!ctx.profile || !ctx.query) return schema;
809
+ return attachRowCounts(ctx.query, schema, quoteRef, opts);
810
+ }
811
+ async function attachRowCounts(run, schema, quoteRef, opts = {}) {
812
+ const targets = schema.tables.slice(0, opts.maxTables ?? DEFAULT_MAX_TABLES);
813
+ await mapWithConcurrency(
814
+ targets,
815
+ opts.concurrency ?? DEFAULT_CONCURRENCY,
816
+ async (table) => {
817
+ try {
818
+ const { rows } = await run(
819
+ `SELECT COUNT(*) AS row_count FROM ${quoteRef(table.schema, table.name)}`
820
+ );
821
+ const first = rows[0] ? Object.values(rows[0])[0] : void 0;
822
+ const rowCount = Number(first);
823
+ if (Number.isFinite(rowCount)) {
824
+ table.profile = { ...table.profile ?? {}, rowCount };
825
+ }
826
+ } catch {
827
+ }
828
+ }
829
+ );
830
+ return schema;
831
+ }
832
+
683
833
  // ../connectors/src/auth-types.ts
684
834
  var AUTH_TYPES = {
685
835
  OAUTH: "oauth",
@@ -690,6 +840,63 @@ var AUTH_TYPES = {
690
840
  USER_PASSWORD: "user-password"
691
841
  };
692
842
 
843
+ // ../connectors/src/introspect-information-schema.ts
844
+ function pickCI(row, key) {
845
+ if (key in row) return String(row[key] ?? "");
846
+ const lower = key.toLowerCase();
847
+ for (const k of Object.keys(row)) {
848
+ if (k.toLowerCase() === lower) return String(row[k] ?? "");
849
+ }
850
+ return "";
851
+ }
852
+ function assembleIntrospectedSchema(input) {
853
+ const { colRows, pkRows = [], fkRows = [] } = input;
854
+ const pkSet = /* @__PURE__ */ new Set();
855
+ for (const r of pkRows) {
856
+ pkSet.add(
857
+ `${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`
858
+ );
859
+ }
860
+ const fkMap = /* @__PURE__ */ new Map();
861
+ for (const r of fkRows) {
862
+ fkMap.set(
863
+ `${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`,
864
+ {
865
+ schema: pickCI(r, "foreign_table_schema"),
866
+ table: pickCI(r, "foreign_table_name"),
867
+ column: pickCI(r, "foreign_column_name")
868
+ }
869
+ );
870
+ }
871
+ const tableMap = /* @__PURE__ */ new Map();
872
+ for (const r of colRows) {
873
+ const schema = pickCI(r, "table_schema");
874
+ const name = pickCI(r, "table_name");
875
+ const key = `${schema}.${name}`;
876
+ let table = tableMap.get(key);
877
+ if (!table) {
878
+ table = {
879
+ schema,
880
+ name,
881
+ type: pickCI(r, "table_type").toUpperCase() === "VIEW" ? "view" : "table",
882
+ columns: []
883
+ };
884
+ tableMap.set(key, table);
885
+ }
886
+ const colKey = `${schema}.${name}.${pickCI(r, "column_name")}`;
887
+ const column = {
888
+ name: pickCI(r, "column_name"),
889
+ dataType: pickCI(r, "data_type"),
890
+ nullable: pickCI(r, "is_nullable").toUpperCase() === "YES"
891
+ };
892
+ if (pkSet.has(colKey)) column.isPrimaryKey = true;
893
+ const fk = fkMap.get(colKey);
894
+ if (fk) column.foreignKey = fk;
895
+ table.columns.push(column);
896
+ }
897
+ return { tables: [...tableMap.values()] };
898
+ }
899
+
693
900
  // ../connectors/src/lib/unwrap-sample-limit.ts
694
901
  var STRICT_WRAPPER_RE = /^\s*SELECT\s+\*\s+FROM\s+\(([\s\S]+)\)\s+AS\s+\w+\s+LIMIT\s+(\d+)\s*;?\s*$/i;
695
902
  var TRAILING_LIMIT_RE = /\s+LIMIT\s+(\d+)\s*;?\s*$/i;
@@ -910,6 +1117,58 @@ var oracleSetupFlow = {
910
1117
  }
911
1118
  };
912
1119
 
1120
+ // ../connectors/src/connectors/oracle/introspect.ts
1121
+ var OWNER_NOT_IN = [...INTERNAL_OWNERS].map((o) => `'${o}'`).join(", ");
1122
+ function ownerFilter(ownerCol) {
1123
+ return `${ownerCol} NOT IN (${OWNER_NOT_IN}) AND ${ownerCol} NOT LIKE 'APEX_%'`;
1124
+ }
1125
+ async function introspectOracle(run) {
1126
+ const [{ rows: colRows }, { rows: pkRows }, { rows: fkRows }] = await Promise.all([
1127
+ // 1) 全カラム(型 / nullable)+ テーブル種別(TABLE / VIEW)
1128
+ run(
1129
+ `SELECT c.owner AS table_schema, c.table_name AS table_name,
1130
+ c.column_name AS column_name, c.data_type AS data_type,
1131
+ CASE WHEN c.nullable = 'Y' THEN 'YES' ELSE 'NO' END AS is_nullable,
1132
+ c.column_id AS ordinal_position,
1133
+ CASE WHEN o.object_type = 'VIEW' THEN 'VIEW' ELSE 'BASE TABLE' END AS table_type
1134
+ FROM all_tab_columns c
1135
+ JOIN all_objects o
1136
+ ON o.owner = c.owner AND o.object_name = c.table_name
1137
+ AND o.object_type IN ('TABLE', 'VIEW')
1138
+ WHERE ${ownerFilter("c.owner")}
1139
+ ORDER BY c.owner, c.table_name, c.column_id`
1140
+ ),
1141
+ // 2) 主キー(CONSTRAINT_TYPE = 'P')
1142
+ run(
1143
+ `SELECT ac.owner AS table_schema, ac.table_name AS table_name,
1144
+ acc.column_name AS column_name
1145
+ FROM all_constraints ac
1146
+ JOIN all_cons_columns acc
1147
+ ON acc.owner = ac.owner AND acc.constraint_name = ac.constraint_name
1148
+ WHERE ac.constraint_type = 'P'
1149
+ AND ${ownerFilter("ac.owner")}`
1150
+ ),
1151
+ // 3) 外部キー(CONSTRAINT_TYPE = 'R')。参照元 → 参照先を position で突き合わせる。
1152
+ run(
1153
+ `SELECT ac.owner AS table_schema, ac.table_name AS table_name,
1154
+ acc.column_name AS column_name,
1155
+ rac.owner AS foreign_table_schema, rac.table_name AS foreign_table_name,
1156
+ racc.column_name AS foreign_column_name
1157
+ FROM all_constraints ac
1158
+ JOIN all_cons_columns acc
1159
+ ON acc.owner = ac.owner AND acc.constraint_name = ac.constraint_name
1160
+ JOIN all_constraints rac
1161
+ ON rac.owner = ac.r_owner AND rac.constraint_name = ac.r_constraint_name
1162
+ JOIN all_cons_columns racc
1163
+ ON racc.owner = rac.owner AND racc.constraint_name = rac.constraint_name
1164
+ AND racc.position = acc.position
1165
+ WHERE ac.constraint_type = 'R'
1166
+ AND ${ownerFilter("ac.owner")}`
1167
+ )
1168
+ ]);
1169
+ return assembleIntrospectedSchema({ colRows, pkRows, fkRows });
1170
+ }
1171
+
913
1172
  // ../connectors/src/connectors/oracle/tools/execute-query.ts
914
1173
  import { z } from "zod";
915
1174
  init_oracle_runner();
@@ -1049,6 +1308,9 @@ The business logic type for this connector is "sql".
1049
1308
  - \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\u3002Oracle \u306B\u306F \`LIMIT\` \u30AD\u30FC\u30EF\u30FC\u30C9\u304C\u5B58\u5728\u3057\u306A\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 \`FETCH FIRST N ROWS ONLY\` / \`OFFSET m ROWS FETCH NEXT N ROWS ONLY\` / \`ROWNUM\` \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
1050
1309
  },
1051
1310
  tools,
1311
+ // 決定論的な立ち上げ survey(ルールベース prewarm)。Oracle は USER_TAB_COLUMNS でメタ取得。
1312
+ surveyProbes: makeOracleSurveyProbes(),
1313
+ introspect: (ctx) => withRowCounts(ctx, introspectOracle(ctx.query), quoteAnsi),
1052
1314
  setup: (params, ctx, config) => runSetupFlow(oracleSetupFlow, params, ctx, config),
1053
1315
  async checkConnection(params, _config) {
1054
1316
  return checkOracleConnection(
@@ -193,6 +193,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
193
193
  * `runSetupFlow` from `setup-flow.ts`.
194
194
  */
195
195
  setup;
196
+ /**
197
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
198
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
199
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
200
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
201
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
202
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
203
+ */
204
+ introspect;
196
205
  /**
197
206
  * Opt-out of the default "verify before save" behavior on connection
198
207
  * creation. The backend invokes `checkConnection` synchronously while
@@ -207,6 +216,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
207
216
  * the default verify-on-create behavior without opt-in.
208
217
  */
209
218
  skipConnectionCheckOnCreate;
219
+ /**
220
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
221
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
222
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
223
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
224
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
225
+ */
226
+ surveyProbes;
210
227
  constructor(config) {
211
228
  this.slug = config.slug;
212
229
  this.authType = config.authType;
@@ -224,7 +241,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
224
241
  this.query = config.query;
225
242
  this.checkConnection = config.checkConnection;
226
243
  this.setup = config.setup;
244
+ this.introspect = config.introspect;
227
245
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
246
+ this.surveyProbes = config.surveyProbes;
228
247
  }
229
248
  get connectorKey() {
230
249
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -262,25 +281,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
262
281
  if (authType) return `${slug}-${authType}`;
263
282
  const LEGACY_NULL_AUTH_TYPE_MAP = {
264
283
  // user-password
265
- "postgresql": "user-password",
266
- "mysql": "user-password",
267
- "clickhouse": "user-password",
268
- "kintone": "user-password",
284
+ postgresql: "user-password",
285
+ mysql: "user-password",
286
+ clickhouse: "user-password",
287
+ kintone: "user-password",
269
288
  "squadbase-db": "user-password",
270
289
  // service-account
271
- "snowflake": "service-account",
272
- "bigquery": "service-account",
290
+ snowflake: "service-account",
291
+ bigquery: "service-account",
273
292
  "google-analytics": "service-account",
274
293
  "google-calendar": "service-account",
275
294
  "aws-athena": "service-account",
276
- "redshift": "service-account",
295
+ redshift: "service-account",
277
296
  // api-key
278
- "databricks": "api-key",
279
- "dbt": "api-key",
280
- "airtable": "api-key",
281
- "openai": "api-key",
282
- "gemini": "api-key",
283
- "anthropic": "api-key",
297
+ databricks: "api-key",
298
+ dbt: "api-key",
299
+ airtable: "api-key",
300
+ openai: "api-key",
301
+ gemini: "api-key",
302
+ anthropic: "api-key",
284
303
  "wix-store": "api-key"
285
304
  };
286
305
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
@@ -151,6 +151,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
151
151
  * `runSetupFlow` from `setup-flow.ts`.
152
152
  */
153
153
  setup;
154
+ /**
155
+ * 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
156
+ * メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
157
+ * {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
158
+ * 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
159
+ * `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
160
+ * coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
161
+ */
162
+ introspect;
154
163
  /**
155
164
  * Opt-out of the default "verify before save" behavior on connection
156
165
  * creation. The backend invokes `checkConnection` synchronously while
@@ -165,6 +174,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
165
174
  * the default verify-on-create behavior without opt-in.
166
175
  */
167
176
  skipConnectionCheckOnCreate;
177
+ /**
178
+ * 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
179
+ * read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
180
+ * recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
181
+ * driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
182
+ * 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
183
+ */
184
+ surveyProbes;
168
185
  constructor(config) {
169
186
  this.slug = config.slug;
170
187
  this.authType = config.authType;
@@ -182,7 +199,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
182
199
  this.query = config.query;
183
200
  this.checkConnection = config.checkConnection;
184
201
  this.setup = config.setup;
202
+ this.introspect = config.introspect;
185
203
  this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
204
+ this.surveyProbes = config.surveyProbes;
186
205
  }
187
206
  get connectorKey() {
188
207
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -220,25 +239,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
220
239
  if (authType) return `${slug}-${authType}`;
221
240
  const LEGACY_NULL_AUTH_TYPE_MAP = {
222
241
  // user-password
223
- "postgresql": "user-password",
224
- "mysql": "user-password",
225
- "clickhouse": "user-password",
226
- "kintone": "user-password",
242
+ postgresql: "user-password",
243
+ mysql: "user-password",
244
+ clickhouse: "user-password",
245
+ kintone: "user-password",
227
246
  "squadbase-db": "user-password",
228
247
  // service-account
229
- "snowflake": "service-account",
230
- "bigquery": "service-account",
248
+ snowflake: "service-account",
249
+ bigquery: "service-account",
231
250
  "google-analytics": "service-account",
232
251
  "google-calendar": "service-account",
233
252
  "aws-athena": "service-account",
234
- "redshift": "service-account",
253
+ redshift: "service-account",
235
254
  // api-key
236
- "databricks": "api-key",
237
- "dbt": "api-key",
238
- "airtable": "api-key",
239
- "openai": "api-key",
240
- "gemini": "api-key",
241
- "anthropic": "api-key",
255
+ databricks: "api-key",
256
+ dbt: "api-key",
257
+ airtable: "api-key",
258
+ openai: "api-key",
259
+ gemini: "api-key",
260
+ anthropic: "api-key",
242
261
  "wix-store": "api-key"
243
262
  };
244
263
  const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];