@squadbase/vite-server 0.1.17-dev.24af54e → 0.1.17-dev.423ee34

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 (77) hide show
  1. package/dist/cli/index.js +4873 -1073
  2. package/dist/connectors/airtable-oauth.js +78 -11
  3. package/dist/connectors/airtable.js +74 -11
  4. package/dist/connectors/amplitude.js +38 -11
  5. package/dist/connectors/anthropic.js +4 -2
  6. package/dist/connectors/asana.js +67 -13
  7. package/dist/connectors/attio.js +60 -16
  8. package/dist/connectors/aws-billing.js +38 -11
  9. package/dist/connectors/azure-sql.js +64 -13
  10. package/dist/connectors/backlog-api-key.js +70 -18
  11. package/dist/connectors/clickup.js +80 -13
  12. package/dist/connectors/cosmosdb.js +42 -15
  13. package/dist/connectors/customerio.js +39 -12
  14. package/dist/connectors/dbt.js +716 -28
  15. package/dist/connectors/freshdesk.js +112 -11
  16. package/dist/connectors/freshsales.js +38 -11
  17. package/dist/connectors/freshservice.js +38 -11
  18. package/dist/connectors/gamma.js +47 -20
  19. package/dist/connectors/gemini.js +4 -2
  20. package/dist/connectors/github.js +42 -15
  21. package/dist/connectors/gmail-oauth.js +38 -13
  22. package/dist/connectors/gmail.js +34 -7
  23. package/dist/connectors/google-ads.js +38 -11
  24. package/dist/connectors/google-analytics-oauth.js +182 -28
  25. package/dist/connectors/google-analytics.js +653 -104
  26. package/dist/connectors/google-audit-log.js +34 -7
  27. package/dist/connectors/google-calendar-oauth.js +91 -18
  28. package/dist/connectors/google-calendar.js +91 -14
  29. package/dist/connectors/google-docs.js +38 -13
  30. package/dist/connectors/google-drive.js +60 -13
  31. package/dist/connectors/google-search-console-oauth.js +156 -20
  32. package/dist/connectors/google-sheets.js +36 -9
  33. package/dist/connectors/google-slides.js +38 -13
  34. package/dist/connectors/grafana.js +75 -13
  35. package/dist/connectors/hubspot-oauth.js +69 -12
  36. package/dist/connectors/hubspot.js +55 -12
  37. package/dist/connectors/influxdb.js +38 -11
  38. package/dist/connectors/intercom-oauth.js +100 -15
  39. package/dist/connectors/intercom.js +42 -15
  40. package/dist/connectors/jdbc.js +36 -9
  41. package/dist/connectors/jira-api-key.js +98 -14
  42. package/dist/connectors/kintone-api-token.js +96 -21
  43. package/dist/connectors/kintone.js +84 -14
  44. package/dist/connectors/linear.js +84 -15
  45. package/dist/connectors/linkedin-ads.js +71 -17
  46. package/dist/connectors/mailchimp-oauth.js +36 -9
  47. package/dist/connectors/mailchimp.js +36 -9
  48. package/dist/connectors/meta-ads-oauth.js +63 -17
  49. package/dist/connectors/meta-ads.js +65 -17
  50. package/dist/connectors/mixpanel.js +38 -11
  51. package/dist/connectors/monday.js +39 -12
  52. package/dist/connectors/mongodb.js +38 -11
  53. package/dist/connectors/notion-oauth.js +88 -14
  54. package/dist/connectors/notion.js +90 -14
  55. package/dist/connectors/openai.js +4 -2
  56. package/dist/connectors/oracle.js +78 -20
  57. package/dist/connectors/outlook-oauth.js +48 -23
  58. package/dist/connectors/powerbi-oauth.js +321 -49
  59. package/dist/connectors/salesforce.js +72 -12
  60. package/dist/connectors/semrush.js +374 -52
  61. package/dist/connectors/sentry.js +66 -13
  62. package/dist/connectors/shopify-oauth.js +71 -13
  63. package/dist/connectors/shopify.js +38 -11
  64. package/dist/connectors/sqlserver.js +64 -13
  65. package/dist/connectors/stripe-api-key.js +96 -18
  66. package/dist/connectors/stripe-oauth.js +98 -22
  67. package/dist/connectors/supabase.js +55 -11
  68. package/dist/connectors/tableau.js +262 -92
  69. package/dist/connectors/tiktok-ads.js +67 -19
  70. package/dist/connectors/wix-store.js +38 -11
  71. package/dist/connectors/zendesk-oauth.js +83 -15
  72. package/dist/connectors/zendesk.js +42 -15
  73. package/dist/index.d.ts +1 -0
  74. package/dist/index.js +4902 -1077
  75. package/dist/main.js +4891 -1071
  76. package/dist/vite-plugin.js +4871 -1071
  77. package/package.json +1 -1
