@flyle/ai-cx-mcp 0.0.0-develop.20261028035948.g64a97f7
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.
- package/LICENSE +53 -0
- package/README.md +85 -0
- package/guide-articles.json.br +0 -0
- package/main.js +120 -0
- package/manifest.json.br +0 -0
- package/package.json +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Flyle AI CX MCP サーバー 使用許諾条件
|
|
2
|
+
|
|
3
|
+
本ソフトウェア(`@flyle/ai-cx-mcp`。以下「本ソフトウェア」)に関する著作権その他
|
|
4
|
+
の知的財産権は、株式会社Flyle(以下「当社」)に帰属します。本ソフトウェアは、以下の条件に同意
|
|
5
|
+
された場合に限りご使用いただけます。
|
|
6
|
+
|
|
7
|
+
1. 使用許諾
|
|
8
|
+
|
|
9
|
+
当社は、当社との間で Flyle AI CX(以下「本サービス」)の利用契約を締結しているお客様に
|
|
10
|
+
対し、当該契約の有効期間中、本サービスを利用する目的に限り、本ソフトウェアを
|
|
11
|
+
使用する非独占的かつ譲渡不能の権利を許諾します。
|
|
12
|
+
|
|
13
|
+
本ソフトウェアの実行に必要な範囲での複製(パッケージレジストリからの取得および実行環境への
|
|
14
|
+
キャッシュを含みます)は、本許諾に含まれます。
|
|
15
|
+
|
|
16
|
+
2. 禁止事項
|
|
17
|
+
|
|
18
|
+
お客様は、前項に定める範囲を超えて本ソフトウェアを利用してはならず、特に次の行為を行っては
|
|
19
|
+
なりません。
|
|
20
|
+
|
|
21
|
+
(1) 第三者への再配布、貸与、販売、譲渡、公衆送信
|
|
22
|
+
(2) 改変、翻案、派生物の作成
|
|
23
|
+
(3) リバースエンジニアリング、逆コンパイル、逆アセンブル
|
|
24
|
+
(4) 著作権表示その他の権利に関する表示の削除または改変
|
|
25
|
+
|
|
26
|
+
3. 無保証
|
|
27
|
+
|
|
28
|
+
本ソフトウェアは現状有姿で提供されます。当社は、本ソフトウェアが特定の目的に適合すること、
|
|
29
|
+
および瑕疵がないことを保証しません。
|
|
30
|
+
|
|
31
|
+
4. 責任の制限
|
|
32
|
+
|
|
33
|
+
本ソフトウェアの使用または使用不能により生じた損害について、当社は責任を負いません。ただし、
|
|
34
|
+
当社の故意または重過失による場合はこの限りではありません。
|
|
35
|
+
|
|
36
|
+
5. 準拠法および関連規約
|
|
37
|
+
|
|
38
|
+
本許諾は日本法に準拠します。本ソフトウェアの使用には、次の規約が併せて適用されます。
|
|
39
|
+
|
|
40
|
+
- 利用規約: https://flyle.io/jp/terms
|
|
41
|
+
- プライバシーポリシー: https://flyle.io/jp/privacy-policy
|
|
42
|
+
- セキュリティポリシー: https://flyle.io/jp/security-policy
|
|
43
|
+
|
|
44
|
+
本許諾の定めと上記規約の定めとが矛盾する場合には、上記規約の定めが優先します。
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
This software is proprietary and is NOT open source. It may be used only by customers
|
|
49
|
+
with an active Flyle AI CX subscription, and solely for the purpose of using
|
|
50
|
+
that service. Redistribution, modification and reverse engineering are prohibited.
|
|
51
|
+
The Japanese text above is the governing version.
|
|
52
|
+
|
|
53
|
+
Copyright (c) 2026 Flyle, Inc. All rights reserved.
|
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @flyle/ai-cx-mcp
|
|
2
|
+
|
|
3
|
+
Flyle AI CX を Claude Code などの MCP クライアントから操作するための MCP サーバーです。ブラウザでご自身のアカウントにログインし、**ご自身のロールの権限の範囲で**テーブル・レコード・ロール・レポート・ダッシュボード・AI グルーピングを操作し、ワークフローを参照・下書きとして作成・更新できます。
|
|
4
|
+
|
|
5
|
+
> [!NOTE]
|
|
6
|
+
> 試験的な提供です。現在は Flyle 社内メンバー(flyle.io ドメインのアカウント)と、Flyle が提供を始めたテナントに限定しています。公開 API のベータ版(`v0`)に対応しており、仕様が変わる場合があります。
|
|
7
|
+
|
|
8
|
+
詳しい使い方は、ご利用ガイドの「[公開 API でテーブルのデータを連携する](https://guide.flyle.io/ja/nexus/public-api)」をご覧ください。
|
|
9
|
+
|
|
10
|
+
## 必要なもの
|
|
11
|
+
|
|
12
|
+
- Node.js 22 以上
|
|
13
|
+
- テナント設定「外部ツールからのログイン接続」が許可されていること(画面左下のメニューの「テナント設定」)
|
|
14
|
+
- ご自身のロールに「外部ツール接続」の権限があること
|
|
15
|
+
- flyle.io ドメインのアカウントでログインするか、Flyle が提供を始めたテナントであること(試験提供中の制限です)
|
|
16
|
+
|
|
17
|
+
## はじめかた
|
|
18
|
+
|
|
19
|
+
コマンドや MCP の設定では、パッケージ名に `@latest` を付けてください。付けないと、PC に残った古い版が使われ続けることがあります。
|
|
20
|
+
|
|
21
|
+
1. テナント専用の作業ディレクトリを用意します。1 つのディレクトリは 1 つのテナント専用になります。ホームディレクトリや、別のテナントの作業ディレクトリを中に含むディレクトリは使えません。
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
mkdir acme-corp && cd acme-corp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
2. そのディレクトリでログインします。ブラウザが開くので、同意画面で接続先のテナントを確認して許可してください。
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npx @flyle/ai-cx-mcp@latest login --tenant <テナント名>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
3. 同じディレクトリに `.mcp.json` を置き、Claude Code を起動します。サーバー名にテナント名を入れると、Claude Code のツール名(`mcp__flyle-ai-cx-<テナント名>__…`)でもテナントを取り違えにくくなります。
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"mcpServers": {
|
|
38
|
+
"flyle-ai-cx-<テナント名>": {
|
|
39
|
+
"command": "npx",
|
|
40
|
+
"args": ["-y", "@flyle/ai-cx-mcp@latest"]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Claude Code を起動したままログインした場合は、`/mcp` から MCP サーバーを再接続してください。
|
|
47
|
+
|
|
48
|
+
作業ディレクトリの中のサブディレクトリで Claude Code を起動しても、その作業ディレクトリのテナントで動きます。
|
|
49
|
+
|
|
50
|
+
作業ディレクトリは、同意する前の `login` の時点でテナントと接続先の専用になります。テナント名を打ち間違えるなどして、そのディレクトリで一度もログインに成功していない場合は、`.flyle-ai-cx-mcp` を削除してから `login` し直してください(保存した結果の `downloads` も消えます)。
|
|
51
|
+
|
|
52
|
+
## コマンド
|
|
53
|
+
|
|
54
|
+
作業ディレクトリで実行します。
|
|
55
|
+
|
|
56
|
+
| コマンド | 内容 |
|
|
57
|
+
| --------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
58
|
+
| `npx @flyle/ai-cx-mcp@latest login --tenant <テナント名>` | ブラウザでログインします。2 回目以降は `--tenant` を省略できます |
|
|
59
|
+
| `npx @flyle/ai-cx-mcp@latest status` | ログイン中のテナント・接続先と有効期限を表示します |
|
|
60
|
+
| `npx @flyle/ai-cx-mcp@latest logout` | ログアウトし、この作業ディレクトリの接続を切断します |
|
|
61
|
+
|
|
62
|
+
ログインは最後に使ってから 30 日間有効で、使うたびに延長されます。ただし、ログインしてから 90 日たつと、使い続けていても期限が切れるので `login` し直してください。ご自身の接続は管理画面の「設定」>「外部ツール接続」から確認・切断できます。
|
|
63
|
+
|
|
64
|
+
## できること・できないこと
|
|
65
|
+
|
|
66
|
+
- 公開 API と同じ次の操作を行えます。
|
|
67
|
+
- フォルダの一覧・取得・作成・名前の変更・移動・削除(削除したフォルダは中身ごと画面の削除済みリソースへ移ります)
|
|
68
|
+
- テーブルの一覧と定義(フィールド)の取得、テーブルの名前・説明の更新
|
|
69
|
+
- ビューの一覧・取得・作成・更新・削除
|
|
70
|
+
- フィールドの追加・更新と、選択肢の一覧の取得・追加・更新
|
|
71
|
+
- レコードの取得・検索・作成・更新・削除と、音声フィールドへの音声ファイルの保存・文字起こしの確認
|
|
72
|
+
- CSV ファイルからのレコードのインポート(アップロード先の発行・開始・状況の確認・中止)
|
|
73
|
+
- ロールの参照・作成・更新・削除と、ユーザー・ユーザーグループへの割り当て
|
|
74
|
+
- ユーザーの一覧・取得・招待・名前の変更・削除、ユーザーグループの一覧・取得・作成・更新・メンバーの追加と削除・削除
|
|
75
|
+
- レポート・ダッシュボードの参照・作成・更新と、保存前のプレビュー画像の作成
|
|
76
|
+
- AI グルーピングの参照・作成・更新・削除、グループの追加・移動・並べ替え・統合・削除、分類の実行・状況の確認・中止(AI で分類する実行は AI クレジットを消費します)
|
|
77
|
+
- ワークフローの一覧・定義と公開版の起動方法の参照、下書きの作成・更新(公開はされません)、削除、実行状況の確認
|
|
78
|
+
- テーブルの作成、フィールドの削除・種類の変更、データのエクスポート、ワークフローの公開は行えません。
|
|
79
|
+
- ワークフローの実行は API キー専用の操作です(再送で二重に実行しないよう Idempotency-Key が必須なため)。ログイン接続で動く MCP サーバーのツールにはありません。
|
|
80
|
+
- Owner ロールや全操作(`*`)を許可・拒否するロールの付与、それらを持つユーザー・ユーザーグループの削除は、画面で行います。
|
|
81
|
+
- 作業の前に Flyle AI CX の考え方とご利用ガイドの記事を読み込みます(`get_product_guide`)。読み込むまで、公開 API を呼ぶツールは実行されません。
|
|
82
|
+
- 接続時に読み込む定義を軽くするため、ツール定義には説明の要約と入力の主な項目だけを載せ、説明の全文・入力の詳しい形・入力例は `get_input_schema` で取得します。レポートの設定・ワークフローのノードの設定・フィールドの作成のように種類ごとに形が大きく違う入力は、種類を指定してその種類の詳しい形を取得します。
|
|
83
|
+
- 作成・更新・削除は下書きを経ずに、すぐテナントのデータへ反映されます。
|
|
84
|
+
- API キーやログイン接続の管理など、資格情報を扱う操作は提供していません。
|
|
85
|
+
- 大きな応答は、作業ディレクトリの `.flyle-ai-cx-mcp/downloads` にファイルとして保存されます。テナントのデータが入るので、`.flyle-ai-cx-mcp` はバージョン管理(git など)に含めないでください(git 向けには、ログイン時にこのディレクトリへ `.gitignore` を置きます)。保存したファイルは 7 日たつと、次に MCP サーバーを起動したときに削除されます。
|
|
Binary file
|
package/main.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{homedir as e,hostname as t,userInfo as n}from"node:os";import{createInterface as r}from"node:readline/promises";import{serveStdio as i}from"@modelcontextprotocol/server/stdio";import{createHash as a,randomBytes as o,timingSafeEqual as s}from"node:crypto";import{chmod as c,link as l,lstat as u,mkdir as d,open as f,readFile as p,readdir as m,realpath as h,rename as g,rm as _,writeFile as ee}from"node:fs/promises";import*as v from"node:path";import{spawn as te}from"node:child_process";import{createServer as ne}from"node:http";import{parseArgs as re}from"node:util";import{readFileSync as ie}from"node:fs";import{brotliDecompressSync as ae}from"node:zlib";import{McpServer as oe,fromJsonSchema as y}from"@modelcontextprotocol/server";import{AjvJsonSchemaValidator as se}from"@modelcontextprotocol/server/validators/ajv";var ce=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);function b(e,t){return Object.hasOwn(e,t)}const le=(e,t)=>b(e,t),x=e=>{let t=[];for(let n in e)le(e,n)&&t.push(n);return t},S=e=>{let t=[];for(let n in e)if(le(e,n)){let r=Reflect.get(e,n);t.push([n,r])}return t},ue=e=>{let t=[];for(let n in e)if(le(e,n)){let r=Reflect.get(e,n);t.push(r)}return t},C=e=>{let t={};for(let[n,r]of e)Object.defineProperty(t,n,{configurable:!0,enumerable:!0,value:r,writable:!0});return t},w=e=>typeof e==`object`&&!!e&&!Array.isArray(e),de=(e,t)=>e===t?0:e<t?-1:1,fe=(e,t)=>{let n=e.length,r=t.length,i=Array.from({length:n+1},()=>Array.from({length:r+1}).fill(0));for(let e=0;e<=n;e++){let t=i[e];t!=null&&(t[0]=e)}for(let e=0;e<=r;e++){let t=i[0];t!=null&&(t[e]=e)}for(let a=1;a<=n;a++)for(let n=1;n<=r;n++){let r=i[a-1],o=i[a];if(o==null||r==null)continue;let s=e[a-1]===t[n-1]?0:1;o[n]=Math.min((r[n]??0)+1,(o[n-1]??0)+1,(r[n-1]??0)+s)}return i[n]?.[r]??0},pe={lang:void 0,message:void 0,abortEarly:void 0,abortPipeEarly:void 0};/* @__NO_SIDE_EFFECTS__ */
|
|
3
|
+
function me(e){return e?{lang:e?.lang??void 0,message:e?.message,abortEarly:e?.abortEarly??void 0,abortPipeEarly:e?.abortPipeEarly??void 0}:pe}/* @__NO_SIDE_EFFECTS__ */
|
|
4
|
+
function he(e){let t=typeof e;return t===`string`?`"${e}"`:t===`number`||t===`bigint`||t===`boolean`?`${e}`:t===`object`||t===`function`?(e&&Object.getPrototypeOf(e)?.constructor?.name)??`null`:t}function T(e,t,n,r,i){let a=i&&`input`in i?i.input:n.value,o=i?.expected??e.expects??null,s=i?.received??/* @__PURE__ */ he(a),c={kind:e.kind,type:e.type,input:a,expected:o,received:s,message:`Invalid ${t}: ${o?`Expected ${o} but r`:`R`}eceived ${s}`,requirement:e.requirement,path:i?.path,issues:i?.issues,lang:r.lang,abortEarly:r.abortEarly,abortPipeEarly:r.abortPipeEarly},l=e.kind===`schema`,u=i?.message??e.message??(e.reference,c.lang,void 0)??(l?(c.lang,void 0):null)??r.message??(c.lang,void 0);u!==void 0&&(c.message=typeof u==`function`?u(c):u),l&&(n.typed=!1),n.issues?n.issues.push(c):n.issues=[c]}/* @__NO_SIDE_EFFECTS__ */
|
|
5
|
+
function ge(e,t){return e===t||Number.isNaN(e)&&Number.isNaN(t)}/* @__NO_SIDE_EFFECTS__ */
|
|
6
|
+
function _e(e,t){return Object.prototype.hasOwnProperty.call(e,t)&&t!==`__proto__`&&t!==`prototype`&&t!==`constructor`}/* @__NO_SIDE_EFFECTS__ */
|
|
7
|
+
function ve(e,t){let n=[...new Set(e)];return n.length>1?`(${n.join(` ${t} `)})`:n[0]??`never`}function E(e){return e[`~standard`]={version:1,vendor:`valibot`,validate:t=>e[`~run`]({value:t},/* @__PURE__ */ me())},e}const ye=/^\d{4}-(?:0[1-9]|1[0-2])-(?:[12]\d|0[1-9]|3[01])[T ](?:0\d|1\d|2[0-3])(?::[0-5]\d){2}(?:\.\d{1,9})?(?:Z| ?[+-](?:0\d|1\d|2[0-3])(?::?[0-5]\d)?)$/u;/* @__NO_SIDE_EFFECTS__ */
|
|
8
|
+
function be(e,t){return{kind:`validation`,type:`check`,reference:be,async:!1,expects:null,requirement:e,message:t,"~run"(e,t){return e.typed&&!this.requirement(e.value)&&T(this,`input`,e,t),e}}}/* @__NO_SIDE_EFFECTS__ */
|
|
9
|
+
function xe(e,t){let n=/* @__PURE__ */ he(e);return{kind:`validation`,type:`includes`,reference:xe,async:!1,expects:n,requirement:e,message:t,"~run"(e,t){return e.typed&&!e.value.includes(this.requirement)&&T(this,`content`,e,t,{received:`!${n}`}),e}}}/* @__NO_SIDE_EFFECTS__ */
|
|
10
|
+
function Se(e){return{kind:`validation`,type:`iso_timestamp`,reference:Se,async:!1,expects:null,requirement:ye,message:e,"~run"(e,t){return e.typed&&!this.requirement.test(e.value)&&T(this,`timestamp`,e,t),e}}}/* @__NO_SIDE_EFFECTS__ */
|
|
11
|
+
function Ce(e){return{kind:`validation`,type:`non_empty`,reference:Ce,async:!1,expects:`!0`,message:e,"~run"(e,t){return e.typed&&e.value.length===0&&T(this,`length`,e,t,{received:`0`}),e}}}/* @__NO_SIDE_EFFECTS__ */
|
|
12
|
+
function D(e,t){return{kind:`validation`,type:`regex`,reference:D,async:!1,expects:`${e}`,requirement:e,message:t,"~run"(e,t){return e.typed&&!this.requirement.test(e.value)&&T(this,`format`,e,t),e}}}/* @__NO_SIDE_EFFECTS__ */
|
|
13
|
+
function we(e){return{kind:`validation`,type:`url`,reference:we,async:!1,expects:null,requirement(e){try{return URL.canParse?URL.canParse(e):(new URL(e),!0)}catch{return!1}},message:e,"~run"(e,t){return e.typed&&!this.requirement(e.value)&&T(this,`URL`,e,t),e}}}/* @__NO_SIDE_EFFECTS__ */
|
|
14
|
+
function Te(e,t,n){return typeof e.fallback==`function`?e.fallback(t,n):e.fallback}/* @__NO_SIDE_EFFECTS__ */
|
|
15
|
+
function Ee(e,t,n){return typeof e.default==`function`?e.default(t,n):e.default}/* @__NO_SIDE_EFFECTS__ */
|
|
16
|
+
function De(e,t){return E({kind:`schema`,type:`array`,reference:De,expects:`Array`,async:!1,item:e,message:t,"~run"(e,t){let n=e.value;if(Array.isArray(n)){e.typed=!0,e.value=[];for(let r=0;r<n.length;r++){let i=n[r],a=this.item[`~run`]({value:i},t);if(a.issues){let o={type:`array`,origin:`value`,input:n,key:r,value:i};for(let t of a.issues)t.path?t.path.unshift(o):t.path=[o],e.issues?.push(t);if(e.issues||=a.issues,t.abortEarly){e.typed=!1;break}}a.typed||(e.typed=!1),e.value.push(a.value)}}else T(this,`type`,e,t);return e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
17
|
+
function Oe(e,t){return E({kind:`schema`,type:`literal`,reference:Oe,expects:/* @__PURE__ */ he(e),async:!1,literal:e,message:t,"~run"(e,t){return/* @__PURE__ */ ge(e.value,this.literal)?e.typed=!0:T(this,`type`,e,t),e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
18
|
+
function ke(e){return E({kind:`schema`,type:`number`,reference:ke,expects:`number`,async:!1,message:e,"~run"(e,t){return typeof e.value==`number`&&!isNaN(e.value)?e.typed=!0:T(this,`type`,e,t),e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
19
|
+
function O(e,t){return E({kind:`schema`,type:`object`,reference:O,expects:`Object`,async:!1,entries:e,message:t,"~run"(e,t){let n=e.value;if(n&&typeof n==`object`){e.typed=!0,e.value={};for(let r in this.entries){let i=this.entries[r];if(r in n||(i.type===`exact_optional`||i.type===`optional`||i.type===`nullish`)&&i.default!==void 0){let a=r in n?n[r]:/* @__PURE__ */ Ee(i),o=i[`~run`]({value:a},t);if(o.issues){let i={type:`object`,origin:`value`,input:n,key:r,value:a};for(let t of o.issues)t.path?t.path.unshift(i):t.path=[i],e.issues?.push(t);if(e.issues||=o.issues,t.abortEarly){e.typed=!1;break}}o.typed||(e.typed=!1),e.value[r]=o.value}else if(i.fallback!==void 0)e.value[r]=/* @__PURE__ */ Te(i);else if(i.type!==`exact_optional`&&i.type!==`optional`&&i.type!==`nullish`&&(T(this,`key`,e,t,{input:void 0,expected:`"${r}"`,path:[{type:`object`,origin:`key`,input:n,key:r,value:n[r]}]}),t.abortEarly))break}}else T(this,`type`,e,t);return e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
20
|
+
function Ae(e,t,n){return E({kind:`schema`,type:`record`,reference:Ae,expects:`Object`,async:!1,key:e,value:t,message:n,"~run"(e,t){let n=e.value;if(n&&typeof n==`object`){e.typed=!0,e.value={};for(let r in n)if(/* @__PURE__ */ _e(n,r)){let i=n[r],a=this.key[`~run`]({value:r},t);if(a.issues){let o={type:`object`,origin:`key`,input:n,key:r,value:i};for(let t of a.issues)t.path=[o],e.issues?.push(t);if(e.issues||=a.issues,t.abortEarly){e.typed=!1;break}}let o=this.value[`~run`]({value:i},t);if(o.issues){let a={type:`object`,origin:`value`,input:n,key:r,value:i};for(let t of o.issues)t.path?t.path.unshift(a):t.path=[a],e.issues?.push(t);if(e.issues||=o.issues,t.abortEarly){e.typed=!1;break}}(!a.typed||!o.typed)&&(e.typed=!1),a.typed&&(e.value[a.value]=o.value)}}else T(this,`type`,e,t);return e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
21
|
+
function je(e,t){return E({kind:`schema`,type:`strict_object`,reference:je,expects:`Object`,async:!1,entries:e,message:t,"~run"(e,t){let n=e.value;if(n&&typeof n==`object`){e.typed=!0,e.value={};for(let r in this.entries){let i=this.entries[r];if(r in n||(i.type===`exact_optional`||i.type===`optional`||i.type===`nullish`)&&i.default!==void 0){let a=r in n?n[r]:/* @__PURE__ */ Ee(i),o=i[`~run`]({value:a},t);if(o.issues){let i={type:`object`,origin:`value`,input:n,key:r,value:a};for(let t of o.issues)t.path?t.path.unshift(i):t.path=[i],e.issues?.push(t);if(e.issues||=o.issues,t.abortEarly){e.typed=!1;break}}o.typed||(e.typed=!1),e.value[r]=o.value}else if(i.fallback!==void 0)e.value[r]=/* @__PURE__ */ Te(i);else if(i.type!==`exact_optional`&&i.type!==`optional`&&i.type!==`nullish`&&(T(this,`key`,e,t,{input:void 0,expected:`"${r}"`,path:[{type:`object`,origin:`key`,input:n,key:r,value:n[r]}]}),t.abortEarly))break}if(!e.issues||!t.abortEarly){for(let r in n)if(!Object.prototype.hasOwnProperty.call(this.entries,r)){T(this,`key`,e,t,{input:r,expected:`never`,path:[{type:`object`,origin:`key`,input:n,key:r,value:n[r]}]});break}}}else T(this,`type`,e,t);return e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
22
|
+
function k(e){return E({kind:`schema`,type:`string`,reference:k,expects:`string`,async:!1,message:e,"~run"(e,t){return typeof e.value==`string`?e.typed=!0:T(this,`type`,e,t),e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
23
|
+
function Me(e){let t;if(e)for(let n of e)if(t)for(let e of n.issues)t.push(e);else t=n.issues;return t}/* @__NO_SIDE_EFFECTS__ */
|
|
24
|
+
function Ne(e,t){return E({kind:`schema`,type:`union`,reference:Ne,expects:/* @__PURE__ */ ve(e.map(e=>e.expects),`|`),async:!1,options:e,message:t,"~run"(e,t){let n,r,i;for(let a of this.options){let o=a[`~run`]({value:e.value},t);if(o.typed){if(o.issues)r?r.push(o):r=[o];else{n=o;break}}else i?i.push(o):i=[o]}if(n)return n;if(r){if(r.length===1)return r[0];T(this,`type`,e,t,{issues:/* @__PURE__ */ Me(r)}),e.typed=!0}else if(i?.length===1)return i[0];else T(this,`type`,e,t,{issues:/* @__PURE__ */ Me(i)});return e}})}/* @__NO_SIDE_EFFECTS__ */
|
|
25
|
+
function A(...e){return E({...e[0],pipe:e,"~run"(t,n){for(let r of e)if(r.kind!==`metadata`){if(t.issues&&(r.kind===`schema`||r.kind===`transformation`)){t.typed=!1;break}(!t.issues||!n.abortEarly&&!n.abortPipeEarly)&&(t=r[`~run`](t,n))}return t}})}/* @__NO_SIDE_EFFECTS__ */
|
|
26
|
+
function j(e,t,n){let r=e[`~run`]({value:t},/* @__PURE__ */ me(n));return{typed:r.typed,success:!r.issues,output:r.value,issues:r.issues}}const Pe=`0.0.0`,Fe=`https://public-api.nexus.flyle.io`,Ie=/^flyle_ac_[0-9A-Za-z]{43}$/,Le=/^flyle_ut_[0-9A-Za-z]{43}$/,Re=/^flyle_rt_[0-9A-Za-z]{43}$/,ze=/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/,Be=/^[a-z0-9](-?[a-z0-9])*$/,M=`get_input_schema`,Ve=`tenantName`;var He=class extends Error{name=`ManifestLoadError`},Ue=class extends Error{name=`ManifestBuildError`},N=class extends Error{name=`ConfigError`},We=class extends Error{name=`GuideArticlesLoadError`},P=class extends Error{name=`ApiError`;info;constructor(e){super(`${e.status} ${e.code??`http_error`}: ${e.message}`),this.info=e}},F=class extends Error{name=`TransportError`;kind;status;constructor(e,t,n=null){super(t),this.kind=e,this.status=n}},I=class extends Error{name=`ResultFileError`;kind;constructor(e,t){super(t),this.kind=e}},L=class extends Error{name=`InvalidArgumentsError`},R=class extends Error{name=`WorkspaceBindingError`;kind;constructor(e,t){super(t),this.kind=e}};const Ge=e=>{let t=`npx @flyle/ai-cx-mcp@latest login --tenant ${e.tenantName}`;return e.baseUrl.href===new URL(`https://public-api.nexus.flyle.io`).href||!e.baseUrlVerified?t:`${t} --api-base-url ${e.baseUrl.href}`},Ke=e=>`ログインが必要です(ログインの期限切れや切断のほか、テナント設定で外部ツールの接続が許可されなくなった場合もこの状態になります)。作業ディレクトリで \`${Ge(e)}\` を実行してください。ログインできない場合は、テナントの管理者に外部ツールの接続が許可されているか確認してください`;var z=class extends Error{name=`AuthError`;kind;constructor(e,t){super(t),this.kind=e}},qe=class extends Error{name=`InvalidGrantError`},B=class extends Error{name=`CliError`};const V=()=>{},Je=`.flyle-ai-cx-mcp`,Ye=/* @__PURE__ */ new Set([`node_modules`,`.git`,Je]),Xe=/* @__PURE__ */ O({tenantName:/* @__PURE__ */ k(),apiBaseUrl:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ we())}),Ze=e=>v.join(e,Je),Qe=e=>v.join(Ze(e),`workspace.json`),H=e=>e instanceof Error&&b(e,`code`)?e.code:null,$e=async e=>{let t;try{t=await p(Qe(e),`utf8`)}catch(e){if(H(e)===`ENOENT`)return null;throw e}let n;try{n=JSON.parse(t)}catch{n=null}let r=/* @__PURE__ */ j(Xe,n);if(!r.success)throw new R(`corrupted`,`${Qe(e)} の内容が正しくありません。MCP サーバーはこのファイルを上書きしません。中身を確かめ、心当たりが無ければ ${Je} ごと削除してから login し直してください。`);return r.output},et=async e=>{try{return await $e(e)}catch(t){if(t instanceof R)throw t;let n=H(t);throw new R(`unreadable`,`${Ze(e)} を確認できません(${typeof n==`string`?n:`unknown`})。他のテナントの作業ディレクトリと入れ子になっていないかを確かめるため、このディレクトリを読めない間は起動しません。${Ze(e)} の権限を見直すか、心当たりが無ければ削除してください。`)}},tt=e=>`このディレクトリでまだ一度もログインに成功していない(打ち間違えた)場合は、${Ze(e)} を削除してから login し直してください(保存した結果の downloads も消えます)。`,nt=(e,t,n)=>new R(`tenant_mismatch`,`${e} はテナント「${t}」専用の作業ディレクトリなので、テナント「${n}」には使えません。テナントごとに別のディレクトリを作り、そこで Claude Code のセッションを始めてください。`+tt(e)),rt=(e,t,n)=>new R(`environment_mismatch`,`${e} は環境 ${new URL(t).host} 専用の作業ディレクトリなので、環境 ${new URL(n).host} には使えません。環境ごとに別のディレクトリを作ってください。`+tt(e)),it=(e,t,n)=>{if(t.tenantName!==n.tenantName)throw nt(e,t.tenantName,n.tenantName);if(t.apiBaseUrl!==n.apiBaseUrl)throw rt(e,t.apiBaseUrl,n.apiBaseUrl)},at=(e,t,n)=>new R(`nested_workspace`,`${e} の中に、別の接続先(テナント「${n}」)の作業ディレクトリ ${t} があります。別のテナントの作業ディレクトリを含む場所は作業ディレクトリにできません。重ならない別のディレクトリを作り、そこでセッションを始めてください。`),ot=e=>{let t=[],n=v.dirname(e);for(;n!==v.dirname(n);)t.push(n),n=v.dirname(n);return t.push(n),t},st=(e,t)=>a(`sha256`).update(`flyle-ai-cx-mcp/workspace-id/v2\0${e.username}\0${t}`).digest(`base64url`).slice(0,32),ct=(e,t)=>a(`sha256`).update(`${e.hostname}\0${e.username}\0${t}`).digest(`base64url`).slice(0,32),lt=(e,t)=>({root:t,workspaceId:st(e,t),legacyWorkspaceId:ct(e,t)}),ut=(e,t)=>{let n={version:1,tenantName:e.tenantName,apiBaseUrl:e.apiBaseUrl,boundAt:t.toISOString()};return`${JSON.stringify(n,null,2)}\n`},dt=e=>new R(`corrupted`,`${e} がシンボリックリンク、またはディレクトリではありません。作業ディレクトリの外へテナントのデータを書き出さないよう、MCP サーバーはこれを使いません。心当たりが無ければ ${e} を削除してから login し直してください。`),ft=async e=>{let t=Ze(e);await d(t,{mode:448}).catch(e=>{if(H(e)!==`EEXIST`)throw e});let n=await u(t);if(n.isSymbolicLink()||!n.isDirectory())throw dt(t);return t},pt=async e=>{let t=v.join(e,`.gitignore`);if((await u(t).catch(e=>{if(H(e)===`ENOENT`)return null;throw e}))?.isFile()===!0&&await p(t,`utf8`)===`*
|
|
27
|
+
`)return;let n=`${t}.${o(8).toString(`hex`)}.tmp`;try{let e=await f(n,`wx`);try{await e.writeFile(`*
|
|
28
|
+
`)}finally{await e.close()}await g(n,t)}catch(e){throw await _(n,{force:!0}).catch(V),e}},mt=async(e,t,n)=>{let r=await ft(e);await pt(r);try{await ee(Qe(e),ut(t,n),{flag:`wx`});return}catch(e){if(H(e)!==`EEXIST`)throw e}let i=await $e(e);if(i==null)throw nt(e,`(unknown)`,t.tenantName);it(e,i,t)},ht=e=>new R(`shared_directory`,`${e} はさまざまな作業で共有される場所なので、1 つのテナント専用にできません。このテナント用のディレクトリ(例: ~/flyle-ai-cx/<テナント名>)を作り、そこでセッションを始めてください。`),gt=async e=>{let t=await h(e.cwd),n=await h(e.homeDir).catch(()=>e.homeDir),r=[t,...ot(t)];return{cwd:t,home:n,bindings:await Promise.all(r.map(async e=>({dir:e,binding:e===t?await $e(e):await et(e)})))}},_t=(e,t)=>e===t||e===v.parse(e).root,vt=e=>{let t=e.bindings.find(e=>e.binding!=null),n=t?.dir??e.cwd;if(_t(n,e.home))throw ht(n);return{root:n,binding:t?.binding??null}},yt=(e,t,n)=>{let r=e.bindings.findIndex(e=>e.dir===t);for(let{dir:t,binding:i}of e.bindings.slice(r+1))i!=null&&it(t,i,n)},bt=e=>new R(`nested_workspace`,`${e} の中のディレクトリが多すぎて、別のテナントの作業ディレクトリが入っていないかを確かめきれません。このテナント専用の空のディレクトリ(例: ~/flyle-ai-cx/<テナント名>)を作り、そこでセッションを始めてください。`),xt=async e=>{try{return await m(e,{withFileTypes:!0})}catch(e){let t=H(e);if(t===`EACCES`||t===`EPERM`||t===`ENOENT`)return[];throw e}},St=async(e,t)=>{let n=[e],r=0,i=0;for(;n.length>0;){let a=await Promise.all(n.map(async e=>({dir:e,entries:await xt(e)}))),o=await Promise.all(a.filter(({dir:t,entries:n})=>t!==e&&n.some(e=>e.name===`.flyle-ai-cx-mcp`)).map(async({dir:e})=>({dir:e,binding:await et(e)})));for(let{dir:n,binding:r}of o)if(r!=null&&(r.tenantName!==t.tenantName||r.apiBaseUrl!==t.apiBaseUrl))throw at(e,n,r.tenantName);if(i>=6)return;if(n=a.flatMap(({dir:e,entries:t})=>t.filter(e=>e.isDirectory()&&!Ye.has(e.name)).map(t=>v.join(e,t.name))),r+=n.length,r>5e3)throw bt(e);i+=1}},Ct=async(e,t)=>{let n=await gt(e),{root:r}=vt(n);return yt(n,r,t),await St(r,t),await mt(r,t,e.now()),{...t,...lt(e,r)}},wt=async e=>vt(await gt(e)).binding,Tt=async e=>lt(e,vt(await gt(e)).root),Et=async e=>{let t=await gt(e),{root:n,binding:r}=vt(t);return r==null?null:(yt(t,n,r),{...r,...lt(e,n)})},Dt=async(e,t)=>{await mt(e.root,e,t)},Ot={allowInsecureHttp:`FLYLE_AI_CX_MCP_ALLOW_INSECURE_HTTP`,noBrowser:`FLYLE_AI_CX_MCP_NO_BROWSER`},kt=/* @__PURE__ */ new Set([`localhost`,`127.0.0.1`,`[::1]`]),At=e=>{let t=e.length;for(;t>0&&e[t-1]===`/`;)--t;return e.slice(0,t)},jt=e=>kt.has(e),Mt=(e,t,n)=>{let r;try{r=new URL(e)}catch{throw new N(`${n} が URL として正しくありません。`)}if(r.search!==``||r.hash!==``||r.username!==``||r.password!==``)throw new N(`${n} にクエリ(?)・フラグメント(#)・認証情報を含めないでください。`);let i=r.protocol===`http:`&&t&&jt(r.hostname);if(r.protocol!==`https:`&&!i)throw new N(`${n} は https の URL を指定してください(http はローカル開発で ${Ot.allowInsecureHttp}=1 を付けたときの localhost だけ使えます)。`);let a=At(r.pathname);return new URL(`${r.origin}${a}`)},Nt=e=>e===`1`||e===`true`,Pt=e=>e.length>=2&&e.length<=32&&Be.test(e),Ft=(e,t)=>{if(!Pt(e))throw new N(`${t} がテナント名として正しくありません。英小文字・数字・ハイフンで 2〜32 文字のテナント名を指定してください。`);return e},It=e=>Nt(e[Ot.allowInsecureHttp]),Lt=e=>Nt(e[Ot.noBrowser]),U=e=>e.host,Rt=(e,t,n)=>{let r=It(e);return{baseUrl:Mt(n.apiBaseUrl,r,`作業ディレクトリの接続先`),tenantName:Ft(n.tenantName,`作業ディレクトリのテナント`),outputDir:v.resolve(t,Je,`downloads`),allowInsecureHttp:r}},zt=`flyle-ai-cx-mcp`,Bt=`credentials`,Vt=()=>o(8).toString(`hex`),Ht=/* @__PURE__ */ je({version:/* @__PURE__ */ Oe(1),apiBaseUrl:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ we()),tenantName:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ be(Pt)),loginConnectionId:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(ze)),accessToken:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(Le)),accessTokenExpiresAt:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ Se()),refreshToken:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(Re)),refreshTokenExpiresAt:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ Se())}),Ut=({platform:e,env:t,homeDir:n})=>{let r=t.XDG_CONFIG_HOME;if(r!=null&&v.isAbsolute(r))return v.join(r,zt,Bt);let i=t.APPDATA;return e===`win32`&&i!=null&&v.isAbsolute(i)?v.join(i,zt,Bt):v.join(n,`.config`,zt,Bt)},Wt=(e,t)=>v.join(e,`${t}.json`),W=e=>e instanceof Error&&b(e,`code`)?e.code:null,Gt=async(e,t)=>{let n=Wt(e,t.workspaceId),r=Wt(e,t.legacyWorkspaceId);try{await l(r,n)}catch(e){let t=W(e);if(t===`ENOENT`||t===`EEXIST`)return n;throw e}return await _(r,{force:!0}),n},Kt=async e=>{let t;try{t=await p(e,`utf8`)}catch(e){if(W(e)===`ENOENT`)return null;throw e}let n;try{n=JSON.parse(t)}catch{n=null}let r=/* @__PURE__ */ j(Ht,n);if(!r.success)throw new z(`login_required`,`保存されたログイン情報(${e})を読めません。`);return r.output},qt=async e=>{await d(e,{recursive:!0,mode:448}),await c(e,448)},Jt=async(e,t)=>{await qt(v.dirname(e));let n={version:1,...t},r=`${e}.${Vt()}.tmp`;try{let t=await f(r,`wx`,384);try{await t.writeFile(`${JSON.stringify(n,null,2)}\n`)}finally{await t.close()}await g(r,e)}catch(e){throw await _(r,{force:!0}).catch(V),e}},Yt=async e=>{await _(e,{force:!0})},Xt=(e,t)=>({staleMs:6e4,acquireTimeoutMs:9e4,retryIntervalMs:100,now:e,sleep:t}),Zt=async e=>{let t;try{t=await f(e,`r`)}catch(e){if(W(e)===`ENOENT`)return null;throw e}try{let[e,n]=await Promise.all([t.readFile(`utf8`),t.stat()]);return{owner:e,mtimeMs:n.mtimeMs}}finally{await t.close()}},Qt=async(e,t)=>{let n=`${e}.${Vt()}.tmp`,r=await f(n,`wx`,384);try{await r.writeFile(t)}finally{await r.close()}try{return await l(n,e),!0}catch(e){if(W(e)===`EEXIST`)return!1;throw e}finally{await _(n,{force:!0})}},$t=async(e,t)=>{let n=`${e}.${Vt()}.aside`;try{await g(e,n)}catch(e){if(W(e)===`ENOENT`)return!1;throw e}return await p(n,`utf8`)===t?(await _(n,{force:!0}),!0):(await l(n,e).catch(e=>{if(W(e)!==`EEXIST`)throw e}),await _(n,{force:!0}),!1)},en=async(e,t,n)=>{let r=`${e}.guard`,i=Vt(),a=t.now()+t.acquireTimeoutMs;for(;!await Qt(r,i);){let n=await Zt(r);if(n!=null){if(t.now()-n.mtimeMs>=t.staleMs)await $t(r,n.owner);else{if(t.now()>=a)throw Error(`ログイン情報のロック(${e})を取得できませんでした。別の MCP プロセスが更新中です。しばらくしてから再実行してください`);await t.sleep(t.retryIntervalMs)}}}try{return await n()}finally{await $t(r,i)}},tn=(e,t,n)=>en(e,n,async()=>(await Zt(e))?.owner===t&&(await _(e,{force:!0}),!0)),nn=(e,t)=>en(e,t,async()=>{let n=await Zt(e);return n==null?!0:t.now()-n.mtimeMs<t.staleMs?!1:(await _(e,{force:!0}),!0)}),rn=async(e,t,n)=>{await qt(v.dirname(e));let r=`${e}.lock`,i=Vt(),a=t.now()+t.acquireTimeoutMs;for(;!await Qt(r,i);)if(!await nn(r,t)){if(t.now()>=a)throw Error(`ログイン情報のロック(${r})を取得できませんでした。別の MCP プロセスが更新中です。しばらくしてから再実行してください`);await t.sleep(t.retryIntervalMs)}try{return await n()}finally{await tn(r,i,t).catch(V)}},an=`application/json`,on=`x-request-id`,sn={headersTimeoutMs:6e4,maxJsonBytes:16777216,maxRetryAfterSeconds:30,downloadIdleTimeoutMs:6e4},cn=(e,t)=>{if(e.origin!==t.origin)throw new F(`request_refused`,`refusing to send credentials outside the configured API origin`)},ln=(e,t)=>{let n=`${At(e.pathname)}${t.path}`,r=new URL(n,e);if(r.pathname!==n)throw new F(`request_refused`,`refusing to send a request whose path was normalized`);for(let[e,n]of t.query)r.searchParams.append(e,n);return cn(r,e),r},un=async(e,t)=>{let n=Number(e.headers.get(`content-length`));if(Number.isFinite(n)&&n>t)throw await e.body?.cancel().catch(V),new F(`response_too_large`,`response exceeds ${t} bytes`,e.status);if(e.body==null)return/* @__PURE__ */ new Uint8Array;let r=e.body.getReader(),i=[],a=0;for(;;){let{done:n,value:o}=await r.read();if(n)break;if(a+=o.byteLength,a>t)throw await r.cancel().catch(V),new F(`response_too_large`,`response exceeds ${t} bytes`,e.status);i.push(o)}let o=new Uint8Array(a),s=0;for(let e of i)o.set(e,s),s+=e.byteLength;return o},dn=e=>new TextDecoder(`utf-8`).decode(e),fn=(e,t)=>(e.headers.get(`content-type`)??``).toLowerCase().startsWith(t),pn=e=>{if(e==null)return null;let t=Number(e);return Number.isInteger(t)&&t>=0?t:null},mn=(e,t)=>{let n=e[t];return typeof n==`string`?n:null},hn=e=>typeof e==`object`&&!!e&&!Array.isArray(e),gn=e=>{let t=e.issues;return Array.isArray(t)?t.filter(e=>hn(e)):null},_n=async(e,t)=>{let n=e.headers.get(on),r=pn(e.headers.get(`retry-after`)),i;try{i=dn(await un(e,t))}catch{i=``}if(fn(e,an))try{let t=JSON.parse(i),a=hn(t)&&hn(t.error)?t.error:null;if(a!=null)return new P({status:e.status,code:mn(a,`code`),message:mn(a,`message`)??e.statusText,detail:mn(a,`detail`),issues:gn(a),requestId:mn(a,`requestId`)??n,retryAfterSeconds:r})}catch{}return new P({status:e.status,code:null,message:i.slice(0,500)||e.statusText||`HTTP error`,detail:null,issues:null,requestId:n,retryAfterSeconds:r})},vn=e=>e instanceof F?e:e instanceof Error&&e.name===`AbortError`?new F(`timeout`,`the API did not respond in time`):new F(`network`,e instanceof Error?e.message:`network failure`),yn=(e,t,n)=>{let r=e.getReader(),i=!1,a=async()=>{i||(i=!0,await r.cancel().catch(V))};return{chunks:async function*(){let e=setTimeout(()=>t.abort(),n);try{for(;;){let{done:a,value:o}=await r.read();if(a){i=!0;return}clearTimeout(e),e=setTimeout(()=>t.abort(),n),yield o}}catch(e){throw i=!0,vn(e)}finally{clearTimeout(e),await a()}}(),cancel:a}},bn=(e,t=sn)=>{let{config:n,auth:r,workspaceId:i,fetch:a,sleep:o,logger:s}=e,c=async(e,r)=>{let o=ln(n.baseUrl,e),s=new Headers({accept:an,"user-agent":`flyle-ai-cx-mcp/${Pe}`,"x-flyle-client-workspace":i});r!=null&&s.set(`authorization`,`Bearer ${r}`);let c;e.hasBody&&(c=JSON.stringify(e.body??{}),s.set(`content-type`,an));let l=new AbortController,u=setTimeout(()=>l.abort(),t.headersTimeoutMs),d;try{d=await a(o,{method:e.method,headers:s,...c==null?{}:{body:c},redirect:`manual`,signal:l.signal})}catch(e){throw clearTimeout(u),vn(e)}if(d.status>=300&&d.status<400)throw clearTimeout(u),await d.body?.cancel().catch(V),new F(`redirect_not_followed`,`redirect responses are not followed`,d.status);if(!d.ok)try{throw await _n(d,t.maxJsonBytes)}finally{clearTimeout(u)}let f=d.headers.get(on);switch(e.responseKind){case`json`:try{if(!fn(d,an))throw await d.body?.cancel().catch(V),new F(`unexpected_content_type`,`expected an application/json response`,d.status);let e=dn(await un(d,t.maxJsonBytes)),n;try{n=JSON.parse(e)}catch{throw new F(`invalid_json`,`the response body is not valid JSON`,d.status)}return{kind:`json`,status:d.status,requestId:f,body:n}}catch(e){throw vn(e)}finally{clearTimeout(u)}case`empty`:return clearTimeout(u),await d.body?.cancel().catch(V),{kind:`empty`,status:d.status,requestId:f};case`file`:if(clearTimeout(u),!fn(d,an)||d.body==null)throw await d.body?.cancel().catch(V),new F(`unexpected_content_type`,`expected an application/json file response`,d.status);return{kind:`file`,status:d.status,requestId:f,...yn(d.body,l,t.downloadIdleTimeoutMs)};default:throw e.responseKind,Error(`unknown response kind ${String(e.responseKind)}`)}},l=async(e,n)=>{let r=e.method===`GET`;try{return await c(e,n)}catch(i){if(!r)throw i;if(i instanceof P&&i.info.status===429&&i.info.retryAfterSeconds!=null&&i.info.retryAfterSeconds<=t.maxRetryAfterSeconds)return s.warn(`rate limited; retrying once`,{path:e.path,retryAfterSeconds:i.info.retryAfterSeconds}),await o(i.info.retryAfterSeconds*1e3),await c(e,n);if(i instanceof F&&i.kind===`network`)return s.warn(`network failure; retrying once`,{path:e.path}),await c(e,n);throw i}};return{request:async e=>{if(r==null)return l(e,null);let t=await r.getAccessToken();try{return await l(e,t)}catch(n){if(!(n instanceof P)||n.info.status!==401)throw n;let i=await r.refreshAfterRejection(t);if(i===t)throw n;return s.warn(`access token rejected; retrying once with a refreshed token`,{path:e.path}),await l(e,i)}}}},xn=`{tenantName}`,Sn={...sn,headersTimeoutMs:2e4},Cn=/* @__PURE__ */ O({authorizationUrlTemplate:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ xe(xn))}),wn=/* @__PURE__ */ O({accessToken:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(Le)),accessTokenExpiresAt:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ Se()),refreshToken:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(Re)),refreshTokenExpiresAt:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ Se()),tenantName:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ be(Pt)),loginConnectionId:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(ze))}),Tn=(e,t,n)=>{let r=/* @__PURE__ */ j(e,t);if(!r.success)throw new F(`invalid_json`,`the login connection response does not match the contract`,n);return r.output},En=async e=>{let t=await e.request({method:`GET`,path:`/v0/login-connections/metadata`,query:[],hasBody:!1,body:null,responseKind:`json`});if(t.kind!==`json`)throw new F(`unexpected_content_type`,`not JSON`);return Tn(Cn,t.body,t.status).authorizationUrlTemplate},Dn=async(e,t)=>{let n;try{n=await e.request({method:`POST`,path:`/v0/login-connections/token`,query:[],hasBody:!0,body:t,responseKind:`json`})}catch(e){throw e instanceof P&&e.info.code===`invalid_grant`?new qe(`the authorization code or refresh token is no longer valid`):e}if(n.kind!==`json`)throw new F(`unexpected_content_type`,`not JSON`);return Tn(wn,n.body,n.status)},On=(e,t,n)=>{if(e.apiBaseUrl===t.href&&e.tenantName===n)return;let r=Ge({tenantName:n,baseUrl:t,baseUrlVerified:e.apiBaseUrl===t.href});throw new z(`credentials_mismatch`,`保存されたログイン(環境 ${U(new URL(e.apiBaseUrl))} / テナント ${e.tenantName})が、この作業ディレクトリの接続先(環境 ${U(t)} / テナント ${n})と一致しません。この作業ディレクトリで \`${r}\` を実行し直してください`)},kn=(e,t)=>({apiBaseUrl:t.href,tenantName:e.tenantName,loginConnectionId:e.loginConnectionId,accessToken:e.accessToken,accessTokenExpiresAt:e.accessTokenExpiresAt,refreshToken:e.refreshToken,refreshTokenExpiresAt:e.refreshTokenExpiresAt}),An=e=>{let{credentialsFile:t,baseUrl:n,tenantName:r,tokenClient:i,now:a}=e,o=null,s=null,c=[],l=!1,u=(...e)=>{c.push(...e),c.splice(0,Math.max(0,c.length-8))},d=()=>Ke({tenantName:r,baseUrl:n,baseUrlVerified:l}),f=()=>new z(`login_required`,d()),p=async()=>{let e;try{e=await Kt(t)}catch(e){throw e instanceof z?new z(`login_required`,`${e.message}${d()}`):e}if(e?.apiBaseUrl===n.href&&(l=!0),e==null||Date.parse(e.refreshTokenExpiresAt)<=a())throw f();return On(e,n,r),e},m=e=>e-a()>6e4,h=async e=>{try{await Jt(t,e)}catch{try{await Jt(t,e)}catch{await Yt(t)}}},g=a=>rn(t,e.lock,async()=>{let e=await p();u(e.accessToken,e.refreshToken);let s=Date.parse(e.accessTokenExpiresAt);if(e.accessToken!==a&&m(s))return o={token:e.accessToken,expiresAt:s},e.accessToken;let c;try{c=await Dn(i,{grant_type:`refresh_token`,refresh_token:e.refreshToken})}catch(e){throw e instanceof qe?(await Yt(t),f()):e}if(u(c.accessToken,c.refreshToken),c.tenantName!==r)throw await Yt(t),new z(`login_required`,`ログインの更新で、設定と違うテナント(${c.tenantName})の応答を受け取ったため、保存したログイン情報を破棄しました。${d()}`);if(c.loginConnectionId!==e.loginConnectionId)throw await Yt(t),new z(`login_required`,`ログインの更新で、保存したログインと違う接続の応答を受け取ったため、保存したログイン情報を破棄しました。${d()}`);return o={token:c.accessToken,expiresAt:Date.parse(c.accessTokenExpiresAt)},await h(kn(c,n)),c.accessToken}),_=e=>(s??=g(e).finally(()=>{s=null}),s);return{getAccessToken:()=>o!=null&&m(o.expiresAt)?Promise.resolve(o.token):_(o?.token??null),refreshAfterRejection:e=>o!=null&&o.token!==e?Promise.resolve(o.token):(o=null,_(e)),assertLoggedIn:async()=>{o??await p()},secrets:()=>c,whenIdle:async()=>{await Promise.allSettled(s==null?[]:[s])}}},jn=(e,t)=>e===`darwin`?[`open`,[t]]:e===`win32`?[`rundll32`,[`url.dll,FileProtocolHandler`,t]]:[`xdg-open`,[t]],Mn=(e,t=process.platform)=>{let[n,r]=jn(t,e),i=te(n,r,{stdio:`ignore`,detached:!0,shell:!1});i.on(`error`,V),i.unref()},Nn=(e,t,n)=>bn({config:{baseUrl:t},auth:null,workspaceId:n,fetch:e.fetch,sleep:e.sleep,logger:e.logger},Sn),Pn=e=>e==null?"作業ディレクトリで `npx @flyle/ai-cx-mcp@latest login --tenant <テナント名>` を実行し直してください":Ke({tenantName:e.tenantName,baseUrl:new URL(e.apiBaseUrl),baseUrlVerified:!1}),Fn=async(e,t,n)=>{let r=await Gt(e.credentialsDir,t),i;try{i=await Kt(r)}catch(e){throw e instanceof z?new z(`login_required`,`${e.message}${Pn(n)}`):e}if(i==null)return null;let a=Mt(i.apiBaseUrl,It(e.env),`${r} の apiBaseUrl`);return{workspace:{...t,...n??{tenantName:i.tenantName,apiBaseUrl:a.href}},file:r,stored:i,baseUrl:a}},In=async e=>{let t=await Et(e.workspaceEnv);return t==null?null:Fn(e,t,t)},Ln=async e=>Fn(e,await Tt(e.workspaceEnv),null),Rn=(e,t)=>{let n=An({credentialsFile:t.file,baseUrl:t.baseUrl,tenantName:t.stored.tenantName,tokenClient:Nn(e,t.baseUrl,t.workspace.workspaceId),now:e.now,lock:e.lock});return{auth:n,client:bn({config:{baseUrl:t.baseUrl},auth:n,workspaceId:t.workspace.workspaceId,fetch:e.fetch,sleep:e.sleep,logger:e.logger})}},zn=(e,t)=>`/v0/tenants/${encodeURIComponent(e)}${t}`,G=e=>e instanceof B||e instanceof z||e instanceof N||e instanceof R?e.message:e instanceof P?`公開 API がエラーを返しました(${String(e.info.status)} ${e.info.code??`http_error`}): ${e.info.message}`:e instanceof F?`公開 API と通信できませんでした(${e.kind}): ${e.message}`:e instanceof Error?e.message:String(e),K=(e,t)=>{let n=e;for(let e of t)e.length!==0&&(n=n.split(e).join(`[redacted]`));return n},Bn=(e,t,n,r)=>{let i={level:e,message:t,...n,time:(/* @__PURE__ */ new Date()).toISOString()};return K(JSON.stringify(i),r)},Vn=(e,t=e=>console.error(e))=>({info:(n,r)=>t(Bn(`info`,n,r,e())),warn:(n,r)=>t(Bn(`warn`,n,r,e())),error:(n,r)=>t(Bn(`error`,n,r,e()))}),Hn=async(e,t)=>{let{client:n}=Rn(e,t);try{return await n.request({method:`DELETE`,path:zn(t.stored.tenantName,`/current-login-connection`),query:[],hasBody:!1,body:null,responseKind:`empty`}),`revoked`}catch(e){if(!(e instanceof z&&e.kind===`login_required`||e instanceof P&&e.info.status===401))throw e;return`unconfirmed`}},Un=async e=>{let t=await Ln(e);if(t==null){e.out(`この作業ディレクトリにはログイン情報がありません。`);return}let n=await Hn(e,t);await rn(t.file,e.lock,()=>Yt(t.file)),e.out(`ログアウトしました(環境 ${U(t.baseUrl)} / テナント ${t.stored.tenantName})。`),n===`unconfirmed`&&e.err(`サーバー側で接続を切断できたか確認できませんでした。接続が残っている場合は、Flyle AI CX の「設定」>「外部ツール接続」から切断してください。`)},Wn=`127.0.0.1`,Gn=`/callback`,Kn=e=>{try{let{values:t}=re({args:[...e],options:{tenant:{type:`string`},"api-base-url":{type:`string`}},strict:!0,allowPositionals:!1});return{tenant:t.tenant??null,apiBaseUrl:t[`api-base-url`]??null}}catch(e){throw new B(`${e instanceof Error?e.message:String(e)}\n使い方: login [--tenant <テナント名>] [--api-base-url <URL>]`)}},qn=async e=>{try{return await Ln(e)}catch{return null}},Jn=async(e,t,n,r)=>{if(t!=null)return Mt(t,r,`--api-base-url`);let i=Mt(Fe,r,`既定の接続先`);if(n==null)return i;let a=Mt(n.apiBaseUrl,r,`作業ディレクトリの接続先`);if(a.href===i.href||(await qn(e))?.baseUrl.href===a.href)return a;throw new B(`この作業ディレクトリは既定以外の接続先(${a.host})に束縛されています。その接続先が正しいことを確かめたうえで \`login --api-base-url <URL>\` で明示してください。心当たりが無ければ、このディレクトリの ${Je} は他人が置いたものかもしれません。`)},Yn=async(e,t,n)=>{let r=new URL(Fe);if(t.href!==r.href&&!(n&&t.protocol===`http:`&&jt(t.hostname))&&(await qn(e))?.baseUrl.href!==t.href&&!await e.confirm(`接続先 ${t.host} は Flyle AI CX の本番の接続先(${r.host})ではありません。ログインすると、この接続先へ認可コードを送ります。Flyle から案内された接続先で間違いなければ y を入力してください [y/N]: `))throw new B(`接続先 ${t.host} へのログインを中止しました。本番以外の接続先へは、対話できる端末で login を実行し、接続先を確かめて y を入力したときだけログインします。`)},Xn=(e,t)=>{if(e!=null)return Ft(e,`--tenant`);if(t!=null)return t.tenantName;throw new B("テナントを決められません。`login --tenant <テナント名>` で指定してください(作業ディレクトリをそのテナント専用にします)。")},Zn=()=>o(32).toString(`base64url`),Qn=e=>a(`sha256`).update(e).digest(`base64url`),$n=(e,t)=>{let n=Buffer.from(e),r=Buffer.from(t);return n.length===r.length&&s(n,r)},er=(e,t,n)=>{let r;try{r=new URL(e.replaceAll(xn,t))}catch{throw new B(`公開 API が返した同意画面の URL が不正です。`)}let i=r.protocol===`http:`&&n&&(jt(r.hostname)||r.hostname.endsWith(`.localhost`));if(r.protocol!==`https:`&&!i)throw new B(`公開 API が返した同意画面の URL が https ではありません。`);return r},tr=/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}\p{Co}]/gu,nr=(e,t)=>{let n=``;for(let r of e){if(n.length+r.length>t)break;n+=r}return n},rr=(e,t)=>{let n=e=>e.replaceAll(tr,``);return nr(`${n(e)} / ${n(v.basename(t))}`,255)},ir=/* @__PURE__ */ Ne([/* @__PURE__ */ O({error:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(/^[a-z_]{1,64}$/)),state:/* @__PURE__ */ k()}),/* @__PURE__ */ O({code:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ D(Ie)),state:/* @__PURE__ */ k()})]),ar={success:`ログインが完了しました。このタブは閉じてかまいません。`,denied:`ログインを中止しました。このタブは閉じてかまいません。`,failure:`ログインを完了できませんでした。このタブを閉じて、ターミナルの表示を確認してください。`,handled:`このログインは処理済みです。このタブは閉じてかまいません。`,unknown:`実行中のログインの応答として確認できませんでした。ログインを続ける場合は、ターミナルに表示された URL から同意画面を開き直してください。`,rejected:`この宛先への要求は受け付けていません。`},or=(e,t,n)=>{e.writeHead(t,{"content-type":`text/html; charset=utf-8`,"cache-control":`no-store`,"content-security-policy":`default-src 'none'`,"referrer-policy":`no-referrer`}),e.end(`<!doctype html><html lang="ja"><meta charset="utf-8"><title>Flyle AI CX</title><p>${ar[n]}</p></html>`)},sr=e=>new Promise((t,n)=>{e.once(`error`,n),e.listen(0,Wn,()=>{let r=e.address();r==null||typeof r==`string`?n(new B(`ログイン用の待受ポートを開けませんでした。`)):t(r.port)})}),cr=async(e,t,n)=>{let r=!1,i=0,a=null,o=Promise.withResolvers(),s=e=>{r=!0,o.reject(new B(e))},c=(e,t,r)=>{i+=1,or(e,400,t),n(r)},l=ne((t,n)=>{if(a==null||t.headers.host!==a){c(n,`rejected`,`ログイン用の待受に、想定外の宛先(Host ヘッダ)の要求が届いたため拒否しました。ログインは待ち続けています。`);return}let i=new URL(t.url??`/`,`http://${a}`);if(t.method!==`GET`||i.pathname!==Gn){n.writeHead(404).end();return}if(r){or(n,410,`handled`);return}let l=i.searchParams.get(`state`);if(l==null||!$n(l,e)){c(n,`unknown`,`このログインのものではない応答(state が一致しない、または無い)を受け取ったため無視しました。ブラウザで同意を続けてください。`);return}let u=/* @__PURE__ */ j(ir,C(i.searchParams));if(!u.success){or(n,400,`failure`),s(`同意画面からの応答の形式が正しくありません(認可コードがない、または形式が違います)。もう一度 login を実行してください。`);return}let d=u.output;if(b(d,`error`)){let e=d.error===`access_denied`;or(n,200,e?`denied`:`failure`),s(e?`ブラウザでログインが拒否されました。`:`同意画面がエラーを返しました(${d.error})。`);return}r=!0;let f=!1;o.resolve({code:d.code,finish:e=>{f||(f=!0,or(n,e===`success`?200:400,e))}})}),u=await sr(l);a=`${Wn}:${String(u)}`;let d=setTimeout(()=>{if(r)return;let e=i===0?``:`(このログインのものではない要求を ${String(i)} 件受け取り、無視しました)`;s(`${String(Math.round(t/1e3/60))} 分以内にブラウザでの同意が完了しませんでした${e}。もう一度 login を実行してください。`)},t);return{port:u,received:o.promise,close:()=>new Promise(e=>{clearTimeout(d),l.closeAllConnections(),l.close(()=>e())})}},lr=`その接続は最長 30 日間有効なまま残る可能性があります。管理画面の「設定」>「外部ツール接続」から切断してください。`,ur=async(e,t)=>{if(t!=null)try{await Hn(e,t)}catch(n){e.err(`以前のログイン(接続 ID ${t.stored.loginConnectionId})をサーバーで切断できませんでした(${G(n)})。${lr}`)}},dr=async e=>{try{return await In(e)}catch(t){if(!(t instanceof z&&t.kind===`login_required`)&&!(t instanceof N))throw t;return e.err(`以前のログイン情報を読めなかったため、新しいログインで上書きします(${G(t)})。以前の接続はサーバーで切断できていません。${lr}`),null}},fr=async(e,t,n,r)=>{let i=Wt(e.credentialsDir,t.workspaceId);await rn(i,e.lock,()=>Jt(i,kn(r,n)))},pr=e=>({getAccessToken:()=>Promise.resolve(e),refreshAfterRejection:()=>Promise.resolve(e),assertLoggedIn:()=>Promise.resolve(),secrets:()=>[e]}),mr=async(e,t,n,r)=>{let i=bn({config:{baseUrl:t},auth:pr(r.accessToken),workspaceId:n.workspaceId,fetch:e.fetch,sleep:e.sleep,logger:e.logger});try{return await i.request({method:`DELETE`,path:zn(r.tenantName,`/current-login-connection`),query:[],hasBody:!1,body:null,responseKind:`empty`}),!0}catch{return!1}},hr=async e=>{let t=Kn(e.argv),n=It(e.env),r=await wt(e.workspaceEnv),i=await Jn(e,t.apiBaseUrl,r,n),a=Xn(t.tenant,r);await Yn(e,i,n);let o=await Ct(e.workspaceEnv,{tenantName:a,apiBaseUrl:i.href}),s=await dr(e),c=Nn(e,i,o.workspaceId),l=er(await En(c),a,n),u=Zn(),d=Zn(),f=[u,d],p=await cr(d,e.callbackTimeoutMs,e.err),m=null;try{let t=`http://${Wn}:${String(p.port)}${Gn}`;l.searchParams.set(`tenant_name`,a),l.searchParams.set(`code_challenge`,Qn(u)),l.searchParams.set(`code_challenge_method`,`S256`),l.searchParams.set(`redirect_uri`,t),l.searchParams.set(`state`,d),l.searchParams.set(`connection_name`,rr(e.workspaceEnv.hostname,o.root)),e.err(`環境 ${U(i)} のテナント「${a}」にログインします。ブラウザで同意画面を開きます。\n開かない場合は、次の URL をブラウザで開いてください:\n${l.href}`),e.openBrowser(l.href),m=await p.received,f.push(m.code);let n;try{n=await Dn(c,{grant_type:`authorization_code`,code:m.code,code_verifier:u,redirect_uri:t})}catch(e){throw e instanceof qe?new B(`認可コードを交換できませんでした。もう一度 login を実行してください。`):e}if(f.push(n.accessToken,n.refreshToken),n.tenantName!==a){let t=await mr(e,i,o,n);throw new B(`ブラウザで同意したテナント(${n.tenantName})が、ログインしようとしたテナント(${a})と違います。ログイン情報は保存していません。`+(t?`そのテナントに作られた接続は切断しました。`:`テナント ${n.tenantName} の管理画面の「設定」>「外部ツール接続」から、作られた接続を切断してください。`))}try{await Dt(o,new Date(e.now())),await ur(e,s),await fr(e,o,i,n)}catch(t){let r=await mr(e,i,o,n);throw new B(`ログイン情報を保存できませんでした(${G(t)})。`+(r?`作った接続は切断しました。原因を取り除いてから、もう一度 login を実行してください。`:`作った接続を切断できませんでした。${lr}`))}m.finish(`success`),e.out(`ログインしました(環境 ${U(i)} / テナント ${a} / 作業ディレクトリ ${o.root})。`)}catch(e){throw m?.finish(`failure`),new B(K(G(e),f))}finally{await p.close()}},gr=/* @__PURE__ */ O({currentUser:/* @__PURE__ */ O({name:/* @__PURE__ */ k(),email:/* @__PURE__ */ k(),roles:/* @__PURE__ */ De(/* @__PURE__ */ O({roleName:/* @__PURE__ */ k()})),tenantName:/* @__PURE__ */ k(),currentLoginConnection:/* @__PURE__ */ O({name:/* @__PURE__ */ k(),expiresAt:/* @__PURE__ */ A(/* @__PURE__ */ k(),/* @__PURE__ */ Se())})})}),_r=async e=>{let t=await Et(e.workspaceEnv);return t==null?"ログインしていません。作業ディレクトリで `npx @flyle/ai-cx-mcp@latest login --tenant <テナント名>` を実行してください":`ログインしていません。作業ディレクトリで \`${Ge({tenantName:t.tenantName,baseUrl:new URL(t.apiBaseUrl),baseUrlVerified:!1})}\` を実行してください`},vr=async e=>{let t=await In(e);if(t==null)throw new B(await _r(e));e.out(`環境: ${U(t.baseUrl)}`),e.out(`テナント: ${t.stored.tenantName}`);let{client:n}=Rn(e,t),r;try{r=await n.request({method:`GET`,path:zn(t.stored.tenantName,`/current-user`),query:[],hasBody:!1,body:null,responseKind:`json`})}catch(e){throw e instanceof z&&e.kind===`login_required`?new B(e.message):e}let i=/* @__PURE__ */ j(gr,r.kind===`json`?r.body:null);if(!i.success)throw new F(`invalid_json`,`the current user response does not match the contract`);let a=i.output.currentUser;if(a.tenantName!==t.stored.tenantName){let e=Ge({tenantName:t.workspace.tenantName,baseUrl:new URL(t.workspace.apiBaseUrl),baseUrlVerified:t.baseUrl.href===t.workspace.apiBaseUrl});throw new z(`credentials_mismatch`,`ログイン中のテナント(${a.tenantName})が、この作業ディレクトリのテナント(${t.stored.tenantName})と一致しません。この作業ディレクトリで \`${e}\` を実行し直してください`)}e.out(`ユーザー: ${a.name} <${a.email}>`),e.out(`ロール: ${a.roles.map(e=>e.roleName).join(`, `)||`(なし)`}`),e.out(`接続名: ${a.currentLoginConnection.name}`),e.out(`ログインの有効期限: ${a.currentLoginConnection.expiresAt}(使うたびに延長。ログインから最長 90 日)`)},yr=(e,t)=>{let n;try{n=ie(e)}catch{throw t(`${e.pathname} cannot be read`)}try{return JSON.parse((e.pathname.endsWith(`.br`)?ae(n):n).toString(`utf8`))}catch{throw t(`${e.pathname} is not valid JSON or brotli`)}},br=e=>Array.isArray(e),xr=`#/$defs/`,Sr=/* @__PURE__ */ new Set([`oneOf`,`anyOf`,`allOf`,`prefixItems`]),Cr=/* @__PURE__ */ new Set([`items`,`additionalProperties`,`propertyNames`,`not`]),wr=e=>Array.isArray(e)?e.map(e=>wr(e)):w(e)?C(S(e).flatMap(([e,t])=>{if(e!==`$comment`||typeof t!=`string`)return[[e,wr(t)]];if(!t.startsWith(`Additional constraints are validated by the server`))return[[e,t]];let n=t.slice(50);return n.startsWith(`: `)?[[e,n.slice(2)]]:[]})):e,Tr=(e,t)=>w(e)&&x(e).length===1&&Array.isArray(e[t]),Er=e=>Array.isArray(e)?e.map(e=>Er(e)):w(e)?C(S(e).map(([e,t])=>{let n=Er(t);return e!==`anyOf`&&e!==`oneOf`||!Array.isArray(n)?[e,n]:[e,n.flatMap(t=>{let n=Tr(t,e)?t[e]:null;return br(n)?n:[t]})]})):e,Dr=(e,t)=>{let n=e.properties;if(!w(n))return null;let r=n[t];return w(r)&&x(r).length===1&&b(r,`const`)?r:null},Or=(e,t)=>Dr(e,t)?.const,kr=e=>{let t=e.properties;return w(t)?x(t).filter(t=>Dr(e,t)!=null):[]},Ar=(e,t)=>{let n=w(e.properties)?e.properties:{};return`${t}${JSON.stringify({...e,properties:{...n,[t]:`\0`}})}`},jr=e=>{let t=/* @__PURE__ */ new Map;for(let[n,r]of e.entries())if(w(r))for(let e of kr(r)){let i=Ar(r,e),a=t.get(i);a==null?t.set(i,[n]):a.push(n)}let n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Set,i=[...t].toSorted(([,e],[,t])=>t.length-e.length);for(let[t,a]of i){let i=a.filter(e=>!r.has(e)),[o]=i;if(o==null||i.length<2)continue;let s=t.slice(0,t.indexOf(`\0`)),c=e[o];if(!w(c)||!w(c.properties))continue;let l=i.map(t=>{let n=e[t];return w(n)?Or(n,s):void 0});for(let e of i)r.add(e);n.set(o,{...c,properties:{...c.properties,[s]:{enum:l}}})}return e.flatMap((e,t)=>n.has(t)?[n.get(t)]:r.has(t)?[]:[e])},Mr=e=>Array.isArray(e)?e.map(e=>Mr(e)):w(e)?C(S(e).map(([e,t])=>{let n=Mr(t);return(e===`anyOf`||e===`oneOf`)&&Array.isArray(n)?[e,jr(n)]:[e,n]})):e,q=(e,t)=>C(S(e).map(([e,n])=>(e===`properties`||e===`$defs`)&&w(n)?[e,C(S(n).map(([e,n])=>[e,w(n)?t(n):n]))]:Sr.has(e)&&Array.isArray(n)?[e,n.map(e=>w(e)?t(e):e)]:Cr.has(e)&&w(n)?[e,t(n)]:[e,n])),Nr=(e,t,n)=>{let r=/* @__PURE__ */ new Map,i=e=>{let t=JSON.stringify(e);return t.length>=n&&r.set(t,(r.get(t)??0)+1),q(e,i)};q(e,i);for(let e of ue(t))w(e)&&q(e,i);return r},Pr=(e,t,n)=>{let r=null,i=0;for(let[a,o]of e){let e=o*(a.length-t)-a.length-n;o>1&&e>i&&(r=a,i=e)}return r},Fr=(e,t)=>{let n=e;for(let e=1;;e+=1){let r=w(n.$defs)?n.$defs:{},i=`shared${String(e)}`;for(;b(r,i);)i=`_${i}`;let a=`${xr}${i}`,{$defs:o,...s}=n,c=Pr(Nr(s,r,t),JSON.stringify({$ref:a}).length,JSON.stringify({[i]:null}).length);if(c==null)return n;let l=e=>JSON.stringify(e)===c?{$ref:a}:q(e,l),u=q(s,l),d=C(S(r).map(([e,t])=>[e,w(t)?q(t,l):t])),f=JSON.parse(c);n={...u,$defs:C([...S(d),[i,f]].toSorted(([e],[t])=>de(e,t)))}}},Ir=e=>{let t=e.lastIndexOf(`__`);return t===-1?``:e.slice(0,t+2)},Lr=e=>{let t=e.$defs;if(!w(t))return e;let n=x(t),[r]=n;if(r==null)return e;let i=Ir(r);for(;i!==``&&!n.every(e=>e.startsWith(i)&&e!==i);)i=Ir(i.slice(0,-2));if(i===``)return e;let a=`${xr}${i}`,o=e=>Array.isArray(e)?e.map(e=>o(e)):w(e)?C(S(e).map(([e,t])=>e===`$ref`&&typeof t==`string`&&t.startsWith(a)?[e,`${xr}${t.slice(a.length)}`]:e===`$defs`&&w(t)?[e,C(S(t).map(([e,t])=>[e.startsWith(i)?e.slice(i.length):e,o(t)]))]:[e,o(t)])):e,s=o(e);return w(s)?s:e},Rr=(e,t)=>{let n=Mr(Er(wr(e)));return Fr(Lr(w(n)?n:e),t)},zr=e=>typeof e==`string`&&e.startsWith(`#/$defs/`)?e.slice(8).replaceAll(`~1`,`/`).replaceAll(`~0`,`~`):null,Br=(e,t)=>{let n=/* @__PURE__ */ new Map,r=e=>{if(Array.isArray(e))for(let t of e)r(t);else if(w(e))for(let[i,a]of S(e)){let e=i===`$ref`?zr(a):null;e==null?r(a):n.has(e)||(n.set(e,t[e]),r(t[e]))}};return r(e),C([...n].toSorted(([e],[t])=>de(e,t)))},Vr=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`],Hr=[`json`,`empty`,`file`],Ur=[`read`,`write`],Wr=[`image/svg+xml`],J=(e,t)=>{throw new Ue(`${e}: ${t}`)},Gr=(e,t)=>w(e)?e:J(t,`expected an object`),Kr=(e,t)=>typeof e==`string`?e:J(t,`expected a string`),qr=/^[a-z0-9]{1,8}$/,Jr=/^\w+$/,Yr=e=>{let[t,...n]=e.split(`/`);return t===``&&n.length>=1&&n.length<=8&&n.every(e=>Jr.test(e))},Xr=(e,t)=>e==null?[]:Array.isArray(e)?e.map((e,n)=>{let r=Gr(e,`${t}[${n}]`),i=Kr(r.pointer,`${t}[${n}].pointer`),a=Kr(r.extension,`${t}[${n}].extension`),o=Wr.find(e=>e===r.mediaType);return o==null?J(`${t}[${n}]`,`unsupported mediaType`):Yr(i)?qr.test(a)?{pointer:i,mediaType:o,extension:a}:J(`${t}[${n}]`,`invalid extension`):J(`${t}[${n}]`,`invalid pointer`)}):J(t,`x-inline-artifacts must be an array`),Zr=new URL(`./manifest.json.br`,import.meta.url),Y=e=>{throw new He(e)},Qr=e=>e===null,$r=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`),ei=e=>typeof e==`string`&&Vr.some(t=>t===e),ti=e=>typeof e==`string`&&Hr.some(t=>t===e),ni=e=>typeof e==`string`&&Ur.some(t=>t===e),ri=(e,t)=>{if(!w(e))return Y(`${t} must be an object`);let{value:n,summary:r,schema:i}=e;return typeof n!=`string`||typeof r!=`string`||!w(i)?Y(`${t} is invalid`):{value:n,summary:r,schema:i}},ii=(e,t)=>{if(!w(e))return Y(`${t} must be an object`);let{path:n,discriminator:r,description:i,variants:a}=e;return typeof n!=`string`||typeof r!=`string`?Y(`${t} is invalid`):!Qr(i)&&typeof i!=`string`?Y(`${t}.description is invalid`):Array.isArray(a)?{path:n,discriminator:r,description:i,variants:a.map((e,n)=>ri(e,`${t}.variants[${n}]`))}:Y(`${t}.variants is invalid`)},ai=(e,t)=>{if(!w(e)||!b(e,`value`))return Y(`${t} is invalid`);let{path:n}=e;return!Qr(n)&&typeof n!=`string`?Y(`${t}.path is invalid`):{path:n,value:e.value}},oi=(e,t)=>{if(Qr(e))return null;if(!w(e))return Y(`${t} is invalid`);let{groups:n,definitions:r,examples:i}=e;return!Array.isArray(n)||n.length===0?Y(`${t}.groups is invalid`):w(r)?Array.isArray(i)?{groups:n.map((e,n)=>ii(e,`${t}.groups[${n}]`)),definitions:r,examples:i.map((e,n)=>ai(e,`${t}.examples[${n}]`))}:Y(`${t}.examples is invalid`):Y(`${t}.definitions is invalid`)},si=(e,t)=>{let n=`operations[${t}]`;if(!w(e))return Y(`${n} must be an object`);let{operationId:r,method:i,pathTemplate:a,summary:o,description:s,effect:c,responseKind:l,queryParams:u,bodyFields:d,wholeBodyField:f,inputSchema:p,fullInputSchema:m,inputDetails:h,inlineArtifacts:g}=e;return typeof r!=`string`||r===``?Y(`${n}.operationId is invalid`):ei(i)?typeof a!=`string`||!a.startsWith(`/`)?Y(`${n}.pathTemplate is invalid`):typeof o==`string`?!Qr(s)&&typeof s!=`string`?Y(`${n}.description is invalid`):ni(c)?ti(l)?$r(u)?!Qr(d)&&!$r(d)?Y(`${n}.bodyFields is invalid`):!Qr(f)&&typeof f!=`string`?Y(`${n}.wholeBodyField is invalid`):d!=null&&f!=null?Y(`${n} declares both bodyFields and wholeBodyField`):w(p)?w(m)?{operationId:r,method:i,pathTemplate:a,summary:o,description:s,effect:c,responseKind:l,queryParams:u,bodyFields:d,wholeBodyField:f,inputSchema:p,fullInputSchema:m,inputDetails:oi(h,`${n}.inputDetails`),inlineArtifacts:Xr(g,`${n}.inlineArtifacts`)}:Y(`${n}.fullInputSchema is invalid`):Y(`${n}.inputSchema is invalid`):Y(`${n}.queryParams is invalid`):Y(`${n}.responseKind is invalid`):Y(`${n}.effect is invalid`):Y(`${n}.summary is invalid`):Y(`${n}.method is invalid`)},ci=e=>{if(!w(e))return Y(`manifest must be an object`);let t=e.source;if(!w(t)||typeof t.title!=`string`||typeof t.version!=`string`)return Y(`manifest.source is invalid`);let n=e.operations;if(!Array.isArray(n))return Y(`manifest.operations must be an array`);let r=n.map((e,t)=>si(e,t));return new Set(r.map(e=>e.operationId)).size===r.length?{source:{title:t.title,version:t.version},operations:r}:Y(`manifest.operations has duplicate operationId`)},li=(e=Zr)=>ci(yr(e,e=>new He(`manifest at ${e}`))),ui=e=>`${e.product}/${e.slug}`,di=e=>({articles:e,articleByReference:new Map(e.map(e=>[ui(e),e])),searchEntries:e.map(e=>({article:e,normalizedTitle:e.title.toLowerCase(),normalizedDescription:e.description.toLowerCase(),normalizedGroup:e.group.toLowerCase(),normalizedBody:e.body.toLowerCase()}))}),fi=(e,t)=>e.articleByReference.get(t)??null,pi=(e,t)=>{for(let n of t){let t=e.normalizedBody.indexOf(n);if(t===-1)continue;let{body:r}=e.article,i=Math.max(0,t-80),a=Math.min(r.length,t+n.length+80),o=i>0?`…`:``,s=a<r.length?`…`:``;return`${o}${r.slice(i,a).replaceAll(/\s+/g,` `).trim()}${s}`}return e.article.description},mi=(e,t,n)=>{let r=[...new Set(t.toLowerCase().split(/\s+/).filter(e=>e.length>0))];if(r.length===0)return[];let i=[];for(let t of e.searchEntries){let e=0,n=0;for(let i of r){let r=0;t.normalizedTitle.includes(i)&&(r+=10),t.normalizedDescription.includes(i)&&(r+=5),t.normalizedGroup.includes(i)&&(r+=3),t.normalizedBody.includes(i)&&(r+=1),r>0&&(e+=1,n+=r)}e>0&&i.push({entry:t,matchedKeywordCount:e,score:n})}return i.sort((e,t)=>t.matchedKeywordCount===e.matchedKeywordCount?t.score-e.score:t.matchedKeywordCount-e.matchedKeywordCount),i.slice(0,n).map(({entry:e})=>({article:ui(e.article),title:e.article.title,group:e.article.group,description:e.article.description,snippet:pi(e,r)}))},hi=(e,t)=>{let n=e.replaceAll(/!\[[^\]]*\]\([^)]*\)/g,``),r=[];for(let e of n.split(/\r?\n/))(e.trim()!==``||r.at(-1)?.trim()!==``)&&r.push(e);return r.join(`
|
|
29
|
+
`).replaceAll(/\]\(([^)\s]+)\)/g,(e,n)=>{try{return`](${new URL(n,t).toString()})`}catch{return e}})},gi=new URL(`./guide-articles.json.br`,import.meta.url),_i=/* @__PURE__ */ je({productLabels:/* @__PURE__ */ Ae(/* @__PURE__ */ k(),/* @__PURE__ */ k()),articles:/* @__PURE__ */ A(/* @__PURE__ */ De(/* @__PURE__ */ je({product:/* @__PURE__ */ k(),slug:/* @__PURE__ */ k(),title:/* @__PURE__ */ k(),description:/* @__PURE__ */ k(),group:/* @__PURE__ */ k(),order:/* @__PURE__ */ ke(),body:/* @__PURE__ */ k(),url:/* @__PURE__ */ k()})),/* @__PURE__ */ Ce())}),vi=(e=gi)=>{let t=/* @__PURE__ */ j(_i,yr(e,e=>new We(`guide articles at ${e}`)));if(!t.success)throw new We(`guide articles at ${e.pathname} has an unexpected shape`);return t.output},yi=(e,t)=>{let n=[],r=null,i=null;for(let a of e)a.product!==r&&(r=a.product,i=null,n.push(`## ${t[a.product]??a.product}`,``)),a.group!==i&&(i=a.group,n.push(`### ${a.group}`)),n.push(`- ${ui(a)}: ${a.title}`);return n.join(`
|
|
30
|
+
`)},X=`get_product_guide`,bi=`search_product_guide`,Z=`read_product_guide_article`,xi=`# Flyle AI CX の全体像
|
|
31
|
+
|
|
32
|
+
Flyle AI CX は、メール・チャット・アンケート・通話などに散らばった顧客の声(VoC)を 1 か所に集め、AI で分類・要約・可視化し、ワークフローで対応を自動化する製品です。利用者は CS・マーケティング・品質管理などの業務担当者で、エンジニアではありません。
|
|
33
|
+
|
|
34
|
+
## 基本となる概念
|
|
35
|
+
|
|
36
|
+
- **組織とテナント**: 組織はサインインの単位、テナントはデータが分離される単位です。この MCP サーバーは起動時に 1 つのテナントへ固定されています。
|
|
37
|
+
- **フォルダとリソース**: テーブル・レポート・ダッシュボード・ワークフロー・フォームなどの「リソース」をフォルダで整理します。
|
|
38
|
+
- **テーブル**: VoC を蓄える表です。列が「フィールド」、行が「レコード」です。フィールドにはデータタイプ(テキスト・リッチテキスト・数値・チェックボックス・日付・日時・時刻・選択肢・ユーザー・リンク・ルックアップ・数式・ファイルなど)があり、値の形式はデータタイプで決まります。名前は変わることがあるので、API ではフィールド ID で指定します。
|
|
39
|
+
- **リンクとルックアップ**: リンクは別テーブルのレコードを参照するフィールド、ルックアップはリンク先のフィールド値を表示する読み取り専用フィールドです。リンクの追加・解除には連携先テーブルの編集権限も要ります。
|
|
40
|
+
- **ビュー**: テーブルの絞り込み・並び替え・表示列を保存したものです。レポートやダッシュボードの集計対象の絞り込みにも使われます。
|
|
41
|
+
- **AI グルーピング**: テキストフィールドの内容を LLM で分類し、結果を選択肢フィールドに書き込みます。AI クレジットを消費します。
|
|
42
|
+
- **レポート**: テーブルのレコードを集計して可視化します(円・折れ線・棒・積み上げ棒・複合グラフ、ピボット、単一の数値、本文の一覧)。集計値(件数・合計・平均など)と分類項目(どのフィールドで分けるか)の組み合わせで作ります。
|
|
43
|
+
- **ダッシュボード**: 複数のレポート・テーブル・テキストブロックを 1 画面に配置して共有します。
|
|
44
|
+
- **ワークフロー**: 「レコード取得・追加・更新・削除」「LLM(要約・分類)」「条件分岐」「繰り返し」「メール通知」「HTTP リクエスト」などのノードをつないだ自動処理です。編集内容は下書きで、公開するとデータの更新を起点に自動実行されます。
|
|
45
|
+
- **ロールとユーザーグループ**: ロールは「どのリソースに何をしてよいか」の権限の束で、ユーザーやユーザーグループに割り当てます。ロールの「絞り込み条件(データフィルタ)」で、操作できるレコードを条件で制限できます。テナントを作った利用者には Owner ロールが付きます。
|
|
46
|
+
- **AI クレジット**: AI 機能(AI グルーピング・ワークフローの AI 処理・データ分析エージェントなど)が消費する利用量です。クレジットが足りないと、それらの機能は実行できません(ai-usage)。
|
|
47
|
+
|
|
48
|
+
## この MCP サーバーでできること・できないこと
|
|
49
|
+
|
|
50
|
+
ツールで行えるのは、テーブル定義の参照、テーブル名・説明とフィールド・選択肢の追加と変更、ビューの参照・作成・変更・削除、レコードの検索・取得・作成・更新・削除と音声ファイルの保存、CSV ファイルからのレコードのインポートと CSV ファイルへのエクスポート、レポート・ダッシュボードの参照・プレビュー・作成・更新、AI グルーピングの参照・作成・更新・削除と分類の実行・中止・グループの作成・並べ替え・移動・統合・削除、ロールの参照・作成・更新・割り当て・削除、ユーザーの参照・招待・名前の変更・削除、ユーザーグループの参照・作成・変更・メンバーの追加と削除・削除、ワークフローの参照・削除と下書きの作成・更新、フォルダの参照・作成・名前の変更・移動・削除です。すべてログインした利用者本人の権限で動きます。
|
|
51
|
+
|
|
52
|
+
次の操作はツールにありません。ツールを組み合わせて代わりにやろうとせず、該当するご利用ガイドの記事を示して画面で操作するよう利用者に案内してください。
|
|
53
|
+
|
|
54
|
+
- テーブルの作成、フィールド・選択肢の削除とフィールドの種類の変更、AI 検索用データ(埋め込み)の有効化、外部サービス連携の設定
|
|
55
|
+
- レポート・ダッシュボードの削除・移動
|
|
56
|
+
- ワークフローの公開・実行(下書きの作成・更新まではできます。公開は利用者が画面で中身を確かめて行います。実行は API キーの公開 API だけで行えます)
|
|
57
|
+
- ロールの絞り込み条件(データフィルタ)の設定、Owner ロールや全操作(*)を許可・拒否するロールの付与
|
|
58
|
+
- フォーム、AI チャット、組織・セキュリティ設定
|
|
59
|
+
|
|
60
|
+
## 作業の進め方
|
|
61
|
+
|
|
62
|
+
1. 依頼の内容に関係するご利用ガイドの記事を、下の一覧や ${bi} で探し、${Z} で読みます。画面での概念・制約・用語を理解してから操作を選んでください。各ツールの説明にも、関係する記事を載せています。
|
|
63
|
+
2. 対象のリソースを一覧・取得系のツールで特定し、現在の状態を確かめます(レコードなら list_tables → get_table でフィールド ID と型を確認。選択肢が多いフィールドは list_select_options)。
|
|
64
|
+
3. 書き込む前に、何をどう変えるか(対象・変更前 → 変更後)を利用者に示して同意を得ます(合意の範囲と確認を省ける場合は、サーバーの指示に従ってください)。レポート・ダッシュボードはプレビュー画像で見た目の同意を得ます。
|
|
65
|
+
4. 書き込んだ後は取得系のツールで結果を確かめ、利用者に報告します。
|
|
66
|
+
|
|
67
|
+
## よくある依頼と使う記事
|
|
68
|
+
|
|
69
|
+
- 問い合わせの傾向を調べたい: filter-and-views(絞り込みの考え方)→ search_records で抽出し、集計はレポートのプレビューで示す
|
|
70
|
+
- 問い合わせを自動で分類したい: ai-grouping → create_ai_grouping → start_ai_grouping_job(またはスケジュール)→ get_ai_grouping_job で完了を待つ → list_ai_grouping_groups でグループを確かめ、統合・移動・削除で整える
|
|
71
|
+
- 集計をグラフにしたい・ダッシュボードにまとめたい: report-create と各グラフの記事、dashboard-create / dashboard-layout → preview_report / preview_dashboard → create_*
|
|
72
|
+
- 権限を設計したい: role-management / role-data-filter / user-groups → list_roles / get_role → 変更案の同意 → update_role / update_role_assignments
|
|
73
|
+
- レコードを直したい: table-edit / link-tables(値の形式)→ get_table → search_records / get_record → update_record`,Si={get_current_user:[`role-management`,`public-api`],list_tables:[`table-create-import`,`table-edit`],get_table:[`table-edit`,`link-tables`],list_select_options:[`table-edit`,`public-api`],update_table:[`table-edit`],list_table_views:[`filter-and-views`,`split-view`,`dashboard-create`],get_table_view:[`filter-and-views`,`split-view`,`timeline-view`],create_table_view:[`filter-and-views`,`split-view`,`timeline-view`],update_table_view:[`filter-and-views`,`split-view`,`timeline-view`],delete_table_view:[`filter-and-views`],create_field:[`table-edit`,`link-tables`],update_field:[`table-edit`],create_select_options:[`table-edit`],update_select_options:[`table-edit`],search_records:[`filter-and-views`,`public-api`],get_record:[`table-record-detail`,`public-api`],create_record:[`table-edit`,`link-tables`,`public-api`],update_record:[`table-edit`,`link-tables`,`bulk-update-fields`],delete_record:[`record-trash-delete`,`public-api`],create_record_audio_upload_url:[`table-create-import`,`public-api`],attach_record_audio:[`table-create-import`,`public-api`],get_record_audio:[`table-record-detail`,`public-api`],create_record_import:[`table-create-import`,`data-overwrite-update`,`public-api`],start_record_import:[`table-create-import`,`data-overwrite-update`,`public-api`],get_record_import:[`import-export-history`,`public-api`],cancel_record_import:[`import-export-history`,`public-api`],start_record_export:[`data-export`,`public-api`],get_record_export:[`import-export-history`,`public-api`],cancel_record_export:[`import-export-history`,`public-api`],list_reports:[`report-create`],get_report:[`report-create`],preview_report:[`report-create`,`chart-bar`,`pivot-table-layout`],create_report:[`report-create`,`chart-bar`,`pivot-table-layout`],update_report:[`report-create`,`chart-bar`,`pivot-table-layout`],list_dashboards:[`dashboard-create`],get_dashboard:[`dashboard-create`],preview_dashboard:[`dashboard-create`,`dashboard-layout`,`dashboard-filter-view`],create_dashboard:[`dashboard-create`,`dashboard-layout`,`dashboard-filter-view`],update_dashboard:[`dashboard-create`,`dashboard-layout`,`dashboard-filter-view`],list_ai_groupings:[`ai-grouping`],get_ai_grouping:[`ai-grouping`],create_ai_grouping:[`ai-grouping`,`ai-usage`],update_ai_grouping:[`ai-grouping`],delete_ai_grouping:[`ai-grouping`],list_ai_grouping_groups:[`ai-grouping`],create_ai_grouping_group:[`ai-grouping`],reorder_ai_grouping_group:[`ai-grouping`],move_ai_grouping_groups:[`ai-grouping`],merge_ai_grouping_groups:[`ai-grouping`],delete_ai_grouping_group:[`ai-grouping`],start_ai_grouping_job:[`ai-grouping`,`ai-usage`],get_ai_grouping_job:[`ai-grouping`],get_latest_ai_grouping_job:[`ai-grouping`],cancel_ai_grouping_job:[`ai-grouping`],list_roles:[`role-management`,`user-groups`],get_role:[`role-management`,`role-data-filter`],create_role:[`role-management`,`role-data-filter`],update_role:[`role-management`,`role-data-filter`],update_role_assignments:[`role-management`,`user-groups`],delete_role:[`role-management`],list_users:[`invite-users`,`role-management`],get_user:[`invite-users`,`role-management`],invite_user:[`invite-users`,`role-management`,`user-groups`],update_user:[`invite-users`],delete_user:[`invite-users`,`user-bulk-import`],list_user_groups:[`user-groups`,`role-management`],get_user_group:[`user-groups`],create_user_group:[`user-groups`,`role-management`],update_user_group:[`user-groups`],update_user_group_members:[`user-groups`],delete_user_group:[`user-groups`],list_folders:[`folder-create-organize`,`public-api`],get_folder:[`folder-create-organize`,`public-api`],create_folder:[`folder-create-organize`,`resource-management`],update_folder:[`folder-create-organize`,`resource-management`],delete_folder:[`resource-management`,`trash`],list_workflows:[`workflow-basics`,`workflow-overview`],get_workflow:[`workflow-basics`,`workflow-advanced-nodes`],create_workflow:[`workflow-basics`,`workflow-advanced-nodes`,`workflow-overview`],update_workflow:[`workflow-basics`,`workflow-advanced-nodes`,`workflow-overview`],delete_workflow:[`resource-management`,`trash`],get_workflow_execution:[`workflow-run-history`,`public-api`],list_workflow_runs:[`workflow-run-history`,`public-api`],get_workflow_run:[`workflow-run-history`,`public-api`],download_workflow_run_log:[`workflow-run-history`,`public-api`]},Ci={list_tables:{createTool:null,articles:[`table-create-import`,`import-export-history`]},list_workflows:{createTool:`create_workflow`,articles:[`workflow-basics`,`workflow-export-import`]},list_folders:{createTool:null,articles:[`folder-create-organize`]}},wi=e=>e.map(e=>`nexus/${e}`).join(`, `),Ti=e=>{let t=Ci[e];if(t==null)return null;let n=wi(t.articles);return t.createTool==null?`一覧が空なら、ツールでは作成できないので、画面での作成・インポートを案内してください(記事: ${n})。`:`一覧が空なら ${t.createTool} で作成できます。インポートや画面での作成は記事(${n})を案内してください。`},Ei=e=>{let t=Si[e];return t==null?null:`先に読む記事: ${wi(t)}`};let Di=null;const Oi=()=>(Di??=vi(),Di);let ki=null;const Ai=()=>(ki??=di(Oi().articles),ki),ji=()=>{let{articles:e,productLabels:t}=Oi();return{isError:!1,payload:{guide:`${xi}\n\n# ご利用ガイドの記事一覧\n\n記事の説明は ${bi} の結果に、全文は ${Z} にあります。\n\n${yi(e,t)}`}}},Mi=(e,t)=>({isError:!1,payload:{results:mi(Ai(),e,t)}}),Ni=e=>{let t=fi(Ai(),e);return t==null?{isError:!0,payload:{error:{kind:`guide_article_not_found`,message:`記事 "${e}" はありません。${X} の一覧か ${bi} で記事を探し、"nexus/table-edit" の形式で指定してください。`}}}:{isError:!1,payload:{article:ui(t),title:t.title,group:t.group,url:t.url,body:hi(t.body,t.url)}}},Pi=()=>({isError:!0,payload:{error:{kind:`product_guide_required`,message:`製品の考え方を確認する前の操作は実行しません。先に ${X} を呼び、依頼に関係する記事を ${Z} で読んでから、この操作をやり直してください。`}}}),Fi=new se,Ii={},Li={getValidator:e=>Fi.getValidator(Ii)},Ri=`^[0-7][0-9A-HJKMNP-TV-Z]{25}$`,zi=/, (?=data[/ ])/u,Bi=/^must have required property '(.+)'$/u,Vi=`must match pattern "${Ri}"`,Hi=`must be equal to one of the allowed values`,Ui=`must be equal to constant`,Wi=/* @__PURE__ */ new Set([`must match a schema in anyOf`,`must match exactly one schema in oneOf`]),Gi=`must be null`,Ki=/^\d+$/u,qi=[`anyOf`,`oneOf`,`allOf`],Ji=e=>e.split(`/`).slice(1).map(e=>e.replaceAll(`~1`,`/`).replaceAll(`~0`,`~`)),Yi=e=>{let t=e.slice(4),n=t.indexOf(` `),r=Ji(n===-1?t:t.slice(0,n)),i=n===-1?e:t.slice(n+1),a=Bi.exec(i)?.[1];return a==null?{code:i===`must NOT have additional properties`?`unknown_argument`:`invalid_value`,path:r.join(`.`),message:i}:{code:`required`,path:[...r,a].join(`.`),message:i}},Xi=(e,t)=>{let n=/* @__PURE__ */ new Set,r=w(e.$defs)?e.$defs:{},i=(e,t,a)=>{if(!w(e)||a>64)return;let o=e.$ref;typeof o==`string`&&o.startsWith(`#/$defs/`)&&i(r[o.slice(8)],t,a+1);for(let n of qi){let r=e[n];if(Array.isArray(r))for(let e of r)i(e,t,a+1)}let[s,...c]=t;if(s==null){let t=e.enum;if(Array.isArray(t))for(let e of t)n.add(e);b(e,`const`)&&n.add(e.const);return}let l=e.properties;w(l)&&b(l,s)?i(l[s],c,a+1):w(e.additionalProperties)&&i(e.additionalProperties,c,a+1),Ki.test(s)&&i(e.items,c,a+1)};return i(e,t,0),[...n]},Zi=(e,t)=>{let n=e;for(let e of t)if(Array.isArray(n)&&Ki.test(e))n=n[Number(e)];else if(w(n)&&b(n,e))n=n[e];else return;return n},Qi=(e,t)=>{if(typeof t!=`string`||t.length>64)return`must be one of ${e.map(e=>JSON.stringify(e)).join(`, `)}`;let n=e.map(e=>({value:e,distance:typeof e==`string`?fe(t,e):1/0})).toSorted((e,t)=>e.distance-t.distance),[r]=n,i=r!=null&&r.distance<=3?` (did you mean ${JSON.stringify(r.value)}?)`:``;return`must be one of ${n.map(e=>JSON.stringify(e.value)).join(`, `)}${i}`},$i=(e,t,n)=>{if(n.message!==Hi&&n.message!==Ui)return n;let r=n.path===``?[]:n.path.split(`.`),i=Xi(e,r);return i.length===0?n:{...n,message:Qi(i,Zi(t,r))}},ea=e=>{let t=/* @__PURE__ */ new Set,n=e.filter(e=>{let n=`${e.code}\u0000${e.path}\u0000${e.message}`;return!t.has(n)&&(t.add(n),!0)}),r=n.filter(e=>!Wi.has(e.message)&&e.message!==Gi).map(e=>e.path),i=new Set(r),a=new Set(r.flatMap(e=>{let t=e.split(`.`);return t.map((e,n)=>t.slice(0,n+1).join(`.`))}));return n.filter(e=>Wi.has(e.message)?!(e.path===``?r.length>0:a.has(e.path)):e.message!==Gi||!i.has(e.path))},ta=e=>e.slice(0,Math.max(e.lastIndexOf(`.`),0)),na=e=>{let t=/* @__PURE__ */ new Map;for(let n of e)(n.message===Hi||n.message===Ui)&&t.set(n.path,(t.get(n.path)??0)+1);let n=new Set([...t].filter(([e,t])=>t>1&&e.includes(`.`)).map(([e])=>e));if(n.size===0)return[...e];let r=new Set(Array.from(n,e=>ta(e)));return e.filter(e=>{if(n.has(e.path))return!0;let t=e.path.split(`.`);return!t.some((e,n)=>r.has(t.slice(0,n+1).join(`.`)))})},ra=(e,t)=>{let n=w(e.properties)?e.properties:{};return x(t).filter(e=>!b(n,e)).map(e=>({code:`unknown_argument`,path:e,message:`is not an argument of this tool`}))},ia=(e,t)=>{let n=w(e.properties)?e.properties[t]:null;return w(n)&&n.pattern===Ri},aa=(e,t)=>[...t.some(e=>e.message===Vi)||t.some(t=>t.code===`required`&&ia(e,t.path))?[`IDs are 26-character codes such as 01J9Z3K8Q2M4N6P8R0T2V4X6Y8, not names. Get table IDs with list_tables, field IDs with get_table, and other IDs from the list_* or get_* tool of that resource.`]:[],...t.some(e=>e.code===`unknown_argument`)?[`Remove the arguments that the input schema of this tool does not list.`]:[]],oa=(e,t)=>{let n=Fi.getValidator(t);return r=>{let i=n(r);if(i.valid)return null;let a=i.errorMessage.split(zi).map(e=>Yi(e)),o=ea([...na(a.filter(e=>e.code!==`unknown_argument`||e.path!==``)).map(e=>$i(t,r,e)),...a.some(e=>e.code===`unknown_argument`&&e.path===``)?ra(t,r):[]]);return{isError:!0,payload:{error:{kind:`invalid_arguments`,code:`invalid_request`,message:`The arguments do not match the input schema of ${e}; nothing was sent to the API.`,issues:o.slice(0,20),hints:aa(t,o)}}}}};var sa=class extends Error{constructor(e,t){super(e,t),this.name=`UnsafeSvgError`}},ca=class extends sa{bytes;maxBytes;constructor(e,t){super(`svg is ${e.bytes} bytes, exceeding the ${e.maxBytes} byte limit`,t),this.name=`SvgTooLargeError`,this.bytes=e.bytes,this.maxBytes=e.maxBytes}},la=/* @__PURE__ */ ce((e=>{
|
|
74
|
+
/**
|
|
75
|
+
* Character classes and associated utilities for the 5th edition of XML 1.0.
|
|
76
|
+
*
|
|
77
|
+
* @author Louis-Dominique Dubeau
|
|
78
|
+
* @license MIT
|
|
79
|
+
* @copyright Louis-Dominique Dubeau
|
|
80
|
+
*/
|
|
81
|
+
Object.defineProperty(e,"__esModule",{value:!0}),e.CHAR=`
|
|
82
|
+
\r --�𐀀-`,e.S=` \r
|
|
83
|
+
`,e.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,e.NAME_CHAR=`-`+e.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,e.CHAR_RE=RegExp(`^[`+e.CHAR+`]$`,`u`),e.S_RE=RegExp(`^[`+e.S+`]+$`,`u`),e.NAME_START_CHAR_RE=RegExp(`^[`+e.NAME_START_CHAR+`]$`,`u`),e.NAME_CHAR_RE=RegExp(`^[`+e.NAME_CHAR+`]$`,`u`),e.NAME_RE=RegExp(`^[`+e.NAME_START_CHAR+`][`+e.NAME_CHAR+`]*$`,`u`),e.NMTOKEN_RE=RegExp(`^[`+e.NAME_CHAR+`]+$`,`u`);var t=9,n=10,r=13,i=32;e.S_LIST=[i,n,r,t];function a(e){return e>=i&&e<=55295||e===n||e===r||e===t||e>=57344&&e<=65533||e>=65536&&e<=1114111}e.isChar=a;function o(e){return e===i||e===n||e===r||e===t}e.isS=o;function s(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}e.isNameStartChar=s;function c(e){return s(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}e.isNameChar=c})),ua=/* @__PURE__ */ ce((e=>{
|
|
84
|
+
/**
|
|
85
|
+
* Character classes and associated utilities for the 2nd edition of XML 1.1.
|
|
86
|
+
*
|
|
87
|
+
* @author Louis-Dominique Dubeau
|
|
88
|
+
* @license MIT
|
|
89
|
+
* @copyright Louis-Dominique Dubeau
|
|
90
|
+
*/
|
|
91
|
+
Object.defineProperty(e,"__esModule",{value:!0}),e.CHAR=`--�𐀀-`,e.RESTRICTED_CHAR=`-\b\v\f---`,e.S=` \r
|
|
92
|
+
`,e.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,e.NAME_CHAR=`-`+e.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,e.CHAR_RE=RegExp(`^[`+e.CHAR+`]$`,`u`),e.RESTRICTED_CHAR_RE=RegExp(`^[`+e.RESTRICTED_CHAR+`]$`,`u`),e.S_RE=RegExp(`^[`+e.S+`]+$`,`u`),e.NAME_START_CHAR_RE=RegExp(`^[`+e.NAME_START_CHAR+`]$`,`u`),e.NAME_CHAR_RE=RegExp(`^[`+e.NAME_CHAR+`]$`,`u`),e.NAME_RE=RegExp(`^[`+e.NAME_START_CHAR+`][`+e.NAME_CHAR+`]*$`,`u`),e.NMTOKEN_RE=RegExp(`^[`+e.NAME_CHAR+`]+$`,`u`);var t=9,n=10,r=13,i=32;e.S_LIST=[i,n,r,t];function a(e){return e>=1&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111}e.isChar=a;function o(e){return e>=1&&e<=8||e===11||e===12||e>=14&&e<=31||e>=127&&e<=132||e>=134&&e<=159}e.isRestrictedChar=o;function s(e){return e===9||e===10||e===13||e>31&&e<127||e===133||e>159&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111}e.isCharAndNotRestricted=s;function c(e){return e===i||e===n||e===r||e===t}e.isS=c;function l(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}e.isNameStartChar=l;function u(e){return l(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}e.isNameChar=u})),da=/* @__PURE__ */ ce((e=>{
|
|
93
|
+
/**
|
|
94
|
+
* Character class utilities for XML NS 1.0 edition 3.
|
|
95
|
+
*
|
|
96
|
+
* @author Louis-Dominique Dubeau
|
|
97
|
+
* @license MIT
|
|
98
|
+
* @copyright Louis-Dominique Dubeau
|
|
99
|
+
*/
|
|
100
|
+
Object.defineProperty(e,"__esModule",{value:!0}),e.NC_NAME_START_CHAR=`A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ--⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,e.NC_NAME_CHAR=`-`+e.NC_NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,e.NC_NAME_START_CHAR_RE=RegExp(`^[`+e.NC_NAME_START_CHAR+`]$`,`u`),e.NC_NAME_CHAR_RE=RegExp(`^[`+e.NC_NAME_CHAR+`]$`,`u`),e.NC_NAME_RE=RegExp(`^[`+e.NC_NAME_START_CHAR+`][`+e.NC_NAME_CHAR+`]*$`,`u`);function t(e){return e>=65&&e<=90||e===95||e>=97&&e<=122||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8204&&e<=8205||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}e.isNCNameStartChar=t;function n(e){return t(e)||e===45||e===46||e>=48&&e<=57||e===183||e>=768&&e<=879||e>=8255&&e<=8256}e.isNCNameChar=n})),fa=(/* @__PURE__ */ ce((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.SaxesParser=e.EVENTS=void 0;let t=la(),n=ua(),r=da();var i=t.isS,a=t.isChar,o=t.isNameStartChar,s=t.isNameChar,c=t.S_LIST,l=t.NAME_RE,u=n.isChar,d=r.isNCNameStartChar,f=r.isNCNameChar,p=r.NC_NAME_RE;let m=`http://www.w3.org/XML/1998/namespace`,h=`http://www.w3.org/2000/xmlns/`,g={__proto__:null,xml:m,xmlns:h},_={__proto__:null,amp:`&`,gt:`>`,lt:`<`,quot:`"`,apos:`'`},ee=8232,v=e=>e===34||e===39,te=[34,39],ne=[...te,91,62],re=[...te,60,93],ie=[61,63,...c],ae=[...c,62,38,60];function oe(e,t,n){switch(t){case`xml`:n!==m&&e.fail(`xml prefix must be bound to ${m}.`);break;case`xmlns`:n!==h&&e.fail(`xmlns prefix must be bound to ${h}.`)}switch(n){case h:e.fail(t===``?`the default namespace may not be set to ${n}.`:`may not assign a prefix (even "xmlns") to the URI \
|
|
101
|
+
${h}.`);break;case m:switch(t){case`xml`:break;case``:e.fail(`the default namespace may not be set to ${n}.`);break;default:e.fail(`may not assign the xml namespace to another prefix.`)}}}function y(e,t){for(let n of Object.keys(t))oe(e,n,t[n])}let se=e=>p.test(e),ce=e=>l.test(e);e.EVENTS=[`xmldecl`,`text`,`processinginstruction`,`doctype`,`comment`,`opentagstart`,`attribute`,`opentag`,`closetag`,`cdata`,`error`,`end`,`ready`];let b={xmldecl:`xmldeclHandler`,text:`textHandler`,processinginstruction:`piHandler`,doctype:`doctypeHandler`,comment:`commentHandler`,opentagstart:`openTagStartHandler`,attribute:`attributeHandler`,opentag:`openTagHandler`,closetag:`closeTagHandler`,cdata:`cdataHandler`,error:`errorHandler`,end:`endHandler`,ready:`readyHandler`};e.SaxesParser=class{constructor(e){this.opt=e??{},this.fragmentOpt=!!this.opt.fragment;let t=this.xmlnsOpt=!!this.opt.xmlns;if(this.trackPosition=this.opt.position!==!1,this.fileName=this.opt.fileName,t){this.nameStartCheck=d,this.nameCheck=f,this.isName=se,this.processAttribs=this.processAttribsNS,this.pushAttrib=this.pushAttribNS,this.ns=Object.assign({__proto__:null},g);let e=this.opt.additionalNamespaces;e!=null&&(y(this,e),Object.assign(this.ns,e))}else this.nameStartCheck=o,this.nameCheck=s,this.isName=ce,this.processAttribs=this.processAttribsPlain,this.pushAttrib=this.pushAttribPlain;this.stateTable=[this.sBegin,this.sBeginWhitespace,this.sDoctype,this.sDoctypeQuote,this.sDTD,this.sDTDQuoted,this.sDTDOpenWaka,this.sDTDOpenWakaBang,this.sDTDComment,this.sDTDCommentEnding,this.sDTDCommentEnded,this.sDTDPI,this.sDTDPIEnding,this.sText,this.sEntity,this.sOpenWaka,this.sOpenWakaBang,this.sComment,this.sCommentEnding,this.sCommentEnded,this.sCData,this.sCDataEnding,this.sCDataEnding2,this.sPIFirstChar,this.sPIRest,this.sPIBody,this.sPIEnding,this.sXMLDeclNameStart,this.sXMLDeclName,this.sXMLDeclEq,this.sXMLDeclValueStart,this.sXMLDeclValue,this.sXMLDeclSeparator,this.sXMLDeclEnding,this.sOpenTag,this.sOpenTagSlash,this.sAttrib,this.sAttribName,this.sAttribNameSawWhite,this.sAttribValue,this.sAttribValueQuoted,this.sAttribValueClosed,this.sAttribValueUnquoted,this.sCloseTag,this.sCloseTagSawWhite],this._init()}get closed(){return this._closed}_init(){var e;this.openWakaBang=``,this.text=``,this.name=``,this.piTarget=``,this.entity=``,this.q=null,this.tags=[],this.tag=null,this.topNS=null,this.chunk=``,this.chunkPosition=0,this.i=0,this.prevI=0,this.carriedFromPrevious=void 0,this.forbiddenState=0,this.attribList=[];let{fragmentOpt:t}=this;this.state=t?13:0,this.reportedTextBeforeRoot=this.reportedTextAfterRoot=this.closedRoot=this.sawRoot=t,this.xmlDeclPossible=!t,this.xmlDeclExpects=[`version`],this.entityReturnState=void 0;let{defaultXMLVersion:n}=this.opt;if(n===void 0){if(this.opt.forceXMLVersion===!0)throw Error(`forceXMLVersion set but defaultXMLVersion is not set`);n=`1.0`}this.setXMLVersion(n),this.positionAtNewLine=0,this.doctype=!1,this._closed=!1,this.xmlDecl={version:void 0,encoding:void 0,standalone:void 0},this.line=1,this.column=0,this.ENTITIES=Object.create(_),(e=this.readyHandler)==null||e.call(this)}get position(){return this.chunkPosition+this.i}get columnIndex(){return this.position-this.positionAtNewLine}on(e,t){this[b[e]]=t}off(e){this[b[e]]=void 0}makeError(e){let t=this.fileName??``;return this.trackPosition&&(t.length>0&&(t+=`:`),t+=`${this.line}:${this.column}`),t.length>0&&(t+=`: `),Error(t+e)}fail(e){let t=this.makeError(e),n=this.errorHandler;if(n===void 0)throw t;return n(t),this}write(e){if(this.closed)return this.fail(`cannot write after close; assign an onready handler.`);let t=!1;e===null?(t=!0,e=``):typeof e==`object`&&(e=e.toString()),this.carriedFromPrevious!==void 0&&(e=`${this.carriedFromPrevious}${e}`,this.carriedFromPrevious=void 0);let n=e.length,r=e.charCodeAt(n-1);!t&&(r===13||r>=55296&&r<=56319)&&(this.carriedFromPrevious=e[n-1],n--,e=e.slice(0,n));let{stateTable:i}=this;for(this.chunk=e,this.i=0;this.i<n;)i[this.state].call(this);return this.chunkPosition+=n,t?this.end():this}close(){return this.write(null)}getCode10(){let{chunk:e,i:t}=this;if(this.prevI=t,this.i=t+1,t>=e.length)return-1;let n=e.charCodeAt(t);if(this.column++,n<55296){if(n>=32||n===9)return n;switch(n){case 10:return this.line++,this.column=0,this.positionAtNewLine=this.position,10;case 13:return e.charCodeAt(t+1)===10&&(this.i=t+2),this.line++,this.column=0,this.positionAtNewLine=this.position,-2;default:return this.fail(`disallowed character.`),n}}if(n>56319)return n>=57344&&n<=65533||this.fail(`disallowed character.`),n;let r=65536+(n-55296)*1024+(e.charCodeAt(t+1)-56320);return this.i=t+2,r>1114111&&this.fail(`disallowed character.`),r}getCode11(){let{chunk:e,i:t}=this;if(this.prevI=t,this.i=t+1,t>=e.length)return-1;let n=e.charCodeAt(t);if(this.column++,n<55296){if(n>31&&n<127||n>159&&n!==ee||n===9)return n;switch(n){case 10:return this.line++,this.column=0,this.positionAtNewLine=this.position,10;case 13:{let n=e.charCodeAt(t+1);(n===10||n===133)&&(this.i=t+2)}case 133:case ee:return this.line++,this.column=0,this.positionAtNewLine=this.position,-2;default:return this.fail(`disallowed character.`),n}}if(n>56319)return n>=57344&&n<=65533||this.fail(`disallowed character.`),n;let r=65536+(n-55296)*1024+(e.charCodeAt(t+1)-56320);return this.i=t+2,r>1114111&&this.fail(`disallowed character.`),r}getCodeNorm(){let e=this.getCode();return e===-2?10:e}unget(){this.i=this.prevI,this.column--}captureTo(e){let{i:t}=this,{chunk:n}=this;for(;;){let r=this.getCode(),i=r===-2,a=i?10:r;if(a===-1||e.includes(a))return this.text+=n.slice(t,this.prevI),a;i&&(this.text+=`${n.slice(t,this.prevI)}\n`,t=this.i)}}captureToChar(e){let{i:t}=this,{chunk:n}=this;for(;;){let r=this.getCode();switch(r){case-2:this.text+=`${n.slice(t,this.prevI)}\n`,t=this.i,r=10;break;case-1:return this.text+=n.slice(t),!1}if(r===e)return this.text+=n.slice(t,this.prevI),!0}}captureNameChars(){let{chunk:e,i:t}=this;for(;;){let n=this.getCode();if(n===-1)return this.name+=e.slice(t),-1;if(!s(n))return this.name+=e.slice(t,this.prevI),n===-2?10:n}}skipSpaces(){for(;;){let e=this.getCodeNorm();if(e===-1||!i(e))return e}}setXMLVersion(e){this.currentXMLVersion=e,e===`1.0`?(this.isChar=a,this.getCode=this.getCode10):(this.isChar=u,this.getCode=this.getCode11)}sBegin(){this.chunk.charCodeAt(0)===65279&&(this.i++,this.column++),this.state=1}sBeginWhitespace(){let e=this.i,t=this.skipSpaces();switch(this.prevI!==e&&(this.xmlDeclPossible=!1),t){case 60:if(this.state=15,this.text.length!==0)throw Error(`no-empty text at start`);break;case-1:break;default:this.unget(),this.state=13,this.xmlDeclPossible=!1}}sDoctype(){var e;let t=this.captureTo(ne);switch(t){case 62:(e=this.doctypeHandler)==null||e.call(this,this.text),this.text=``,this.state=13,this.doctype=!0;break;case-1:break;default:this.text+=String.fromCodePoint(t),t===91?this.state=4:v(t)&&(this.state=3,this.q=t)}}sDoctypeQuote(){let e=this.q;this.captureToChar(e)&&(this.text+=String.fromCodePoint(e),this.q=null,this.state=2)}sDTD(){let e=this.captureTo(re);e!==-1&&(this.text+=String.fromCodePoint(e),e===93?this.state=2:e===60?this.state=6:v(e)&&(this.state=5,this.q=e))}sDTDQuoted(){let e=this.q;this.captureToChar(e)&&(this.text+=String.fromCodePoint(e),this.state=4,this.q=null)}sDTDOpenWaka(){let e=this.getCodeNorm();switch(this.text+=String.fromCodePoint(e),e){case 33:this.state=7,this.openWakaBang=``;break;case 63:this.state=11;break;default:this.state=4}}sDTDOpenWakaBang(){let e=String.fromCodePoint(this.getCodeNorm()),t=this.openWakaBang+=e;this.text+=e,t!==`-`&&(this.state=t===`--`?8:4,this.openWakaBang=``)}sDTDComment(){this.captureToChar(45)&&(this.text+=`-`,this.state=9)}sDTDCommentEnding(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),this.state=e===45?10:8}sDTDCommentEnded(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),e===62?this.state=4:(this.fail(`malformed comment.`),this.state=8)}sDTDPI(){this.captureToChar(63)&&(this.text+=`?`,this.state=12)}sDTDPIEnding(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),e===62&&(this.state=4)}sText(){this.tags.length===0?this.handleTextOutsideRoot():this.handleTextInRoot()}sEntity(){let{i:e}=this,{chunk:t}=this;loop:for(;;)switch(this.getCode()){case-2:this.entity+=`${t.slice(e,this.prevI)}\n`,e=this.i;break;case 59:{let{entityReturnState:n}=this,r=this.entity+t.slice(e,this.prevI);this.state=n;let i;r===``?(this.fail(`empty entity name.`),i=`&;`):(i=this.parseEntity(r),this.entity=``),(n!==13||this.textHandler!==void 0)&&(this.text+=i);break loop}case-1:this.entity+=t.slice(e);break loop}}sOpenWaka(){let e=this.getCode();if(o(e))this.state=34,this.unget(),this.xmlDeclPossible=!1;else switch(e){case 47:this.state=43,this.xmlDeclPossible=!1;break;case 33:this.state=16,this.openWakaBang=``,this.xmlDeclPossible=!1;break;case 63:this.state=23;break;default:this.fail(`disallowed character in tag name`),this.state=13,this.xmlDeclPossible=!1}}sOpenWakaBang(){switch(this.openWakaBang+=String.fromCodePoint(this.getCodeNorm()),this.openWakaBang){case`[CDATA[`:!this.sawRoot&&!this.reportedTextBeforeRoot&&(this.fail(`text data outside of root node.`),this.reportedTextBeforeRoot=!0),this.closedRoot&&!this.reportedTextAfterRoot&&(this.fail(`text data outside of root node.`),this.reportedTextAfterRoot=!0),this.state=20,this.openWakaBang=``;break;case`--`:this.state=17,this.openWakaBang=``;break;case`DOCTYPE`:this.state=2,(this.doctype||this.sawRoot)&&this.fail(`inappropriately located doctype declaration.`),this.openWakaBang=``;break;default:this.openWakaBang.length>=7&&this.fail(`incorrect syntax.`)}}sComment(){this.captureToChar(45)&&(this.state=18)}sCommentEnding(){var e;let t=this.getCodeNorm();t===45?(this.state=19,(e=this.commentHandler)==null||e.call(this,this.text),this.text=``):(this.text+=`-${String.fromCodePoint(t)}`,this.state=17)}sCommentEnded(){let e=this.getCodeNorm();e===62?this.state=13:(this.fail(`malformed comment.`),this.text+=`--${String.fromCodePoint(e)}`,this.state=17)}sCData(){this.captureToChar(93)&&(this.state=21)}sCDataEnding(){let e=this.getCodeNorm();e===93?this.state=22:(this.text+=`]${String.fromCodePoint(e)}`,this.state=20)}sCDataEnding2(){var e;let t=this.getCodeNorm();switch(t){case 62:(e=this.cdataHandler)==null||e.call(this,this.text),this.text=``,this.state=13;break;case 93:this.text+=`]`;break;default:this.text+=`]]${String.fromCodePoint(t)}`,this.state=20}}sPIFirstChar(){let e=this.getCodeNorm();this.nameStartCheck(e)?(this.piTarget+=String.fromCodePoint(e),this.state=24):e===63||i(e)?(this.fail(`processing instruction without a target.`),this.state=e===63?26:25):(this.fail(`disallowed character in processing instruction name.`),this.piTarget+=String.fromCodePoint(e),this.state=24)}sPIRest(){let{chunk:e,i:t}=this;for(;;){let n=this.getCodeNorm();if(n===-1){this.piTarget+=e.slice(t);return}if(!this.nameCheck(n)){this.piTarget+=e.slice(t,this.prevI);let r=n===63;r||i(n)?this.piTarget===`xml`?(this.xmlDeclPossible||this.fail(`an XML declaration must be at the start of the document.`),this.state=r?33:27):this.state=r?26:25:(this.fail(`disallowed character in processing instruction name.`),this.piTarget+=String.fromCodePoint(n));break}}}sPIBody(){if(this.text.length===0){let e=this.getCodeNorm();e===63?this.state=26:i(e)||(this.text=String.fromCodePoint(e))}else this.captureToChar(63)&&(this.state=26)}sPIEnding(){var e;let t=this.getCodeNorm();if(t===62){let{piTarget:t}=this;t.toLowerCase()===`xml`&&this.fail(`the XML declaration must appear at the start of the document.`),(e=this.piHandler)==null||e.call(this,{target:t,body:this.text}),this.piTarget=this.text=``,this.state=13}else t===63?this.text+=`?`:(this.text+=`?${String.fromCodePoint(t)}`,this.state=25);this.xmlDeclPossible=!1}sXMLDeclNameStart(){let e=this.skipSpaces();e===63?this.state=33:e!==-1&&(this.state=28,this.name=String.fromCodePoint(e))}sXMLDeclName(){let e=this.captureTo(ie);if(e===63)this.state=33,this.name+=this.text,this.text=``,this.fail(`XML declaration is incomplete.`);else if(i(e)||e===61){if(this.name+=this.text,this.text=``,!this.xmlDeclExpects.includes(this.name))switch(this.name.length){case 0:this.fail(`did not expect any more name/value pairs.`);break;case 1:this.fail(`expected the name ${this.xmlDeclExpects[0]}.`);break;default:this.fail(`expected one of ${this.xmlDeclExpects.join(`, `)}`)}this.state=e===61?30:29}}sXMLDeclEq(){let e=this.getCodeNorm();e===63?(this.state=33,this.fail(`XML declaration is incomplete.`)):i(e)||(e!==61&&this.fail(`value required.`),this.state=30)}sXMLDeclValueStart(){let e=this.getCodeNorm();e===63?(this.state=33,this.fail(`XML declaration is incomplete.`)):i(e)||(v(e)?this.q=e:(this.fail(`value must be quoted.`),this.q=32),this.state=31)}sXMLDeclValue(){let e=this.captureTo([this.q,63]);if(e===63){this.state=33,this.text=``,this.fail(`XML declaration is incomplete.`);return}if(e===-1)return;let t=this.text;switch(this.text=``,this.name){case`version`:{this.xmlDeclExpects=[`encoding`,`standalone`];let e=t;this.xmlDecl.version=e,/^1\.[0-9]+$/.test(e)?this.opt.forceXMLVersion||this.setXMLVersion(e):this.fail(`version number must match /^1\\.[0-9]+$/.`);break}case`encoding`:/^[A-Za-z][A-Za-z0-9._-]*$/.test(t)||this.fail(`encoding value must match /^[A-Za-z0-9][A-Za-z0-9._-]*$/.`),this.xmlDeclExpects=[`standalone`],this.xmlDecl.encoding=t;break;case`standalone`:t!==`yes`&&t!==`no`&&this.fail(`standalone value must match "yes" or "no".`),this.xmlDeclExpects=[],this.xmlDecl.standalone=t}this.name=``,this.state=32}sXMLDeclSeparator(){let e=this.getCodeNorm();e===63?this.state=33:(i(e)||(this.fail(`whitespace required.`),this.unget()),this.state=27)}sXMLDeclEnding(){var e;this.getCodeNorm()===62?(this.piTarget===`xml`?this.name!==`version`&&this.xmlDeclExpects.includes(`version`)&&this.fail(`XML declaration must contain a version.`):this.fail(`processing instructions are not allowed before root.`),(e=this.xmldeclHandler)==null||e.call(this,this.xmlDecl),this.name=``,this.piTarget=this.text=``,this.state=13):this.fail(`The character ? is disallowed anywhere in XML declarations.`),this.xmlDeclPossible=!1}sOpenTag(){var e;let t=this.captureNameChars();if(t===-1)return;let n=this.tag={name:this.name,attributes:Object.create(null)};switch(this.name=``,this.xmlnsOpt&&(this.topNS=n.ns=Object.create(null)),(e=this.openTagStartHandler)==null||e.call(this,n),this.sawRoot=!0,!this.fragmentOpt&&this.closedRoot&&this.fail(`documents may contain only one root.`),t){case 62:this.openTag();break;case 47:this.state=35;break;default:i(t)||this.fail(`disallowed character in tag name.`),this.state=36}}sOpenTagSlash(){this.getCode()===62?this.openSelfClosingTag():(this.fail(`forward-slash in opening tag not followed by >.`),this.state=36)}sAttrib(){let e=this.skipSpaces();e!==-1&&(o(e)?(this.unget(),this.state=37):e===62?this.openTag():e===47?this.state=35:this.fail(`disallowed character in attribute name.`))}sAttribName(){let e=this.captureNameChars();e===61?this.state=39:i(e)?this.state=38:e===62?(this.fail(`attribute without value.`),this.pushAttrib(this.name,this.name),this.name=this.text=``,this.openTag()):e!==-1&&this.fail(`disallowed character in attribute name.`)}sAttribNameSawWhite(){let e=this.skipSpaces();switch(e){case-1:return;case 61:this.state=39;break;default:this.fail(`attribute without value.`),this.text=``,this.name=``,e===62?this.openTag():o(e)?(this.unget(),this.state=37):(this.fail(`disallowed character in attribute name.`),this.state=36)}}sAttribValue(){let e=this.getCodeNorm();v(e)?(this.q=e,this.state=40):i(e)||(this.fail(`unquoted attribute value.`),this.state=42,this.unget())}sAttribValueQuoted(){let{q:e,chunk:t}=this,{i:n}=this;for(;;)switch(this.getCode()){case e:this.pushAttrib(this.name,this.text+t.slice(n,this.prevI)),this.name=this.text=``,this.q=null,this.state=41;return;case 38:this.text+=t.slice(n,this.prevI),this.state=14,this.entityReturnState=40;return;case 10:case-2:case 9:this.text+=`${t.slice(n,this.prevI)} `,n=this.i;break;case 60:this.text+=t.slice(n,this.prevI),this.fail(`disallowed character.`);return;case-1:this.text+=t.slice(n);return}}sAttribValueClosed(){let e=this.getCodeNorm();i(e)?this.state=36:e===62?this.openTag():e===47?this.state=35:o(e)?(this.fail(`no whitespace between attributes.`),this.unget(),this.state=37):this.fail(`disallowed character in attribute name.`)}sAttribValueUnquoted(){let e=this.captureTo(ae);switch(e){case 38:this.state=14,this.entityReturnState=42;break;case 60:this.fail(`disallowed character.`);break;case-1:break;default:this.text.includes(`]]>`)&&this.fail(`the string "]]>" is disallowed in char data.`),this.pushAttrib(this.name,this.text),this.name=this.text=``,e===62?this.openTag():this.state=36}}sCloseTag(){let e=this.captureNameChars();e===62?this.closeTag():i(e)?this.state=44:e!==-1&&this.fail(`disallowed character in closing tag.`)}sCloseTagSawWhite(){switch(this.skipSpaces()){case 62:this.closeTag();break;case-1:break;default:this.fail(`disallowed character in closing tag.`)}}handleTextInRoot(){let{i:e,forbiddenState:t}=this,{chunk:n,textHandler:r}=this;scanLoop:for(;;)switch(this.getCode()){case 60:if(this.state=15,r!==void 0){let{text:t}=this,i=n.slice(e,this.prevI);t.length===0?i.length!==0&&r(i):(r(t+i),this.text=``)}t=0;break scanLoop;case 38:this.state=14,this.entityReturnState=13,r!==void 0&&(this.text+=n.slice(e,this.prevI)),t=0;break scanLoop;case 93:switch(t){case 0:t=1;break;case 1:t=2;break;case 2:break;default:throw Error(`impossible state`)}break;case 62:t===2&&this.fail(`the string "]]>" is disallowed in char data.`),t=0;break;case-2:r!==void 0&&(this.text+=`${n.slice(e,this.prevI)}\n`),e=this.i,t=0;break;case-1:r!==void 0&&(this.text+=n.slice(e));break scanLoop;default:t=0}this.forbiddenState=t}handleTextOutsideRoot(){let{i:e}=this,{chunk:t,textHandler:n}=this,r=!1;outRootLoop:for(;;){let a=this.getCode();switch(a){case 60:if(this.state=15,n!==void 0){let{text:r}=this,i=t.slice(e,this.prevI);r.length===0?i.length!==0&&n(i):(n(r+i),this.text=``)}break outRootLoop;case 38:this.state=14,this.entityReturnState=13,n!==void 0&&(this.text+=t.slice(e,this.prevI)),r=!0;break outRootLoop;case-2:n!==void 0&&(this.text+=`${t.slice(e,this.prevI)}\n`),e=this.i;break;case-1:n!==void 0&&(this.text+=t.slice(e));break outRootLoop;default:i(a)||(r=!0)}}r&&(!this.sawRoot&&!this.reportedTextBeforeRoot&&(this.fail(`text data outside of root node.`),this.reportedTextBeforeRoot=!0),this.closedRoot&&!this.reportedTextAfterRoot&&(this.fail(`text data outside of root node.`),this.reportedTextAfterRoot=!0))}pushAttribNS(e,t){var n;let{prefix:r,local:i}=this.qname(e),a={name:e,prefix:r,local:i,value:t};if(this.attribList.push(a),(n=this.attributeHandler)==null||n.call(this,a),r===`xmlns`){let e=t.trim();this.currentXMLVersion===`1.0`&&e===``&&this.fail(`invalid attempt to undefine prefix in XML 1.0`),this.topNS[i]=e,oe(this,i,e)}else if(e===`xmlns`){let e=t.trim();this.topNS[``]=e,oe(this,``,e)}}pushAttribPlain(e,t){var n;let r={name:e,value:t};this.attribList.push(r),(n=this.attributeHandler)==null||n.call(this,r)}end(){var e,t;this.sawRoot||this.fail(`document must contain a root element.`);let{tags:n}=this;for(;n.length>0;){let e=n.pop();this.fail(`unclosed tag: ${e.name}`)}this.state!==0&&this.state!==13&&this.fail(`unexpected end.`);let{text:r}=this;return r.length!==0&&((e=this.textHandler)==null||e.call(this,r),this.text=``),this._closed=!0,(t=this.endHandler)==null||t.call(this),this._init(),this}resolve(e){var t;let n=this.topNS[e];if(n!==void 0)return n;let{tags:r}=this;for(let t=r.length-1;t>=0;t--)if(n=r[t].ns[e],n!==void 0)return n;return n=this.ns[e],n===void 0?(t=this.opt).resolvePrefix?.call(t,e):n}qname(e){let t=e.indexOf(`:`);if(t===-1)return{prefix:``,local:e};let n=e.slice(t+1),r=e.slice(0,t);return(r===``||n===``||n.includes(`:`))&&this.fail(`malformed name: ${e}.`),{prefix:r,local:n}}processAttribsNS(){let{attribList:e}=this,t=this.tag;{let{prefix:e,local:n}=this.qname(t.name);t.prefix=e,t.local=n;let r=t.uri=this.resolve(e)??``;e!==``&&(e===`xmlns`&&this.fail(`tags may not have "xmlns" as prefix.`),r===``&&(this.fail(`unbound namespace prefix: ${JSON.stringify(e)}.`),t.uri=e))}if(e.length===0)return;let{attributes:n}=t,r=/* @__PURE__ */ new Set;for(let t of e){let{name:e,prefix:i,local:a}=t,o,s;i===``?(o=e===`xmlns`?h:``,s=e):(o=this.resolve(i),o===void 0&&(this.fail(`unbound namespace prefix: ${JSON.stringify(i)}.`),o=i),s=`{${o}}${a}`),r.has(s)&&this.fail(`duplicate attribute: ${s}.`),r.add(s),t.uri=o,n[e]=t}this.attribList=[]}processAttribsPlain(){let{attribList:e}=this,t=this.tag.attributes;for(let{name:n,value:r}of e)t[n]!==void 0&&this.fail(`duplicate attribute: ${n}.`),t[n]=r;this.attribList=[]}openTag(){var e;this.processAttribs();let{tags:t}=this,n=this.tag;n.isSelfClosing=!1,(e=this.openTagHandler)==null||e.call(this,n),t.push(n),this.state=13,this.name=``}openSelfClosingTag(){var e,t;this.processAttribs();let{tags:n}=this,r=this.tag;r.isSelfClosing=!0,(e=this.openTagHandler)==null||e.call(this,r),(t=this.closeTagHandler)==null||t.call(this,r),(this.tag=n[n.length-1]??null)===null&&(this.closedRoot=!0),this.state=13,this.name=``}closeTag(){let{tags:e,name:t}=this;if(this.state=13,this.name=``,t===``){this.fail(`weird empty close tag.`),this.text+=`</>`;return}let n=this.closeTagHandler,r=e.length;for(;r-->0;){let r=this.tag=e.pop();if(this.topNS=r.ns,n?.(r),r.name===t)break;this.fail(`unexpected close tag.`)}r===0?this.closedRoot=!0:r<0&&(this.fail(`unmatched closing tag: ${t}.`),this.text+=`</${t}>`)}parseEntity(e){if(e[0]!==`#`){let t=this.ENTITIES[e];return t===void 0?(this.fail(this.isName(e)?`undefined entity.`:`disallowed character in entity name.`),`&${e};`):t}let t=NaN;return e[1]===`x`&&/^#x[0-9a-f]+$/i.test(e)?t=parseInt(e.slice(2),16):/^#[0-9]+$/.test(e)&&(t=parseInt(e.slice(1),10)),this.isChar(t)?String.fromCodePoint(t):(this.fail(`malformed character entity.`),`&${e};`)}}})))();const pa=e=>{let t=0;for(let n of e){let e=n.codePointAt(0)??0;t+=e<128?1:e<2048?2:e<65536?3:4}return t},ma=/* @__PURE__ */ new Set([`svg`,`g`,`path`,`rect`,`circle`,`ellipse`,`line`,`polyline`,`polygon`,`text`,`tspan`,`defs`,`clipPath`,`linearGradient`,`radialGradient`,`stop`,`title`,`desc`]),ha=/* @__PURE__ */ new Set(/* @__PURE__ */ `xmlns.xmlns:xlink.version.baseProfile.id.class.x.y.x1.y1.x2.y2.cx.cy.r.rx.ry.fx.fy.dx.dy.width.height.viewBox.preserveAspectRatio.transform.d.points.offset.gradientUnits.gradientTransform.clipPathUnits.fill.fill-opacity.fill-rule.clip-path.clip-rule.stroke.stroke-width.stroke-opacity.stroke-linecap.stroke-linejoin.stroke-miterlimit.stroke-dasharray.stroke-dashoffset.stop-color.stop-opacity.opacity.paint-order.pointer-events.font-family.font-size.font-weight.font-style.text-anchor.dominant-baseline.xml:space.style.ecmeta_ssr_type.ecmeta_series_index.ecmeta_data_index.ecmeta_ssr_component.ecmeta_ssr_component_index`.split(`.`)),ga=/* @__PURE__ */ new Set([`font-size`,`font-family`,`font-weight`,`font-style`,`fill`,`fill-opacity`,`stroke`,`stroke-width`,`stroke-opacity`,`opacity`,`paint-order`,`white-space`]),_a=/url\s*\(([^)]*)\)/gi,va=/^\s*(['"]?)#[\w.:-]+\1\s*$/,ya=/javascript:|vbscript:|data:|expression\s*\(|@import|https?:|\/\//i,ba=/[\\<>]|\/\*/,Q=e=>{throw new sa(e)},xa=(e,t)=>{ba.test(t)&&Q(`forbidden character in attribute ${e}`),ya.test(t)&&Q(`forbidden value in attribute ${e}`);for(let n of t.matchAll(_a))va.test(n[1]??``)||Q(`non-local url() in attribute ${e}`)},Sa=e=>{for(let t of e.split(`;`)){if(t.trim()===``)continue;let e=t.indexOf(`:`),n=(e===-1?t:t.slice(0,e)).trim().toLowerCase();ga.has(n)||Q(`style property ${n} is not allowed`)}},Ca=(e,t,n)=>{ha.has(t)||Q(`attribute ${t} on <${e}> is not allowed`),t===`xmlns`?n!==`http://www.w3.org/2000/svg`&&Q(`unexpected namespace`):t===`xmlns:xlink`?n!==`http://www.w3.org/1999/xlink`&&Q(`unexpected namespace`):(xa(t,n),t===`style`&&Sa(n))},wa=(e,t)=>{let n=pa(e);if(n>t)throw new ca({bytes:n,maxBytes:t});let r=new fa.SaxesParser({xmlns:!1}),i=0,a=!1;r.on(`error`,e=>Q(`malformed svg: ${e.message}`)),r.on(`doctype`,()=>Q(`doctype is not allowed`)),r.on(`xmldecl`,()=>Q(`xml declaration is not allowed`)),r.on(`processinginstruction`,()=>Q(`processing instructions are not allowed`)),r.on(`comment`,()=>Q(`comments are not allowed`)),r.on(`cdata`,()=>Q(`cdata sections are not allowed`)),r.on(`opentag`,e=>{i===0&&((a||e.name!==`svg`)&&Q(`root element must be a single <svg>`),a=!0),i+=1,i>64&&Q(`elements are nested too deeply`),ma.has(e.name)||Q(`element <${e.name}> is not allowed`);for(let[t,n]of S(e.attributes))Ca(e.name,t,n)}),r.on(`closetag`,()=>{--i}),r.write(e).close(),a||Q(`root element must be a single <svg>`)},Ta=(e,t)=>`${t.toISOString().replaceAll(/[:.]/g,`-`)}-${o(3).toString(`hex`)}-${e}`,Ea=e=>new I(`write_failed`,e instanceof Error?e.message:`the result could not be written`),Da=(e,t)=>e instanceof Error&&b(e,`code`)&&e.code===t,Oa=async e=>{for(let t of[v.dirname(e),e]){await d(t,{mode:448}).catch(e=>{if(!Da(e,`EEXIST`))throw e});let e=await u(t);if(e.isSymbolicLink()||!e.isDirectory())throw new I(`unsafe_location`,`${t} is not a real directory (symbolic links are not followed)`)}},ka=async e=>{for(let t of[v.dirname(e),e]){let e=await u(t).catch(e=>{if(Da(e,`ENOENT`))return null;throw e});if(e==null||e.isSymbolicLink()||!e.isDirectory())return!1}return!0},Aa=async e=>{try{await e()}catch(e){throw Ea(e)}},ja=async(e,t)=>{let n=v.join(e.outputDir,Ta(e.fileName,e.now)),r;try{await Oa(e.outputDir),r=await f(n,`wx`,384)}catch(e){throw e instanceof I?e:Ea(e)}try{let e=await t(r);return await Aa(()=>r.close()),{path:n,...e}}catch(e){throw await r.close().catch(V),await _(n,{force:!0}).catch(V),e}},Ma=async(e,t)=>{if(e.byteLength>t.maxBytes)throw new I(`too_large`,`the result exceeds ${t.maxBytes} bytes`);return ja(t,async t=>(await Aa(()=>t.writeFile(e)),{bytes:e.byteLength,sha256Hex:a(`sha256`).update(e).digest(`hex`)}))},Na=(e,t)=>ja(t,async n=>{let r=a(`sha256`),i=0;for await(let a of e){if(i+=a.byteLength,i>t.maxBytes)throw new I(`too_large`,`the result exceeds ${t.maxBytes} bytes`);r.update(a),await Aa(async()=>{await n.write(a)})}return{bytes:i,sha256Hex:r.digest(`hex`)}}),Pa=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z-[0-9a-f]{6}-/,Fa=async(e,t)=>{if(!await ka(e))return 0;let n;try{n=await m(e,{withFileTypes:!0})}catch(e){if(Da(e,`ENOENT`))return 0;throw e}let r=t.now.getTime()-t.maxAgeMs;return(await Promise.all(n.filter(e=>e.isFile()&&Pa.test(e.name)).map(async t=>{let n=v.join(e,t.name),i=await u(n);return!i.isFile()||i.mtimeMs>=r?!1:(await _(n,{force:!0}),!0)}))).filter(Boolean).length},Ia=e=>e.split(`/`).slice(1),La=(e,t,n)=>{if(e===`image/svg+xml`)wa(t,n);else throw new sa(`unknown artifact media type`)},Ra=e=>e instanceof I?e.kind:e instanceof ca?`too_large`:e instanceof sa?`unsafe_content`:`unexpected`,za=async(e,t,n)=>{if(e.isError||t.length===0||!w(e.payload))return e;let r=e.payload.body;if(!w(r))return e;let i=structuredClone(r);for(let e of t){let t=Ia(e.pointer),r=t.pop(),a=i;for(let e of t)a=w(a)&&b(a,e)?a[e]:null;if(r==null||!w(a)||typeof a[r]!=`string`)continue;let o=a;try{let t=K(String(o[r]),n.secrets);La(e.mediaType,t,n.maxBytes);let i=Buffer.from(t,`utf8`);o[r]={file:{...await Ma(i,{outputDir:n.outputDir,fileName:`${n.operationId}.${e.extension}`,maxBytes:n.maxBytes,now:n.now}),mediaType:e.mediaType}}}catch(e){o[r]={error:{kind:`artifact_not_saved`,failure:Ra(e)}}}}return{isError:!1,payload:{...e.payload,body:i}}},Ba=[`anyOf`,`oneOf`,`allOf`],Va=`The server also validates constraints that JSON Schema cannot express; $comment states them where known.`,Ha=(e,t)=>{let n=e;for(let e=0;e<16;e+=1){let e=n.$ref;if(typeof e!=`string`||!e.startsWith(`#/$defs/`))return n;let r=t[e.slice(8)];if(!w(r))return n;n=r}return n},Ua=(e,t,n)=>{let r=Ha(e,n),i=r.properties;if(w(i)&&w(i[t]))return i[t];let a=r.items;if(w(a))return Ua(a,t,n);let o=Ba.flatMap(e=>{let i=r[e];return Array.isArray(i)?i.flatMap(e=>{let r=w(e)?Ua(e,t,n):null;return r==null?[]:[r]}):[]}),[s]=o;return s==null?null:o.length===1?s:{anyOf:o}},Wa=(e,t)=>{let n=Ha(e,t),r=n.properties;if(w(r))return x(r);let i=Ba.flatMap(e=>{let r=n[e];return Array.isArray(r)?r.flatMap(e=>w(e)?Wa(e,t):[]):[]});return[...new Set(i)]},Ga=(e,t,n)=>{let r=e;for(let e of t.split(`.`)){if(r==null)return null;r=Ua(r,e,n)}return r},Ka=(e,t)=>{let n=Br(e,t);return x(n).length===0?e:{...e,$defs:n}},qa=(e,t,n)=>{let r=[],i=e=>{if(!(r.length>=2)){if(Array.isArray(e))for(let t of e)i(t);else if(w(e)){if(e[t]===n)r.push(e);else for(let t of ue(e))i(t)}}};for(let t of e)i(t.value);return r},Ja=e=>({isError:!0,payload:{error:e}}),Ya=(e,t)=>Ja({kind:`unknown_path`,message:e,keys:t}),Xa=(e,t)=>{let{operationId:n}=e,{$defs:r,...i}=e.fullInputSchema,a=w(r)?r:{},o=t==null?i:Ga(i,t,a);if(o==null)return Ya(`The input of ${n} has no key path "${t??``}". Use a key below, or join nested keys with "." (array items are entered implicitly).`,Wa(i,a));let s=e.inputDetails;return{isError:!1,payload:{operationId:n,...t==null?{description:e.description,hint:`To get only part of the schema, call ${M} again with path set to a key (nested keys joined with ".").`}:{selectedPath:t},...s==null||t!=null?{}:{groups:s.groups.map(e=>({path:e.path,discriminator:e.discriminator,description:e.description,types:e.variants.map(t=>({[e.discriminator]:t.value,summary:t.summary}))})),typeHint:`The keys at each group path depend on ${s.groups[0]?.discriminator??`type`}. Call ${M} with type to get the full shape of one type before sending it.`},note:Va,schema:Rr(Ka(o,a),80),...s==null||t!=null?{}:{examples:s.examples}}}},Za=(e,t,n,r)=>{let i=e.get(t);if(i==null)return Ja({kind:`unknown_operation`,message:`${t} is not a tool of this server.`,operationIds:[...e.keys()]});if(n==null)return Xa(i,r);let a=i.inputDetails,o=(a?.groups??[]).flatMap(e=>e.variants.filter(e=>e.value===n).map(t=>({group:e,variant:t})));if(a==null||o.length===0)return Ja({kind:`unknown_type`,message:a==null?`The input of ${t} does not depend on a type. Call ${M} without type.`:`${t} has no input type "${n}". Call ${M} without type to list the types.`,types:(a?.groups??[]).flatMap(e=>e.variants.map(e=>e.value))});let s=[];for(let{group:e,variant:i}of o){let o=Wa(i.schema,a.definitions),c=r==null?i.schema:Ga(i.schema,r,a.definitions);if(c==null)return Ya(`The ${n} input of ${t} has no key path "${r??``}". Use a key below, or join nested keys with "." (array items are entered implicitly, e.g. "aggregates.query").`,o);s.push({path:r==null?e.path:`${e.path}.${r}`,discriminator:e.discriminator,...r==null?{keys:o,examples:qa(a.examples,e.discriminator,n)}:{},schema:Rr(Ka(c,a.definitions),80)})}return{isError:!1,payload:{operationId:t,type:n,...r==null?{hint:`To get only part of the schema, call ${M} again with path set to one of keys (nested keys joined with ".").`}:{selectedPath:r},note:Va,schemas:s}}},Qa=(e,t)=>{let n=``,r=0,i=e.indexOf(`{`);for(;i!==-1;){let a=e.indexOf(`}`,i+1);if(a===-1)break;n+=a===i+1?e.slice(r,a+1):e.slice(r,i)+t(e.slice(i+1,a)),r=a+1,i=e.indexOf(`{`,r)}return n+e.slice(r)},$a=(e,t)=>{if(typeof t==`string`)return t;if(typeof t==`number`||typeof t==`boolean`)return String(t);throw new L(`argument "${e}" must be a string, number, or boolean`)},eo=/* @__PURE__ */ new Set([`.`,`..`,`%2e`,`.%2e`,`%2e.`,`%2e%2e`]),to=(e,t)=>{if(t===``||eo.has(t.toLowerCase()))throw new L(`path parameter "${e}" must not be empty, "." or ".."`);return encodeURIComponent(t)},no=(e,t,n)=>{if(b(n,`tenantName`))throw new L(`"${Ve}" is fixed by the server configuration`);let r=Qa(t.pathTemplate,t=>{if(t===`tenantName`)return encodeURIComponent(e.tenantName);let r=n[t];if(r==null)throw new L(`path parameter "${t}" is required`);return to(t,$a(t,r))}),i=[];for(let e of t.queryParams){let t=n[e];if(t!=null){if(Array.isArray(t))for(let n of t)i.push([e,$a(e,n)]);else i.push([e,$a(e,t)])}}let a=null,o=!1;if(t.wholeBodyField!=null){if(!b(n,t.wholeBodyField))throw new L(`argument "${t.wholeBodyField}" is required`);a=n[t.wholeBodyField],o=!0}else if(t.bodyFields!=null){let e={};for(let r of t.bodyFields)b(n,r)&&(e[r]=n[r]);a=e,o=!0}return{method:t.method,path:r,query:i,hasBody:o,body:a,responseKind:t.responseKind}},ro=(e,t,n)=>{if(e instanceof P){let{retryAfterSeconds:t,status:n}=e.info;return{isError:!0,payload:{error:{kind:`api`,...e.info,...t==null?{}:{hint:`${n===429?`Rate limited; the request was not processed. `:``}Wait ${String(t)} seconds, then call the tool again.`}}}}}if(e instanceof F)return{isError:!0,payload:{error:{kind:`transport`,failure:e.kind,status:e.status,message:e.message,...n===`write`?{note:`The write may have completed on the server even though no valid response was received. Check the current state with list_* / get_* / search_records before running it again.`}:{}}}};if(e instanceof I)return{isError:!0,payload:{error:{kind:`result_not_saved`,failure:e.kind,message:`The file could not be saved to the output directory.`}}};if(e instanceof L)return{isError:!0,payload:{error:{kind:`invalid_arguments`,message:e.message}}};if(e instanceof R)return{isError:!0,payload:{error:{kind:`workspace`,failure:e.kind,message:e.message}}};if(e instanceof z)return{isError:!0,payload:{error:{kind:`auth`,failure:e.kind,message:e.message}}};if(e instanceof Error)return{isError:!0,payload:{error:{kind:`unexpected`,message:K(e.message,t)}}};throw e},io=async(e,t,n)=>{try{return await Dt(e.workspace,new Date(e.now())),await e.auth.assertLoggedIn(),{isError:!1,payload:await n()}}catch(n){let r=e.auth.secrets(),i=ro(n,r,t.effect),a=JSON.parse(K(JSON.stringify(i.payload),r));return e.logger.warn(`tool call failed`,{operationId:t.operationId,payload:a}),{isError:!0,payload:a}}},ao=async(e,t,n)=>io(e,t,async()=>{let r=await e.client.request(no(e.config,t,n));switch(r.kind){case`json`:return{status:r.status,requestId:r.requestId,body:r.body};case`empty`:return{status:r.status,requestId:r.requestId};case`file`:try{let n=await Na(r.chunks,{outputDir:e.config.outputDir,fileName:`${t.operationId}.json`,maxBytes:2147483648,now:new Date(e.now())});return{status:r.status,requestId:r.requestId,file:{...n,format:`json`}}}finally{await r.cancel()}default:throw Error(`unknown response kind`)}}),oo=(e,t)=>`Flyle AI CX の公開 API を呼ぶツール群です。テーブルとレコードの参照・検索・作成・更新・削除、ロールの設定・割り当て、レポート・ダッシュボードの作成・編集、AI グルーピングの作成・編集・削除、ワークフローの参照と下書きの作成・更新を、ログインしたユーザーの権限で行います。
|
|
102
|
+
- 作業を始める前に必ず ${X} で製品の考え方とご利用ガイドの記事一覧を確認し、依頼に関係する記事を ${Z} で読んでください。公開 API の操作は ${X} を呼ぶまで実行されません。ツールに無い操作は代わりの手順を組み立てず、該当する記事を示して画面での操作を案内してください。
|
|
103
|
+
- 顧客の環境を利用者の合意なしに変えないでください。まず読み取り系ツール(readOnlyHint)で調べ、どの設定・データをどう変えるか(対象、変更前 → 変更後、影響)と理由を示して、利用者の明示的な合意を得てから書き込み系ツールを呼びます。合意した範囲を超える変更が必要になったら、その都度改めて合意を得てください。preview_* や search_* など、設定やデータを変えない確認は合意なしで進めて構いません。利用者が合意を省いてよいと明示した場合は、その範囲に限って確認を省けます。
|
|
104
|
+
- ロールの変更(create_role / update_role / update_role_assignments / delete_role)はテナントの全員の権限に直ちに影響します。実行前に list_roles / get_role で対象と現在の設定を確かめ、変更内容(対象・変更前 → 変更後)を利用者に示して明示的な同意を得てから実行してください。
|
|
105
|
+
- AI グルーピング(create_ai_grouping / update_ai_grouping / delete_ai_grouping)は対象テーブルに出力用の選択肢フィールドを作り、スケジュールに従って LLM で全レコードを分類します(AI の利用量に計上されます)。実行前に get_table で入力フィールド(PLAIN_TEXT)とフィールド名の重複を確かめ、作成・変更する内容(出力フィールド名・階層・スケジュール)を利用者に示して同意を得てください。作成しただけでは分類は走りません。今すぐ分類するには start_ai_grouping_job を使い、FULL・ONLY_ASSIGN は AI の利用量に計上されるので実行前に利用者の同意を得てください。分類もグループの移動・統合・削除(move_ai_grouping_groups / merge_ai_grouping_groups / delete_ai_grouping_group)も非同期になりうるので、応答が status queued やジョブを返したら get_ai_grouping_job で SUCCEEDED などの終わった状態になるまで確かめてから結果を報告します。統合・移動・削除はレコードの値を書き換えるので、対象のグループ(list_ai_grouping_groups)と影響を利用者に示して同意を得てください。スケジュールは 1 時間に 1 回まで(cron 式の分は 1 つの値)で、FULL は実行のたびにテーブルの全レコードを分類し直すので、頻度は利用者と決めてください。作成の応答を受け取れずに再送して出力フィールド名の重複で 400 になったら、list_ai_groupings で作成済みかを確かめてください。削除しても出力フィールドと分類済みの値はテーブルに残ります。
|
|
106
|
+
- ワークフロー(create_workflow / update_workflow)は下書きとして保存するだけで、保存しても公開はされません(動き出しません)。公開は利用者が画面で中身を確かめて行うよう案内してください。応答の issues に直すべき箇所が、publishable に公開できる状態かが返ります。update_workflow の nodes / edges は配列ごとの置き換えなので、get_workflow の結果を編集して送ってください。保存先の folderId は list_folders で探します。ノードの config の書き方(type ごとの設定項目)と入力例は ${M} で取得します。
|
|
107
|
+
- ツールの説明は要約で、大きい入力 schema は最上位のキーと型だけを載せています。説明の全文(制約・エラー・値の形式)と入力 schema の全体・入力例は ${M}(operationId)で取得します。create_* / update_* / preview_* は、呼ぶ前に必ず ${M} で入力の形を確かめてください。型ごとに形が違う入力(レポートの reportOption、ワークフローのノードの config、フィールドの作成など)は、type を指定してその型の形を取得します。大きい結果はファイルに保存されるので、必要な部分だけを path(例: "filter"、"aggregates")で取得できます。
|
|
108
|
+
- 接続先テナントは「${e}」、環境(公開 API のホスト)は「${t}」です。テナント・環境・ログインはサーバー起動時に固定されており、ツール引数でテナントを指定することはできません。
|
|
109
|
+
- この作業ディレクトリは「${e}」専用です。別の顧客(テナント)の情報・ファイル・記憶をこのテナントへの書き込みに使わないでください。別テナントの作業は別ディレクトリの別セッションで行います。
|
|
110
|
+
- 各ツール結果の先頭の environment と tenantName は、その操作を実行した環境とテナントです。
|
|
111
|
+
- ツール説明の「HTTP:」は呼び出す公開 API の操作で、パスは /v0/tenants/{tenantName} からの相対です。「先に読む記事:」の記事は ${Z} で読みます。
|
|
112
|
+
- ツールが「ログインが必要です」と返したら、ツール結果に示されたコマンドを利用者に作業ディレクトリで実行してもらってください。--api-base-url などの引数を書き足したり変えたりしないでください(接続先は利用者自身が確かめて指定します)。
|
|
113
|
+
- レコードを検索・書き込む前に list_tables でテーブルを探し、get_table でフィールド ID・型・選択肢を確認してください。値の形式は型で決まり、${M}(operationId: "create_record")の values の説明にあります。values のキーはフィールド名ではなくフィールド ID です。選択肢が多く optionsTruncated が true のフィールドは、list_select_options で選択肢 ID を探してください。
|
|
114
|
+
- search_records の結果は検索インデックス由来で、書き込み直後は数秒遅れることがあります。1 件の最新状態は get_record で確認してください。
|
|
115
|
+
- 書き込み系ツール(readOnlyHint: false)はテナントのデータを直ちに書き換えます(create_workflow / update_workflow は下書きを保存するだけで、公開も実行もしません)。書き込み系ツールは自動再送しません。Idempotency-Key はログイン接続では使えないため、タイムアウトや transport エラーの後は書き込みが完了している可能性があります。list_* / get_* / search_records で状態を確認してから再実行してください。
|
|
116
|
+
- 結果に error.kind = "result_not_saved" と operationCompleted: true があれば、操作は完了しており全文の保存だけに失敗しています。同じ操作を再実行しないでください。
|
|
117
|
+
- 大きな JSON 結果は出力ディレクトリに全文を保存し、保存先と先頭部分を返します。全文は保存ファイルを参照してください。
|
|
118
|
+
- レポート・ダッシュボードを作成・更新する前に preview_report / preview_dashboard で下書きを画像(SVG)にし、保存先のファイルを利用者に開いてもらって見た目(グラフの種類・軸・配色・配置)の同意を得てから create_* / update_* を実行してください。プレビューは何も保存しません。プレビューの応答に values(集計した数値)があれば、件数や集計値は画像ではなく values から読んでください。保存先の folderId は get_table の folderId(テーブルと同じフォルダ)か、既存のレポート・ダッシュボードの folderPath の末尾の ID です。update_dashboard の items は全カードの置き換えなので、読めないカード(他の人のレポートなど)も get_dashboard の結果のまま含めて送ってください。外すとダッシュボードから消えます。`,so=e=>w(e)&&e.type===`object`&&w(e.properties),co=(e,t)=>{if(!so(e))throw Error(`${t}: input schema must be an object schema`);return e},lo=`/v0/tenants/{${Ve}}`,uo={create_workflow:`下書きを保存するだけで、公開も実行もしません。`,update_workflow:`下書きを保存するだけで、公開も実行もしません。`},fo=e=>e.startsWith(lo)?e.slice(lo.length):e,po=/(?<=\.)\s+/u,mo=e=>{let t=[],n=0;for(let r of e.split(po)){if(t.length>0&&n+r.length>280)break;t.push(r),n+=r.length+1}return t.join(` `)},ho=e=>{let t=[e.summary];e.description!=null&&t.push(``,mo(e.description)),t.push(``,`HTTP: ${e.method} ${fo(e.pathTemplate)}`);let n=Ei(e.operationId);n!=null&&t.push(``,n);let r=Ti(e.operationId);r!=null&&t.push(``,r);let i=uo[e.operationId];return i!=null&&t.push(``,i),e.wholeBodyField!=null&&t.push(``,`リクエストボディは "${e.wholeBodyField}" 引数にそのまま渡します(判別共用体)。`),t.join(`
|
|
119
|
+
`)},go=/* @__PURE__ */ new Set([`update_role_assignments`]),_o=/* @__PURE__ */ new Set([`PUT`,`PATCH`,`DELETE`]),vo=e=>({readOnlyHint:e.effect===`read`,destructiveHint:e.effect!==`read`,idempotentHint:e.effect===`read`||_o.has(e.method)||go.has(e.operationId),openWorldHint:!1}),yo=e=>{let t=e.slice(0,4096),n=t.codePointAt(t.length-1)??0;return n>=55296&&n<=56319?t.slice(0,-1):t},bo=(e,t,n)=>({content:[{type:`text`,text:JSON.stringify({environment:e.environment,tenantName:e.tenantName})},{type:`text`,text:t}],isError:n}),$=async(e,t)=>{let{secrets:n}=t,r=K(JSON.stringify(e.payload,null,t.indent?2:void 0)??`null`,n);if(r.length<=t.maxTextChars)return bo(t,r,e.isError);let i=Buffer.from(K(JSON.stringify(e.payload)??`null`,n),`utf8`),a={totalChars:r.length,preview:yo(r)};try{let n=await Ma(i,{outputDir:t.outputDir,fileName:t.fileName,maxBytes:t.maxFileBytes,now:t.now});return bo(t,JSON.stringify({file:{...n,format:`json`},...a},null,2),e.isError)}catch(n){let r=n instanceof I?n.kind:`unexpected`;t.logger.warn(`tool result could not be saved`,{fileName:t.fileName,failure:r,bytes:i.byteLength});let o=!e.isError,s=t.effect===`write`?`The operation completed. Only saving the full result failed; do not run the operation again. The preview below is the beginning of the result.`:`The operation completed. Only saving the full result failed; the preview below is the beginning of the result.`;return bo(t,JSON.stringify({error:{kind:`result_not_saved`,failure:r,operationCompleted:o,message:o?s:`The operation failed and its full error was not saved; only the preview below is available.`},...a},null,2),e.isError)}},xo=(e,t,n)=>({environment:U(e.config.baseUrl),tenantName:e.config.tenantName,effect:n,outputDir:e.config.outputDir,fileName:`${t}.result.json`,logger:e.logger,secrets:e.auth.secrets(),maxFileBytes:67108864,maxTextChars:1048576,indent:!0,now:new Date(e.now())}),So=e=>w(e)?e:{},Co={readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},wo=(e,t,n)=>{e.registerTool(X,{title:`Read the Flyle AI CX product overview and guide index`,description:`作業の最初に呼びます。Flyle AI CX の考え方(テーブル・レポート・ワークフロー・ロールなどの概念)、この MCP サーバーでできること・できないこと、よくある依頼の進め方と、ご利用ガイドの全記事の一覧を返します。これを呼ぶまで公開 API の操作は実行されません。`,inputSchema:y({type:`object`,properties:{}}),annotations:Co},()=>(n(),$(ji(),xo(t,X,`read`)))),e.registerTool(bi,{title:`Search the Flyle AI CX user guide`,description:`ご利用ガイドの記事をキーワードで探します。空白区切りの複数キーワードは、より多く一致した記事を先に返します。記事の全文は ${Z} で読みます。`,inputSchema:y({type:`object`,properties:{query:{type:`string`,minLength:1,description:`検索キーワード(例: "AIグルーピング 階層")`},maxResults:{type:`integer`,minimum:1,maximum:20,description:`返す記事の最大数(既定 10)`}},required:[`query`],additionalProperties:!1}),annotations:Co},e=>{let n=So(e),r=typeof n.query==`string`?n.query:``,i=typeof n.maxResults==`number`?n.maxResults:10;return $(Mi(r,i),xo(t,bi,`read`))}),e.registerTool(Z,{title:`Read a Flyle AI CX user guide article`,description:`ご利用ガイドの記事を全文読みます。記事は ${X} の一覧や ${bi} の結果にある "nexus/table-edit" 形式で指定します。画面での操作手順・制約・用語の正はこの記事です。`,inputSchema:y({type:`object`,properties:{article:{type:`string`,minLength:1,description:`記事(例: "nexus/ai-grouping")`}},required:[`article`],additionalProperties:!1}),annotations:Co},e=>{let n=So(e).article;return $(Ni(typeof n==`string`?n:``),xo(t,Z,`read`))})},To=(e,t,n)=>{let r=new Map(n.operations.map(e=>[e.operationId,e])),i={type:`object`,properties:{operationId:{enum:[...r.keys()],description:`詳しく知りたいツールの名前`},type:{type:`string`,minLength:1,description:`型(例: "PIVOT_TABLE"、"SELECT_TABLE_RECORDS")。省くと説明の全文・入力 schema・型の一覧を返す`},path:{type:`string`,minLength:1,description:`一部だけを返すときのキー(例: "filter"、"aggregates.query")。type と一緒なら、その型の中のキー`}},required:[`operationId`],additionalProperties:!1},a=oa(M,i);e.registerTool(M,{title:`Get the detailed input schema of a tool`,description:`ツールの説明の全文(制約・エラー・値の形式)と入力 schema の全体・入力例を返します。type を指定すると、レポートの reportOption やワークフローのノードの config のように型ごとに形が違う入力の、その型の schema を返します。path で一部だけを返し、大きい結果はファイルに保存します。`,inputSchema:y(i,Li),annotations:Co},e=>{let n=So(e),i=typeof n.operationId==`string`?n.operationId:``,o=typeof n.type==`string`?n.type:null,s=typeof n.path==`string`?n.path:null;return $(a(n)??Za(r,i,o,s),{...xo(t,M,`read`),maxTextChars:16e3,indent:!1})})},Eo=(e,t)=>{let n=new oe({name:`flyle-ai-cx`,version:Pe},{capabilities:{tools:{}},instructions:oo(e.config.tenantName,U(e.config.baseUrl))}),r=!1;wo(n,e,()=>{r=!0}),To(n,e,t);for(let i of t.operations){let t=oa(i.operationId,co(i.fullInputSchema,i.operationId));n.registerTool(i.operationId,{title:i.summary,description:ho(i),inputSchema:y(co(i.inputSchema,i.operationId),Li),annotations:vo(i)},async n=>{let a=xo(e,i.operationId,i.effect),o=So(n),s=t(o);if(s!=null)return $(s,a);if(!r)return $(Pi(),a);let c=await za(await ao(e,i,o),i.inlineArtifacts,{operationId:i.operationId,outputDir:a.outputDir,maxBytes:8388608,now:a.now,secrets:a.secrets});return $(c,a)})}return n},Do=e=>new Promise(t=>setTimeout(t,e)),Oo=()=>Date.now(),ko=()=>{try{return n().username}catch{throw new B(`OS のユーザー情報を取得できませんでした(実行中のユーザーがシステムに登録されていない可能性があります)。登録済みのユーザーで実行してください。`)}},Ao=()=>({cwd:process.cwd(),homeDir:e(),hostname:t(),username:ko(),now:()=>/* @__PURE__ */ new Date}),jo=()=>Ut({platform:process.platform,env:process.env,homeDir:e()}),Mo=(e,t)=>{console.error(e),process.exit(t)},No=async e=>{try{return await Kt(e)}catch(e){if(e instanceof z&&e.kind===`login_required`)return null;throw e}},Po=async()=>{let e=await Et(Ao());if(e==null)throw new B("この作業ディレクトリはまだログインしていません。このディレクトリで `npx @flyle/ai-cx-mcp@latest login --tenant <テナント名>` を実行してから、MCP サーバーを起動し直してください。");let t=Rt(process.env,e.root,e),n=await Gt(jo(),e),r=await No(n);return r!=null&&On(r,t.baseUrl,t.tenantName),{config:t,workspace:e,credentialsFile:n,loggedIn:r!=null}},Fo=async()=>{let e=await Po().catch(e=>Mo(G(e),1)),{config:t,workspace:n,credentialsFile:r}=e,a=()=>[],o=Vn(()=>a()),s=An({credentialsFile:r,baseUrl:t.baseUrl,tenantName:t.tenantName,tokenClient:bn({config:t,auth:null,workspaceId:n.workspaceId,fetch:globalThis.fetch,sleep:Do,logger:o},Sn),now:Oo,lock:Xt(Oo,Do)});a=s.secrets;let c=li(),l={config:t,auth:s,client:bn({config:t,auth:s,workspaceId:n.workspaceId,fetch:globalThis.fetch,sleep:Do,logger:o}),logger:o,now:Oo,workspace:n},u=i(()=>Eo(l,c));o.info(`ai-cx mcp server started`,{environment:U(t.baseUrl),tenantName:t.tenantName,workspace:n.root,loggedIn:e.loggedIn,operations:c.operations.length});let d=!1,f=()=>{d||(d=!0,Promise.race([s.whenIdle(),Do(25e3)]).then(()=>u.close()).catch(V).finally(()=>process.exit(0)))};Fa(t.outputDir,{now:new Date(Oo()),maxAgeMs:6048e5}).then(e=>{e>0&&o.info(`old result files removed`,{removed:e})}).catch(()=>o.warn(`old result files could not be removed`)),process.on(`SIGINT`,f),process.on(`SIGTERM`,f),process.stdin.once(`end`,f)},Io=()=>({env:process.env,workspaceEnv:Ao(),credentialsDir:jo(),fetch:globalThis.fetch,now:Oo,sleep:Do,lock:Xt(Oo,Do),logger:Vn(()=>[]),out:e=>console.log(e),err:e=>console.error(e)}),Lo=async e=>{if(!process.stdin.isTTY)return!1;let t=r({input:process.stdin,output:process.stderr});try{return(await t.question(e)).trim().toLowerCase()===`y`}finally{t.close()}},Ro=async e=>{try{await e()}catch(e){Mo(G(e),1)}};await(async()=>{let[e,...t]=process.argv.slice(2);if(e==null){await Fo();return}let n={login:()=>hr({...Io(),argv:t,openBrowser:Lt(process.env)?()=>null:e=>Mn(e),callbackTimeoutMs:6e5,confirm:Lo}),logout:()=>Un(Io()),status:()=>vr(Io())},r=b(n,e)?n[e]:null;if(r==null)return Mo(`使い方: flyle-ai-cx-mcp [login [--tenant <テナント名>] [--api-base-url <URL>] | logout | status]
|
|
120
|
+
引数なしで起動すると MCP サーバー(stdio)として動きます。`,2);await Ro(r)})().catch(e=>Mo(G(e),1));export{};
|
package/manifest.json.br
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"@flyle/ai-cx-mcp","version":"0.0.0-develop.20261028035948.g64a97f7","description":"MCP server for the Flyle AI CX public API","keywords":["flyle","mcp","modelcontextprotocol"],"license":"SEE LICENSE IN LICENSE","author":"Flyle.inc","repository":{"type":"git","url":"git+https://github.com/flyle-io/flyle-nexus.git","directory":"apps/nexus/mcp"},"type":"module","engines":{"node":">=22.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"bin":{"flyle-ai-cx-mcp":"./main.js"},"dependencies":{"@modelcontextprotocol/server":"2.3.1"}}
|