@@ -21,6 +21,7 @@ var init_parameter_definition = __esm({
21
21
  type;
22
22
  secret;
23
23
  required;
24
+ isDeprecated;
24
25
  constructor(config) {
25
26
  this.slug = config.slug;
26
27
  this.name = config.name;
@@ -29,6 +30,7 @@ var init_parameter_definition = __esm({
29
30
  this.type = config.type;
30
31
  this.secret = config.secret;
31
32
  this.required = config.required;
33
+ this.isDeprecated = config.isDeprecated ?? false;
32
34
  }
33
35
  /**
34
36
  * Get the parameter value from a ConnectorConnectionObject.
@@ -511,7 +513,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
511
513
  /**
512
514
  * Create tools for connections that belong to this connector.
513
515
  * Filters connections by connectorKey internally.
514
- * Returns tools keyed as `${connectorKey}_${toolName}`.
516
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
515
517
  */
516
518
  createTools(connections, config, opts) {
517
519
  const myConnections = connections.filter(
@@ -521,7 +523,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
521
523
  for (const t of Object.values(this.tools)) {
522
524
  const tool = t.createTool(myConnections, config);
523
525
  const originalToModelOutput = tool.toModelOutput;
524
- result[`${this.connectorKey}_${t.name}`] = {
526
+ result[`connector_${this.connectorKey}_${t.name}`] = {
525
527
  ...tool,
526
528
  toModelOutput: async (options) => {
527
529
  if (!originalToModelOutput) {
@@ -577,19 +579,34 @@ async function runSetupFlow(flow, params, ctx, config) {
577
579
  };
578
580
  let state = flow.initialState();
579
581
  let answerIdx = 0;
582
+ const pendingParameterUpdates = [];
580
583
  for (const step of flow.steps) {
581
584
  const ans = ctx.answers[answerIdx];
582
585
  if (ans && ans.questionSlug === step.slug) {
583
586
  state = step.applyAnswer(state, ans.answer);
587
+ if (step.toParameterUpdates) {
588
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
589
+ }
584
590
  answerIdx += 1;
585
591
  continue;
586
592
  }
593
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
587
594
  if (step.type === "text") {
595
+ if (step.fetchOptions) {
596
+ const options2 = await step.fetchOptions(state, runtime);
597
+ if (options2.length === 0) {
598
+ continue;
599
+ }
600
+ }
588
601
  return {
589
602
  type: "nextQuestion",
590
603
  questionSlug: step.slug,
591
604
  question: step.question[ctx.language],
592
- questionType: "text"
605
+ questionType: "text",
606
+ allowFreeText: resolvedAllowFreeText,
607
+ ...pendingParameterUpdates.length > 0 && {
608
+ parameterUpdates: pendingParameterUpdates
609
+ }
593
610
  };
594
611
  }
595
612
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -601,11 +618,21 @@ async function runSetupFlow(flow, params, ctx, config) {
601
618
  questionSlug: step.slug,
602
619
  question: step.question[ctx.language],
603
620
  questionType: step.type,
604
- options
621
+ options,
622
+ allowFreeText: resolvedAllowFreeText,
623
+ ...pendingParameterUpdates.length > 0 && {
624
+ parameterUpdates: pendingParameterUpdates
625
+ }
605
626
  };
606
627
  }
607
628
  const dataInvestigationResult = await flow.finalize(state, runtime);
608
- return { type: "fulfilled", dataInvestigationResult };
629
+ return {
630
+ type: "fulfilled",
631
+ dataInvestigationResult,
632
+ ...pendingParameterUpdates.length > 0 && {
633
+ parameterUpdates: pendingParameterUpdates
634
+ }
635
+ };
609
636
  }
610
637
  async function resolveSetupSelection(params) {
611
638
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -700,8 +727,8 @@ function buildFlow(options) {
700
727
  slug: "tables",
701
728
  type: "multiSelect",
702
729
  question: {
703
- ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
704
- en: "Select target tables (multi-select allowed)"
730
+ ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u30FB\u30D3\u30E5\u30FC\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
731
+ en: "Select target tables and views (multi-select allowed)"
705
732
  },
706
733
  async fetchOptions(state, rt) {
707
734
  if (!state.schema) return [];
@@ -710,7 +737,7 @@ function buildFlow(options) {
710
737
  return [
711
738
  {
712
739
  value: ALL_TABLES,
713
- label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
740
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB\u30FB\u30D3\u30E5\u30FC" : "All tables and views"
714
741
  },
715
742
  ...tableOptions
716
743
  ];
@@ -729,6 +756,28 @@ function buildFlow(options) {
729
756
  fetchAll: () => fetchTableNames(rt.params, schema),
730
757
  limit: SQLSERVER_SETUP_MAX_TABLES
731
758
  });
759
+ let rowCounts = /* @__PURE__ */ new Map();
760
+ try {
761
+ const countRows = await runSqlServerSetupQuery(
762
+ rt.params,
763
+ `SELECT t.TABLE_NAME, SUM(p.rows) AS row_count
764
+ FROM INFORMATION_SCHEMA.TABLES t
765
+ JOIN sys.partitions p
766
+ ON OBJECT_ID(t.TABLE_SCHEMA + '.' + t.TABLE_NAME) = p.object_id
767
+ AND p.index_id IN (0, 1)
768
+ WHERE t.TABLE_SCHEMA = ${quoteLiteral(schema)}
769
+ AND t.TABLE_TYPE IN ('BASE TABLE', 'VIEW')
770
+ GROUP BY t.TABLE_NAME`,
771
+ forceEncrypt
772
+ );
773
+ rowCounts = new Map(
774
+ countRows.map((r) => [
775
+ String(r["TABLE_NAME"] ?? ""),
776
+ Number(r["row_count"] ?? 0)
777
+ ])
778
+ );
779
+ } catch {
780
+ }
732
781
  const sections = [
733
782
  `## ${connectorName}`,
734
783
  "",
@@ -745,7 +794,9 @@ function buildFlow(options) {
745
794
  ORDER BY ORDINAL_POSITION`,
746
795
  forceEncrypt
747
796
  );
748
- sections.push(`#### Table: ${table}`, "");
797
+ const rowCount = rowCounts.get(table);
798
+ const heading = typeof rowCount === "number" ? `#### Table: ${table} (~${rowCount.toLocaleString()} rows)` : `#### Table: ${table}`;
799
+ sections.push(heading, "");
749
800
  sections.push("| Column | Type | Nullable | Default |");
750
801
  sections.push("|--------|------|----------|---------|");
751
802
  for (const c of cols) {
@@ -778,11 +829,11 @@ init_utils();
778
829
  // ../connectors/src/connectors/azure-sql/setup.ts
779
830
  var azureSqlOnboarding = new ConnectorOnboarding({
780
831
  dataOverviewInstructions: {
781
- en: `1. Use azure-sql_executeQuery to confirm the database flavor: \`SELECT @@VERSION\` (Azure SQL returns "Microsoft SQL Azure \u2026")
832
+ en: `1. Use connector_azure-sql_executeQuery to confirm the database flavor: \`SELECT @@VERSION\` (Azure SQL returns "Microsoft SQL Azure \u2026")
782
833
  2. List user tables: \`SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')\`
783
834
  3. For key tables, fetch column info: \`SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'xxx'\`
784
835
  4. Sample up to 3 tables. Azure SQL is T-SQL, so use \`TOP\` rather than \`LIMIT\`: \`SELECT TOP 5 * FROM <schema>.<table_name>\``,
785
- ja: `1. azure-sql_executeQuery \u3067\u30D5\u30EC\u30FC\u30D0\u30FC\u3092\u78BA\u8A8D: \`SELECT @@VERSION\`\uFF08Azure SQL \u306F "Microsoft SQL Azure \u2026" \u3092\u8FD4\u3057\u307E\u3059\uFF09
836
+ ja: `1. connector_azure-sql_executeQuery \u3067\u30D5\u30EC\u30FC\u30D0\u30FC\u3092\u78BA\u8A8D: \`SELECT @@VERSION\`\uFF08Azure SQL \u306F "Microsoft SQL Azure \u2026" \u3092\u8FD4\u3057\u307E\u3059\uFF09
786
837
  2. \u30E6\u30FC\u30B6\u30FC\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7: \`SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')\`
787
838
  3. \u4E3B\u8981\u30C6\u30FC\u30D6\u30EB\u306E\u30AB\u30E9\u30E0\u60C5\u5831: \`SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'xxx'\`
788
839
  4. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u6700\u59273\u30C6\u30FC\u30D6\u30EB\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3002Azure SQL \u306F T-SQL \u306E\u305F\u3081 \`LIMIT\` \u3067\u306F\u306A\u304F \`TOP\` \u3092\u4F7F\u7528: \`SELECT TOP 5 * FROM <schema>.<table_name>\``
@@ -888,7 +939,7 @@ var azureSqlConnector = new ConnectorPlugin({
888
939
  systemPrompt: {
889
940
  en: `### Tools
890
941
 
891
- - \`azure-sql_executeQuery\`: Executes a T-SQL query against Azure SQL Database and returns rows. Use for schema exploration via \`INFORMATION_SCHEMA\` and data sampling. See the SQL Reference below for Azure SQL-specific notes.
942
+ - \`connector_azure-sql_executeQuery\`: Executes a T-SQL query against Azure SQL Database and returns rows. Use for schema exploration via \`INFORMATION_SCHEMA\` and data sampling. See the SQL Reference below for Azure SQL-specific notes.
892
943
 
893
944
  ### Business Logic
894
945
 
@@ -905,7 +956,7 @@ The business logic type for this connector is "sql".
905
956
  - Row-limit compatibility: the platform's server-logic schema inference may wrap your query as \`SELECT * FROM (<inner>) AS _sq LIMIT N\`. T-SQL does not understand \`LIMIT\`, so the connector detects this exact wrapper at \`query()\` time, executes \`<inner>\` directly, and slices the first N rows in JS. You do not need to handle this \u2014 but do not author your own \`LIMIT\` clauses; use \`TOP\` / \`OFFSET ... FETCH NEXT\` in queries you write.`,
906
957
  ja: `### \u30C4\u30FC\u30EB
907
958
 
908
- - \`azure-sql_executeQuery\`: Azure SQL Database \u306B\u5BFE\u3057\u3066 T-SQL \u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\`INFORMATION_SCHEMA\` \u3092\u4F7F\u3063\u305F\u30B9\u30AD\u30FC\u30DE\u63A2\u7D22\u3084\u30C7\u30FC\u30BF\u306E\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u306B\u4F7F\u3044\u307E\u3059\u3002Azure SQL \u56FA\u6709\u306E\u6CE8\u610F\u70B9\u306F\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
959
+ - \`connector_azure-sql_executeQuery\`: Azure SQL Database \u306B\u5BFE\u3057\u3066 T-SQL \u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\`INFORMATION_SCHEMA\` \u3092\u4F7F\u3063\u305F\u30B9\u30AD\u30FC\u30DE\u63A2\u7D22\u3084\u30C7\u30FC\u30BF\u306E\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u306B\u4F7F\u3044\u307E\u3059\u3002Azure SQL \u56FA\u6709\u306E\u6CE8\u610F\u70B9\u306F\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
909
960
 
910
961
  ### Business Logic
911
962
 
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
16
16
  type;
17
17
  secret;
18
18
  required;
19
+ isDeprecated;
19
20
  constructor(config) {
20
21
  this.slug = config.slug;
21
22
  this.name = config.name;
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
24
25
  this.type = config.type;
25
26
  this.secret = config.secret;
26
27
  this.required = config.required;
28
+ this.isDeprecated = config.isDeprecated ?? false;
27
29
  }
28
30
  /**
29
31
  * Get the parameter value from a ConnectorConnectionObject.
@@ -210,7 +212,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
210
212
  /**
211
213
  * Create tools for connections that belong to this connector.
212
214
  * Filters connections by connectorKey internally.
213
- * Returns tools keyed as `${connectorKey}_${toolName}`.
215
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
214
216
  */
215
217
  createTools(connections, config, opts) {
216
218
  const myConnections = connections.filter(
@@ -220,7 +222,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
220
222
  for (const t of Object.values(this.tools)) {
221
223
  const tool = t.createTool(myConnections, config);
222
224
  const originalToModelOutput = tool.toModelOutput;
223
- result[`${this.connectorKey}_${t.name}`] = {
225
+ result[`connector_${this.connectorKey}_${t.name}`] = {
224
226
  ...tool,
225
227
  toModelOutput: async (options) => {
226
228
  if (!originalToModelOutput) {
@@ -276,19 +278,34 @@ async function runSetupFlow(flow, params, ctx, config) {
276
278
  };
277
279
  let state = flow.initialState();
278
280
  let answerIdx = 0;
281
+ const pendingParameterUpdates = [];
279
282
  for (const step of flow.steps) {
280
283
  const ans = ctx.answers[answerIdx];
281
284
  if (ans && ans.questionSlug === step.slug) {
282
285
  state = step.applyAnswer(state, ans.answer);
286
+ if (step.toParameterUpdates) {
287
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
288
+ }
283
289
  answerIdx += 1;
284
290
  continue;
285
291
  }
292
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
286
293
  if (step.type === "text") {
294
+ if (step.fetchOptions) {
295
+ const options2 = await step.fetchOptions(state, runtime);
296
+ if (options2.length === 0) {
297
+ continue;
298
+ }
299
+ }
287
300
  return {
288
301
  type: "nextQuestion",
289
302
  questionSlug: step.slug,
290
303
  question: step.question[ctx.language],
291
- questionType: "text"
304
+ questionType: "text",
305
+ allowFreeText: resolvedAllowFreeText,
306
+ ...pendingParameterUpdates.length > 0 && {
307
+ parameterUpdates: pendingParameterUpdates
308
+ }
292
309
  };
293
310
  }
294
311
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -300,11 +317,21 @@ async function runSetupFlow(flow, params, ctx, config) {
300
317
  questionSlug: step.slug,
301
318
  question: step.question[ctx.language],
302
319
  questionType: step.type,
303
- options
320
+ options,
321
+ allowFreeText: resolvedAllowFreeText,
322
+ ...pendingParameterUpdates.length > 0 && {
323
+ parameterUpdates: pendingParameterUpdates
324
+ }
304
325
  };
305
326
  }
306
327
  const dataInvestigationResult = await flow.finalize(state, runtime);
307
- return { type: "fulfilled", dataInvestigationResult };
328
+ return {
329
+ type: "fulfilled",
330
+ dataInvestigationResult,
331
+ ...pendingParameterUpdates.length > 0 && {
332
+ parameterUpdates: pendingParameterUpdates
333
+ }
334
+ };
308
335
  }
309
336
  async function resolveSetupSelection(params) {
310
337
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -325,14 +352,14 @@ var AUTH_TYPES = {
325
352
  // ../connectors/src/connectors/backlog/setup.ts
326
353
  var backlogOnboarding = new ConnectorOnboarding({
327
354
  dataOverviewInstructions: {
328
- en: `1. Call backlog-api-key_request with GET space to verify the connection and get space information
329
- 2. Call backlog-api-key_request with GET projects to list all accessible projects
330
- 3. For key projects, call backlog-api-key_request with GET issues?projectId[]={projectId}&count=5&order=desc to retrieve recent issues
331
- 4. Call backlog-api-key_request with GET projects/{projectIdOrKey}/statuses to understand the workflow statuses`,
332
- ja: `1. backlog-api-key_request \u3067 GET space \u3092\u547C\u3073\u51FA\u3057\u3001\u63A5\u7D9A\u78BA\u8A8D\u3068\u30B9\u30DA\u30FC\u30B9\u60C5\u5831\u3092\u53D6\u5F97
333
- 2. backlog-api-key_request \u3067 GET projects \u3092\u547C\u3073\u51FA\u3057\u3001\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
334
- 3. \u4E3B\u8981\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u3064\u3044\u3066 backlog-api-key_request \u3067 GET issues?projectId[]={projectId}&count=5&order=desc \u3092\u547C\u3073\u51FA\u3057\u3001\u6700\u8FD1\u306E\u8AB2\u984C\u3092\u53D6\u5F97
335
- 4. backlog-api-key_request \u3067 GET projects/{projectIdOrKey}/statuses \u3092\u547C\u3073\u51FA\u3057\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E\u30B9\u30C6\u30FC\u30BF\u30B9\u3092\u78BA\u8A8D`
355
+ en: `1. Call connector_backlog-api-key_request with GET space to verify the connection and get space information
356
+ 2. Call connector_backlog-api-key_request with GET projects to list all accessible projects
357
+ 3. For key projects, call connector_backlog-api-key_request with GET issues?projectId[]={projectId}&count=5&order=desc to retrieve recent issues
358
+ 4. Call connector_backlog-api-key_request with GET projects/{projectIdOrKey}/statuses to understand the workflow statuses`,
359
+ ja: `1. connector_backlog-api-key_request \u3067 GET space \u3092\u547C\u3073\u51FA\u3057\u3001\u63A5\u7D9A\u78BA\u8A8D\u3068\u30B9\u30DA\u30FC\u30B9\u60C5\u5831\u3092\u53D6\u5F97
360
+ 2. connector_backlog-api-key_request \u3067 GET projects \u3092\u547C\u3073\u51FA\u3057\u3001\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
361
+ 3. \u4E3B\u8981\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u3064\u3044\u3066 connector_backlog-api-key_request \u3067 GET issues?projectId[]={projectId}&count=5&order=desc \u3092\u547C\u3073\u51FA\u3057\u3001\u6700\u8FD1\u306E\u8AB2\u984C\u3092\u53D6\u5F97
362
+ 4. connector_backlog-api-key_request \u3067 GET projects/{projectIdOrKey}/statuses \u3092\u547C\u3073\u51FA\u3057\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E\u30B9\u30C6\u30FC\u30BF\u30B9\u3092\u78BA\u8A8D`
336
363
  }
337
364
  });
338
365
 
@@ -381,6 +408,20 @@ async function listStatuses(params, projectIdOrKey) {
381
408
  if (!res.ok) return [];
382
409
  return await res.json();
383
410
  }
411
+ async function countIssues(params, projectId, statusId) {
412
+ try {
413
+ const statusParam = statusId ? `&statusId[]=${statusId}` : "";
414
+ const res = await apiFetch(
415
+ params,
416
+ `issues/count?projectId[]=${encodeURIComponent(projectId)}${statusParam}`
417
+ );
418
+ if (!res.ok) return null;
419
+ const data = await res.json();
420
+ return typeof data.count === "number" ? data.count : null;
421
+ } catch {
422
+ return null;
423
+ }
424
+ }
384
425
  var backlogSetupFlow = {
385
426
  initialState: () => ({}),
386
427
  steps: [
@@ -430,14 +471,25 @@ var backlogSetupFlow = {
430
471
  continue;
431
472
  }
432
473
  sections.push(`### Project: ${project.name} (${project.projectKey})`, "");
433
- const [issueTypes, statuses] = await Promise.all([
474
+ const [issueTypes, statuses, totalIssues] = await Promise.all([
434
475
  listIssueTypes(rt.params, id),
435
- listStatuses(rt.params, id)
476
+ listStatuses(rt.params, id),
477
+ countIssues(rt.params, id)
436
478
  ]);
479
+ if (totalIssues != null) {
480
+ sections.push(`- Total issues: ${totalIssues.toLocaleString()}`);
481
+ }
437
482
  sections.push(`- Issue types (${issueTypes.length}):`);
438
483
  for (const t of issueTypes) sections.push(` - ${t.name}`);
484
+ const statusCounts = await Promise.all(
485
+ statuses.map((s) => countIssues(rt.params, id, s.id))
486
+ );
439
487
  sections.push(`- Statuses (${statuses.length}):`);
440
- for (const s of statuses) sections.push(` - ${s.name}`);
488
+ for (let i = 0; i < statuses.length; i++) {
489
+ const c = statusCounts[i];
490
+ const cStr = c != null ? `: ${c.toLocaleString()} issues` : "";
491
+ sections.push(` - ${statuses[i].name}${cStr}`);
492
+ }
441
493
  sections.push("");
442
494
  }
443
495
  return sections.join("\n");
@@ -536,7 +588,7 @@ var backlogConnector = new ConnectorPlugin({
536
588
  systemPrompt: {
537
589
  en: `### Tools
538
590
 
539
- - \`backlog-api-key_request\`: The only way to call the Backlog REST API (v2). Use it to list projects, search issues, get issue details, create/update issues, manage wikis, and retrieve users. Authentication (API key as query parameter) and space URL are configured automatically.
591
+ - \`connector_backlog-api-key_request\`: The only way to call the Backlog REST API (v2). Use it to list projects, search issues, get issue details, create/update issues, manage wikis, and retrieve users. Authentication (API key as query parameter) and space URL are configured automatically.
540
592
 
541
593
  ### Business Logic
542
594
 
@@ -608,7 +660,7 @@ await backlog.request("/api/v2/issues", {
608
660
  - order: "asc" or "desc"`,
609
661
  ja: `### \u30C4\u30FC\u30EB
610
662
 
611
- - \`backlog-api-key_request\`: Backlog REST API\uFF08v2\uFF09\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u8AB2\u984C\u306E\u691C\u7D22\u3001\u8AB2\u984C\u8A73\u7D30\u306E\u53D6\u5F97\u3001\u8AB2\u984C\u306E\u4F5C\u6210\u30FB\u66F4\u65B0\u3001Wiki\u7BA1\u7406\u3001\u30E6\u30FC\u30B6\u30FC\u53D6\u5F97\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API\u30AD\u30FC\u3092\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u4ED8\u4E0E\uFF09\u3068\u30B9\u30DA\u30FC\u30B9URL\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
663
+ - \`connector_backlog-api-key_request\`: Backlog REST API\uFF08v2\uFF09\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u8AB2\u984C\u306E\u691C\u7D22\u3001\u8AB2\u984C\u8A73\u7D30\u306E\u53D6\u5F97\u3001\u8AB2\u984C\u306E\u4F5C\u6210\u30FB\u66F4\u65B0\u3001Wiki\u7BA1\u7406\u3001\u30E6\u30FC\u30B6\u30FC\u53D6\u5F97\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API\u30AD\u30FC\u3092\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u4ED8\u4E0E\uFF09\u3068\u30B9\u30DA\u30FC\u30B9URL\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
612
664
 
613
665
  ### Business Logic
614
666
 
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
16
16
  type;
17
17
  secret;
18
18
  required;
19
+ isDeprecated;
19
20
  constructor(config) {
20
21
  this.slug = config.slug;
21
22
  this.name = config.name;
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
24
25
  this.type = config.type;
25
26
  this.secret = config.secret;
26
27
  this.required = config.required;
28
+ this.isDeprecated = config.isDeprecated ?? false;
27
29
  }
28
30
  /**
29
31
  * Get the parameter value from a ConnectorConnectionObject.
@@ -346,7 +348,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
346
348
  /**
347
349
  * Create tools for connections that belong to this connector.
348
350
  * Filters connections by connectorKey internally.
349
- * Returns tools keyed as `${connectorKey}_${toolName}`.
351
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
350
352
  */
351
353
  createTools(connections, config, opts) {
352
354
  const myConnections = connections.filter(
@@ -356,7 +358,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
356
358
  for (const t of Object.values(this.tools)) {
357
359
  const tool = t.createTool(myConnections, config);
358
360
  const originalToModelOutput = tool.toModelOutput;
359
- result[`${this.connectorKey}_${t.name}`] = {
361
+ result[`connector_${this.connectorKey}_${t.name}`] = {
360
362
  ...tool,
361
363
  toModelOutput: async (options) => {
362
364
  if (!originalToModelOutput) {
@@ -412,19 +414,34 @@ async function runSetupFlow(flow, params, ctx, config) {
412
414
  };
413
415
  let state = flow.initialState();
414
416
  let answerIdx = 0;
417
+ const pendingParameterUpdates = [];
415
418
  for (const step of flow.steps) {
416
419
  const ans = ctx.answers[answerIdx];
417
420
  if (ans && ans.questionSlug === step.slug) {
418
421
  state = step.applyAnswer(state, ans.answer);
422
+ if (step.toParameterUpdates) {
423
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
424
+ }
419
425
  answerIdx += 1;
420
426
  continue;
421
427
  }
428
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
422
429
  if (step.type === "text") {
430
+ if (step.fetchOptions) {
431
+ const options2 = await step.fetchOptions(state, runtime);
432
+ if (options2.length === 0) {
433
+ continue;
434
+ }
435
+ }
423
436
  return {
424
437
  type: "nextQuestion",
425
438
  questionSlug: step.slug,
426
439
  question: step.question[ctx.language],
427
- questionType: "text"
440
+ questionType: "text",
441
+ allowFreeText: resolvedAllowFreeText,
442
+ ...pendingParameterUpdates.length > 0 && {
443
+ parameterUpdates: pendingParameterUpdates
444
+ }
428
445
  };
429
446
  }
430
447
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -436,11 +453,21 @@ async function runSetupFlow(flow, params, ctx, config) {
436
453
  questionSlug: step.slug,
437
454
  question: step.question[ctx.language],
438
455
  questionType: step.type,
439
- options
456
+ options,
457
+ allowFreeText: resolvedAllowFreeText,
458
+ ...pendingParameterUpdates.length > 0 && {
459
+ parameterUpdates: pendingParameterUpdates
460
+ }
440
461
  };
441
462
  }
442
463
  const dataInvestigationResult = await flow.finalize(state, runtime);
443
- return { type: "fulfilled", dataInvestigationResult };
464
+ return {
465
+ type: "fulfilled",
466
+ dataInvestigationResult,
467
+ ...pendingParameterUpdates.length > 0 && {
468
+ parameterUpdates: pendingParameterUpdates
469
+ }
470
+ };
444
471
  }
445
472
  async function resolveSetupSelection(params) {
446
473
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -471,15 +498,15 @@ function normalizeRequestPath(path2, basePathSegment) {
471
498
  // ../connectors/src/connectors/clickup/setup.ts
472
499
  var clickupOnboarding = new ConnectorOnboarding({
473
500
  dataOverviewInstructions: {
474
- en: `1. Call clickup_request with GET /team to list workspaces (the ClickUp API still calls workspaces "teams"). Pick the first workspace's \`id\`.
475
- 2. Call clickup_request with GET /team/{team_id}/space?archived=false to list spaces in the workspace.
501
+ en: `1. Call connector_clickup_request with GET /team to list workspaces (the ClickUp API still calls workspaces "teams"). Pick the first workspace's \`id\`.
502
+ 2. Call connector_clickup_request with GET /team/{team_id}/space?archived=false to list spaces in the workspace.
476
503
  3. Pick one space and list its folders (GET /space/{space_id}/folder?archived=false) and folderless lists (GET /space/{space_id}/list?archived=false). Each folder also contains lists at GET /folder/{folder_id}/list.
477
- 4. Pick one list and call clickup_request with GET /list/{list_id}/task?page=0&include_closed=true to sample tasks. Inspect each task's \`status\`, \`assignees\`, \`due_date\`, and \`custom_fields\`.
504
+ 4. Pick one list and call connector_clickup_request with GET /list/{list_id}/task?page=0&include_closed=true to sample tasks. Inspect each task's \`status\`, \`assignees\`, \`due_date\`, and \`custom_fields\`.
478
505
  5. If custom fields are used, call GET /list/{list_id}/field to get their definitions.`,
479
- ja: `1. clickup_request \u3067 GET /team \u3092\u547C\u3073\u51FA\u3057\u3066\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\uFF08ClickUp API \u3067\u306F\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092 "team" \u3068\u547C\u3073\u307E\u3059\uFF09\u3002\u6700\u521D\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E \`id\` \u3092\u9078\u629E\u3057\u307E\u3059\u3002
480
- 2. clickup_request \u3067 GET /team/{team_id}/space?archived=false \u3092\u547C\u3073\u51FA\u3057\u3066\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002
506
+ ja: `1. connector_clickup_request \u3067 GET /team \u3092\u547C\u3073\u51FA\u3057\u3066\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\uFF08ClickUp API \u3067\u306F\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092 "team" \u3068\u547C\u3073\u307E\u3059\uFF09\u3002\u6700\u521D\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E \`id\` \u3092\u9078\u629E\u3057\u307E\u3059\u3002
507
+ 2. connector_clickup_request \u3067 GET /team/{team_id}/space?archived=false \u3092\u547C\u3073\u51FA\u3057\u3066\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002
481
508
  3. \u30B9\u30DA\u30FC\u30B9\u30921\u3064\u9078\u3073\u3001\u30D5\u30A9\u30EB\u30C0\u4E00\u89A7\uFF08GET /space/{space_id}/folder?archived=false\uFF09\u3068\u30D5\u30A9\u30EB\u30C0\u7121\u3057\u30EA\u30B9\u30C8\u4E00\u89A7\uFF08GET /space/{space_id}/list?archived=false\uFF09\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u5404\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u30EA\u30B9\u30C8\u306F GET /folder/{folder_id}/list \u3067\u53D6\u5F97\u3067\u304D\u307E\u3059\u3002
482
- 4. \u30EA\u30B9\u30C8\u30921\u3064\u9078\u3073\u3001clickup_request \u3067 GET /list/{list_id}/task?page=0&include_closed=true \u3092\u547C\u3073\u51FA\u3057\u3066\u30BF\u30B9\u30AF\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u307E\u3059\u3002\u5404\u30BF\u30B9\u30AF\u306E \`status\`, \`assignees\`, \`due_date\`, \`custom_fields\` \u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
509
+ 4. \u30EA\u30B9\u30C8\u30921\u3064\u9078\u3073\u3001connector_clickup_request \u3067 GET /list/{list_id}/task?page=0&include_closed=true \u3092\u547C\u3073\u51FA\u3057\u3066\u30BF\u30B9\u30AF\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u307E\u3059\u3002\u5404\u30BF\u30B9\u30AF\u306E \`status\`, \`assignees\`, \`due_date\`, \`custom_fields\` \u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
483
510
  5. \u30AB\u30B9\u30BF\u30E0\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u5229\u7528\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F GET /list/{list_id}/field \u3067\u305D\u306E\u5B9A\u7FA9\u3092\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044\u3002`
484
511
  }
485
512
  });
@@ -540,6 +567,21 @@ async function listFolderlessLists(params, spaceId) {
540
567
  const data = await res.json();
541
568
  return data.lists ?? [];
542
569
  }
570
+ var CLICKUP_SAMPLE_LISTS_PER_SPACE = 5;
571
+ async function fetchListTaskCount(params, listId) {
572
+ try {
573
+ const res = await apiFetch(
574
+ params,
575
+ `/list/${encodeURIComponent(listId)}/task?archived=false&page=0`
576
+ );
577
+ if (!res.ok) return null;
578
+ const data = await res.json();
579
+ const tasks = data.tasks ?? [];
580
+ return tasks.length >= 100 ? "100+" : String(tasks.length);
581
+ } catch {
582
+ return null;
583
+ }
584
+ }
543
585
  var clickupSetupFlow = {
544
586
  initialState: () => ({}),
545
587
  steps: [
@@ -609,6 +651,31 @@ var clickupSetupFlow = {
609
651
  for (const f of folders) sections.push(` - ${f.name}`);
610
652
  sections.push(`- Folderless lists (${folderlessLists.length}):`);
611
653
  for (const l of folderlessLists) sections.push(` - ${l.name}`);
654
+ const sampled = folderlessLists.slice(0, CLICKUP_SAMPLE_LISTS_PER_SPACE);
655
+ if (sampled.length > 0) {
656
+ const counts = await Promise.all(
657
+ sampled.map((l) => fetchListTaskCount(rt.params, l.id))
658
+ );
659
+ sections.push(
660
+ "",
661
+ rt.language === "ja" ? `- \u30EA\u30B9\u30C8\u5225\u30BF\u30B9\u30AF\u4EF6\u6570 (\u4E0A\u4F4D${sampled.length}\u4EF6):` : `- Task counts (first ${sampled.length} lists):`
662
+ );
663
+ sections.push("");
664
+ sections.push("| List | Tasks |");
665
+ sections.push("|------|-------|");
666
+ for (let i = 0; i < sampled.length; i++) {
667
+ const list = sampled[i];
668
+ const count = counts[i] ?? "-";
669
+ const safeName = list.name.replace(/\|/g, "\\|");
670
+ sections.push(`| ${safeName} | ${count} |`);
671
+ }
672
+ if (folderlessLists.length > sampled.length) {
673
+ sections.push(
674
+ "",
675
+ rt.language === "ja" ? `_\u5168${folderlessLists.length}\u4EF6\u306E\u3046\u3061\u5148\u982D${sampled.length}\u4EF6\u3092\u8868\u793A_` : `_Showing first ${sampled.length} of ${folderlessLists.length} folderless lists._`
676
+ );
677
+ }
678
+ }
612
679
  sections.push("");
613
680
  }
614
681
  return sections.join("\n");
@@ -739,7 +806,7 @@ var clickupConnector = new ConnectorPlugin({
739
806
  systemPrompt: {
740
807
  en: `### Tools
741
808
 
742
- - \`clickup_request\`: The only way to call the ClickUp REST API v2. Use it to list workspaces, spaces, folders, lists, tasks, members, and custom fields. Authentication (Personal API Token in the \`Authorization\` header \u2014 no \`Bearer\` prefix) is configured automatically. Provide the API path and optionally append query parameters like \`page\`, \`archived\`, \`include_closed\`.
809
+ - \`connector_clickup_request\`: The only way to call the ClickUp REST API v2. Use it to list workspaces, spaces, folders, lists, tasks, members, and custom fields. Authentication (Personal API Token in the \`Authorization\` header \u2014 no \`Bearer\` prefix) is configured automatically. Provide the API path and optionally append query parameters like \`page\`, \`archived\`, \`include_closed\`.
743
810
 
744
811
  ### Business Logic
745
812
 
@@ -825,7 +892,7 @@ export default async function handler(c: Context) {
825
892
  - POST \`/team/{team_id}/time_entries\` \u2014 Create a time entry`,
826
893
  ja: `### \u30C4\u30FC\u30EB
827
894
 
828
- - \`clickup_request\`: ClickUp REST API v2 \u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3001\u30B9\u30DA\u30FC\u30B9\u3001\u30D5\u30A9\u30EB\u30C0\u3001\u30EA\u30B9\u30C8\u3001\u30BF\u30B9\u30AF\u3001\u30E1\u30F3\u30D0\u30FC\u3001\u30AB\u30B9\u30BF\u30E0\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u53D6\u5F97\u30FB\u66F4\u65B0\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Personal API Token \u3092 \`Authorization\` \u30D8\u30C3\u30C0\u30FC\u306B\u8A2D\u5B9A \u2014 \`Bearer\` \u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306F\u4ED8\u304D\u307E\u305B\u3093\uFF09\u306F\u81EA\u52D5\u3067\u884C\u308F\u308C\u307E\u3059\u3002API\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u3001\u5FC5\u8981\u306B\u5FDC\u3058\u3066 \`page\`, \`archived\`, \`include_closed\` \u306A\u3069\u306E\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4ED8\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002
895
+ - \`connector_clickup_request\`: ClickUp REST API v2 \u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3001\u30B9\u30DA\u30FC\u30B9\u3001\u30D5\u30A9\u30EB\u30C0\u3001\u30EA\u30B9\u30C8\u3001\u30BF\u30B9\u30AF\u3001\u30E1\u30F3\u30D0\u30FC\u3001\u30AB\u30B9\u30BF\u30E0\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u53D6\u5F97\u30FB\u66F4\u65B0\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Personal API Token \u3092 \`Authorization\` \u30D8\u30C3\u30C0\u30FC\u306B\u8A2D\u5B9A \u2014 \`Bearer\` \u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306F\u4ED8\u304D\u307E\u305B\u3093\uFF09\u306F\u81EA\u52D5\u3067\u884C\u308F\u308C\u307E\u3059\u3002API\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u3001\u5FC5\u8981\u306B\u5FDC\u3058\u3066 \`page\`, \`archived\`, \`include_closed\` \u306A\u3069\u306E\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4ED8\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002
829
896
 
830
897
  ### Business Logic
831
898