taiwan-invoice-skill 2.0.0 → 2.1.0
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/README.md +131 -0
- package/assets/templates/base/quick-reference.md +85 -0
- package/assets/templates/platforms/{antigravity.json → agent.json} +6 -3
- package/assets/templates/platforms/claude.json +5 -2
- package/assets/templates/platforms/codebuddy.json +5 -2
- package/assets/templates/platforms/codex.json +5 -2
- package/assets/templates/platforms/continue.json +5 -2
- package/assets/templates/platforms/copilot.json +5 -2
- package/assets/templates/platforms/cursor.json +5 -2
- package/assets/templates/platforms/gemini.json +5 -2
- package/assets/templates/platforms/kiro.json +5 -2
- package/assets/templates/platforms/opencode.json +5 -2
- package/assets/templates/platforms/qoder.json +5 -2
- package/assets/templates/platforms/roocode.json +5 -2
- package/assets/templates/platforms/trae.json +5 -2
- package/assets/templates/platforms/windsurf.json +5 -2
- package/dist/index.js +265 -60
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# taiwan-invoice-skill
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>台灣電子發票 AI 開發技能包</strong><br>
|
|
5
|
+
<sub>支援 ECPay 綠界 · SmilePay 速買配 · Amego 光貿</sub>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://www.npmjs.com/package/taiwan-invoice-skill"><img src="https://img.shields.io/npm/v/taiwan-invoice-skill?style=flat-square&logo=npm" alt="npm version"></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/taiwan-invoice-skill"><img src="https://img.shields.io/npm/dm/taiwan-invoice-skill?style=flat-square&label=downloads" alt="npm downloads"></a>
|
|
11
|
+
<img src="https://img.shields.io/badge/node-%3E%3D18-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js">
|
|
12
|
+
<img src="https://img.shields.io/badge/platforms-14-blue?style=flat-square" alt="14 Platforms">
|
|
13
|
+
<a href="https://github.com/Moksa1123/taiwan-invoice/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Moksa1123/taiwan-invoice?style=flat-square" alt="License"></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="https://paypal.me/cccsubcom"><img src="https://img.shields.io/badge/PayPal-支持開發-00457C?style=for-the-badge&logo=paypal&logoColor=white" alt="PayPal"></a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 安裝
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g taiwan-invoice-skill
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 使用方式
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# 進入專案目錄
|
|
34
|
+
cd /path/to/your/project
|
|
35
|
+
|
|
36
|
+
# 選擇你的 AI 助手
|
|
37
|
+
taiwan-invoice init --ai claude # Claude Code
|
|
38
|
+
taiwan-invoice init --ai cursor # Cursor
|
|
39
|
+
taiwan-invoice init --ai windsurf # Windsurf
|
|
40
|
+
taiwan-invoice init --ai copilot # GitHub Copilot
|
|
41
|
+
taiwan-invoice init --ai antigravity # Antigravity
|
|
42
|
+
taiwan-invoice init --ai all # 全部安裝
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
<details>
|
|
46
|
+
<summary>完整平台列表</summary>
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
taiwan-invoice init --ai kiro # Kiro (AWS)
|
|
50
|
+
taiwan-invoice init --ai codex # Codex CLI (OpenAI)
|
|
51
|
+
taiwan-invoice init --ai qoder # Qoder
|
|
52
|
+
taiwan-invoice init --ai roocode # Roo Code
|
|
53
|
+
taiwan-invoice init --ai gemini # Gemini CLI
|
|
54
|
+
taiwan-invoice init --ai trae # Trae (ByteDance)
|
|
55
|
+
taiwan-invoice init --ai opencode # OpenCode
|
|
56
|
+
taiwan-invoice init --ai continue # Continue
|
|
57
|
+
taiwan-invoice init --ai codebuddy # CodeBuddy (Tencent)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
</details>
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 其他指令
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
taiwan-invoice list # 列出支援平台
|
|
68
|
+
taiwan-invoice info # 顯示技能資訊
|
|
69
|
+
taiwan-invoice versions # 列出可用版本
|
|
70
|
+
taiwan-invoice update # 檢查更新
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 選項
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
taiwan-invoice init --offline # 跳過 GitHub 下載,使用內建資源
|
|
77
|
+
taiwan-invoice init --force # 覆蓋現有檔案
|
|
78
|
+
taiwan-invoice init --global # 安裝到全域目錄
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 運作原理
|
|
84
|
+
|
|
85
|
+
`taiwan-invoice init` 預設會從 GitHub 下載最新版本。如果下載失敗(網路錯誤、速率限制),會自動使用 CLI 內建的資源。
|
|
86
|
+
|
|
87
|
+
使用 `--offline` 可跳過 GitHub 下載,直接使用內建資源。
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 支援平台
|
|
92
|
+
|
|
93
|
+
| 平台 | 說明 | 啟動方式 |
|
|
94
|
+
|------|------|----------|
|
|
95
|
+
| **Claude Code** | Anthropic 官方 CLI | 自動 |
|
|
96
|
+
| **Cursor** | AI 程式編輯器 | `/taiwan-invoice` |
|
|
97
|
+
| **Windsurf** | Codeium 編輯器 | 自動 |
|
|
98
|
+
| **Copilot** | GitHub Copilot | `/taiwan-invoice` |
|
|
99
|
+
| **Antigravity** | Google AI 助手 | 自動 |
|
|
100
|
+
| **Kiro** | AWS AI 助手 | `/taiwan-invoice` |
|
|
101
|
+
| **Codex** | OpenAI CLI | 自動 |
|
|
102
|
+
| **Qoder** | Qodo AI 助手 | 自動 |
|
|
103
|
+
| **RooCode** | VSCode 擴充 | `/taiwan-invoice` |
|
|
104
|
+
| **Gemini CLI** | Google Gemini | 自動 |
|
|
105
|
+
| **Trae** | ByteDance AI | 自動 |
|
|
106
|
+
| **OpenCode** | 開源 AI 助手 | 自動 |
|
|
107
|
+
| **Continue** | 開源 AI 助手 | 自動 |
|
|
108
|
+
| **CodeBuddy** | Tencent AI | 自動 |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 加值中心
|
|
113
|
+
|
|
114
|
+
| 加值中心 | 驗證方式 | 特點 |
|
|
115
|
+
|----------|----------|------|
|
|
116
|
+
| **ECPay 綠界** | AES-128-CBC 加密 | 市佔率高,文件完整 |
|
|
117
|
+
| **SmilePay 速買配** | URL 參數簽章 | 雙協定支援,整合簡單 |
|
|
118
|
+
| **Amego 光貿** | MD5 簽章 (MIG 4.0) | API 設計乾淨 |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 授權
|
|
123
|
+
|
|
124
|
+
[MIT License](https://github.com/Moksa1123/taiwan-invoice/blob/main/LICENSE)
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
<p align="center">
|
|
129
|
+
<sub>Made by <strong>Moksa</strong></sub><br>
|
|
130
|
+
<sub>service@moksaweb.com</sub>
|
|
131
|
+
</p>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
## When to Apply
|
|
2
|
+
|
|
3
|
+
Reference these guidelines when:
|
|
4
|
+
- Developing Taiwan E-Invoice issuance functionality
|
|
5
|
+
- Integrating ECPay, SmilePay, or Amego APIs
|
|
6
|
+
- Implementing B2C or B2B invoice logic
|
|
7
|
+
- Handling invoice printing, void, and allowance
|
|
8
|
+
- Troubleshooting invoice API integration issues
|
|
9
|
+
|
|
10
|
+
## Provider Quick Reference
|
|
11
|
+
|
|
12
|
+
| Priority | Task | Impact | Provider |
|
|
13
|
+
|----------|------|--------|----------|
|
|
14
|
+
| 1 | Amount Calculation | CRITICAL | All |
|
|
15
|
+
| 2 | Encryption/Signature | CRITICAL | All |
|
|
16
|
+
| 3 | B2B vs B2C Logic | HIGH | All |
|
|
17
|
+
| 4 | Print Response Handling | HIGH | All |
|
|
18
|
+
| 5 | Provider Binding | MEDIUM | All |
|
|
19
|
+
| 6 | Error Handling | MEDIUM | All |
|
|
20
|
+
| 7 | Carrier/Donation | LOW | B2C only |
|
|
21
|
+
|
|
22
|
+
## Quick Reference
|
|
23
|
+
|
|
24
|
+
### 1. Amount Calculation (CRITICAL)
|
|
25
|
+
|
|
26
|
+
- `b2c-tax-inclusive` - B2C uses tax-inclusive total
|
|
27
|
+
- `b2b-split-tax` - B2B requires pre-tax + tax split
|
|
28
|
+
- `round-tax` - Round tax: `Math.round(total - (total / 1.05))`
|
|
29
|
+
- `salesamount` - ECPay/Amego: Use SalesAmount for pre-tax
|
|
30
|
+
|
|
31
|
+
### 2. Encryption/Signature (CRITICAL)
|
|
32
|
+
|
|
33
|
+
- `ecpay-aes` - ECPay: AES-128-CBC with HashKey/HashIV
|
|
34
|
+
- `smilepay-verify` - SmilePay: Grvc + Verify_key params
|
|
35
|
+
- `amego-md5` - Amego: MD5(data + time + appKey)
|
|
36
|
+
- `url-encode` - Always URL encode before encryption
|
|
37
|
+
|
|
38
|
+
### 3. B2B vs B2C Logic (HIGH)
|
|
39
|
+
|
|
40
|
+
- `buyer-id-b2c` - B2C: BuyerIdentifier = "0000000000"
|
|
41
|
+
- `buyer-id-b2b` - B2B: BuyerIdentifier = actual 8-digit tax ID
|
|
42
|
+
- `no-carrier-b2b` - B2B: Cannot use carrier or donation
|
|
43
|
+
- `validate-taxid` - Validate 8-digit tax ID format
|
|
44
|
+
|
|
45
|
+
### 4. Print Response Handling (HIGH)
|
|
46
|
+
|
|
47
|
+
- `ecpay-html` - ECPay: Returns HTML, use window.document.write
|
|
48
|
+
- `smilepay-redirect` - SmilePay: Returns URL, use window.open
|
|
49
|
+
- `amego-pdf` - Amego: Returns PDF URL, use window.open
|
|
50
|
+
- `form-submit` - Some APIs require form POST submission
|
|
51
|
+
|
|
52
|
+
### 5. Provider Binding (MEDIUM)
|
|
53
|
+
|
|
54
|
+
- `save-provider` - Save invoiceProvider when issuing
|
|
55
|
+
- `save-random` - Save invoiceRandomNum for printing
|
|
56
|
+
- `match-provider` - Use issuing provider for print/void
|
|
57
|
+
|
|
58
|
+
### 6. Error Handling (MEDIUM)
|
|
59
|
+
|
|
60
|
+
- `log-raw-response` - Log complete raw response for debugging
|
|
61
|
+
- `ecpay-codes` - ECPay: Check RtnCode and RtnMsg
|
|
62
|
+
- `smilepay-codes` - SmilePay: Check Status field
|
|
63
|
+
- `amego-codes` - Amego: Check Code and Message
|
|
64
|
+
|
|
65
|
+
### 7. Carrier/Donation (B2C only)
|
|
66
|
+
|
|
67
|
+
- `carrier-mobile` - Mobile barcode: /XXXXXXX format
|
|
68
|
+
- `carrier-npc` - Natural person certificate
|
|
69
|
+
- `donation-code` - Donation: 3-7 digit love code
|
|
70
|
+
- `mutual-exclusive` - Carrier and donation are mutually exclusive
|
|
71
|
+
|
|
72
|
+
## Test Credentials
|
|
73
|
+
|
|
74
|
+
| Provider | Key Info |
|
|
75
|
+
|----------|----------|
|
|
76
|
+
| ECPay | MerchantID: 2000132, Stage URL |
|
|
77
|
+
| SmilePay | Grvc: SEI1000034, Test Tax ID: 80129529 |
|
|
78
|
+
| Amego | Tax ID: 12345678, test@amego.tw |
|
|
79
|
+
|
|
80
|
+
## How to Use
|
|
81
|
+
|
|
82
|
+
See the full skill documentation for detailed API references and code examples.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"platform": "antigravity",
|
|
3
|
-
"displayName": "
|
|
3
|
+
"displayName": "Antigravity / Generic Agent",
|
|
4
4
|
"installType": "full",
|
|
5
5
|
"folderStructure": {
|
|
6
6
|
"root": ".agent",
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": {
|
|
11
12
|
"name": "taiwan-invoice",
|
|
12
13
|
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego. Provides B2C/B2B invoice issuance, void, allowance, query, and print functionality."
|
|
@@ -14,8 +15,10 @@
|
|
|
14
15
|
"sections": {
|
|
15
16
|
"examples": true,
|
|
16
17
|
"references": true,
|
|
17
|
-
"scripts": true
|
|
18
|
+
"scripts": true,
|
|
19
|
+
"quickReference": false
|
|
18
20
|
},
|
|
19
21
|
"title": "Taiwan E-Invoice Skill",
|
|
20
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
22
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
23
|
+
"skillOrWorkflow": "Skill"
|
|
21
24
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": {
|
|
11
12
|
"name": "taiwan-invoice",
|
|
12
13
|
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego. Provides B2C/B2B invoice issuance, void, allowance, query, and print functionality. Includes encryption implementations (AES-128-CBC, MD5), tax calculations, and complete API specifications.",
|
|
@@ -15,8 +16,10 @@
|
|
|
15
16
|
"sections": {
|
|
16
17
|
"examples": true,
|
|
17
18
|
"references": true,
|
|
18
|
-
"scripts": true
|
|
19
|
+
"scripts": true,
|
|
20
|
+
"quickReference": true
|
|
19
21
|
},
|
|
20
22
|
"title": "Taiwan E-Invoice Skill",
|
|
21
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
23
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
24
|
+
"skillOrWorkflow": "Skill"
|
|
22
25
|
}
|
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": null,
|
|
11
12
|
"sections": {
|
|
12
13
|
"examples": true,
|
|
13
14
|
"references": true,
|
|
14
|
-
"scripts": true
|
|
15
|
+
"scripts": true,
|
|
16
|
+
"quickReference": false
|
|
15
17
|
},
|
|
16
18
|
"title": "Taiwan E-Invoice Skill",
|
|
17
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
19
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
18
21
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": {
|
|
11
12
|
"name": "taiwan-invoice",
|
|
12
13
|
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego."
|
|
@@ -14,8 +15,10 @@
|
|
|
14
15
|
"sections": {
|
|
15
16
|
"examples": true,
|
|
16
17
|
"references": true,
|
|
17
|
-
"scripts": true
|
|
18
|
+
"scripts": true,
|
|
19
|
+
"quickReference": false
|
|
18
20
|
},
|
|
19
21
|
"title": "Taiwan E-Invoice Skill",
|
|
20
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
22
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
23
|
+
"skillOrWorkflow": "Skill"
|
|
21
24
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": {
|
|
11
12
|
"name": "taiwan-invoice",
|
|
12
13
|
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego."
|
|
@@ -14,8 +15,10 @@
|
|
|
14
15
|
"sections": {
|
|
15
16
|
"examples": true,
|
|
16
17
|
"references": true,
|
|
17
|
-
"scripts": true
|
|
18
|
+
"scripts": true,
|
|
19
|
+
"quickReference": false
|
|
18
20
|
},
|
|
19
21
|
"title": "Taiwan E-Invoice Skill",
|
|
20
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
22
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
23
|
+
"skillOrWorkflow": "Skill"
|
|
21
24
|
}
|
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
"skillPath": "prompts/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "prompts/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": null,
|
|
11
12
|
"sections": {
|
|
12
13
|
"examples": true,
|
|
13
14
|
"references": true,
|
|
14
|
-
"scripts": true
|
|
15
|
+
"scripts": true,
|
|
16
|
+
"quickReference": false
|
|
15
17
|
},
|
|
16
18
|
"title": "Taiwan E-Invoice Skill",
|
|
17
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
19
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
18
21
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": {
|
|
11
12
|
"name": "taiwan-invoice",
|
|
12
13
|
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego. Provides B2C/B2B invoice issuance, void, allowance, query, and print functionality. Includes encryption implementations (AES-128-CBC, MD5), tax calculations, and complete API specifications."
|
|
@@ -14,8 +15,10 @@
|
|
|
14
15
|
"sections": {
|
|
15
16
|
"examples": true,
|
|
16
17
|
"references": true,
|
|
17
|
-
"scripts": true
|
|
18
|
+
"scripts": true,
|
|
19
|
+
"quickReference": false
|
|
18
20
|
},
|
|
19
21
|
"title": "Taiwan E-Invoice Skill",
|
|
20
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
22
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
23
|
+
"skillOrWorkflow": "Skill"
|
|
21
24
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": {
|
|
11
12
|
"name": "taiwan-invoice",
|
|
12
13
|
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego."
|
|
@@ -14,8 +15,10 @@
|
|
|
14
15
|
"sections": {
|
|
15
16
|
"examples": true,
|
|
16
17
|
"references": true,
|
|
17
|
-
"scripts": true
|
|
18
|
+
"scripts": true,
|
|
19
|
+
"quickReference": false
|
|
18
20
|
},
|
|
19
21
|
"title": "Taiwan E-Invoice Skill",
|
|
20
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
22
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
23
|
+
"skillOrWorkflow": "Skill"
|
|
21
24
|
}
|
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
"skillPath": "steering/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "steering/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": null,
|
|
11
12
|
"sections": {
|
|
12
13
|
"examples": true,
|
|
13
14
|
"references": true,
|
|
14
|
-
"scripts": true
|
|
15
|
+
"scripts": true,
|
|
16
|
+
"quickReference": false
|
|
15
17
|
},
|
|
16
18
|
"title": "Taiwan E-Invoice Skill",
|
|
17
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
19
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
18
21
|
}
|
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": null,
|
|
11
12
|
"sections": {
|
|
12
13
|
"examples": true,
|
|
13
14
|
"references": true,
|
|
14
|
-
"scripts": true
|
|
15
|
+
"scripts": true,
|
|
16
|
+
"quickReference": false
|
|
15
17
|
},
|
|
16
18
|
"title": "Taiwan E-Invoice Skill",
|
|
17
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
19
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
18
21
|
}
|
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
"skillPath": "rules/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "rules/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": null,
|
|
11
12
|
"sections": {
|
|
12
13
|
"examples": true,
|
|
13
14
|
"references": true,
|
|
14
|
-
"scripts": true
|
|
15
|
+
"scripts": true,
|
|
16
|
+
"quickReference": false
|
|
15
17
|
},
|
|
16
18
|
"title": "Taiwan E-Invoice Skill",
|
|
17
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
19
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
18
21
|
}
|
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
"skillPath": "commands/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "commands/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": null,
|
|
11
12
|
"sections": {
|
|
12
13
|
"examples": true,
|
|
13
14
|
"references": true,
|
|
14
|
-
"scripts": true
|
|
15
|
+
"scripts": true,
|
|
16
|
+
"quickReference": false
|
|
15
17
|
},
|
|
16
18
|
"title": "Taiwan E-Invoice Skill",
|
|
17
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
19
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
18
21
|
}
|
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": null,
|
|
11
12
|
"sections": {
|
|
12
13
|
"examples": true,
|
|
13
14
|
"references": true,
|
|
14
|
-
"scripts": true
|
|
15
|
+
"scripts": true,
|
|
16
|
+
"quickReference": false
|
|
15
17
|
},
|
|
16
18
|
"title": "Taiwan E-Invoice Skill",
|
|
17
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
19
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
18
21
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"skillPath": "skills/taiwan-invoice",
|
|
8
8
|
"filename": "SKILL.md"
|
|
9
9
|
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
10
11
|
"frontmatter": {
|
|
11
12
|
"name": "taiwan-invoice",
|
|
12
13
|
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego. Provides B2C/B2B invoice issuance, void, allowance, query, and print functionality."
|
|
@@ -14,8 +15,10 @@
|
|
|
14
15
|
"sections": {
|
|
15
16
|
"examples": true,
|
|
16
17
|
"references": true,
|
|
17
|
-
"scripts": true
|
|
18
|
+
"scripts": true,
|
|
19
|
+
"quickReference": false
|
|
18
20
|
},
|
|
19
21
|
"title": "Taiwan E-Invoice Skill",
|
|
20
|
-
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations."
|
|
22
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
23
|
+
"skillOrWorkflow": "Skill"
|
|
21
24
|
}
|
package/dist/index.js
CHANGED
|
@@ -921,8 +921,8 @@ var require_command = __commonJS({
|
|
|
921
921
|
"node_modules/commander/lib/command.js"(exports2) {
|
|
922
922
|
var EventEmitter = require("events").EventEmitter;
|
|
923
923
|
var childProcess = require("child_process");
|
|
924
|
-
var
|
|
925
|
-
var
|
|
924
|
+
var path3 = require("path");
|
|
925
|
+
var fs3 = require("fs");
|
|
926
926
|
var process2 = require("process");
|
|
927
927
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
928
928
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1745,10 +1745,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1745
1745
|
let launchWithNode = false;
|
|
1746
1746
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1747
1747
|
function findFile(baseDir, baseName) {
|
|
1748
|
-
const localBin =
|
|
1749
|
-
if (
|
|
1750
|
-
if (sourceExt.includes(
|
|
1751
|
-
const foundExt = sourceExt.find((ext) =>
|
|
1748
|
+
const localBin = path3.resolve(baseDir, baseName);
|
|
1749
|
+
if (fs3.existsSync(localBin)) return localBin;
|
|
1750
|
+
if (sourceExt.includes(path3.extname(baseName))) return void 0;
|
|
1751
|
+
const foundExt = sourceExt.find((ext) => fs3.existsSync(`${localBin}${ext}`));
|
|
1752
1752
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1753
1753
|
return void 0;
|
|
1754
1754
|
}
|
|
@@ -1759,23 +1759,23 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1759
1759
|
if (this._scriptPath) {
|
|
1760
1760
|
let resolvedScriptPath;
|
|
1761
1761
|
try {
|
|
1762
|
-
resolvedScriptPath =
|
|
1762
|
+
resolvedScriptPath = fs3.realpathSync(this._scriptPath);
|
|
1763
1763
|
} catch (err) {
|
|
1764
1764
|
resolvedScriptPath = this._scriptPath;
|
|
1765
1765
|
}
|
|
1766
|
-
executableDir =
|
|
1766
|
+
executableDir = path3.resolve(path3.dirname(resolvedScriptPath), executableDir);
|
|
1767
1767
|
}
|
|
1768
1768
|
if (executableDir) {
|
|
1769
1769
|
let localFile = findFile(executableDir, executableFile);
|
|
1770
1770
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1771
|
-
const legacyName =
|
|
1771
|
+
const legacyName = path3.basename(this._scriptPath, path3.extname(this._scriptPath));
|
|
1772
1772
|
if (legacyName !== this._name) {
|
|
1773
1773
|
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
|
1774
1774
|
}
|
|
1775
1775
|
}
|
|
1776
1776
|
executableFile = localFile || executableFile;
|
|
1777
1777
|
}
|
|
1778
|
-
launchWithNode = sourceExt.includes(
|
|
1778
|
+
launchWithNode = sourceExt.includes(path3.extname(executableFile));
|
|
1779
1779
|
let proc;
|
|
1780
1780
|
if (process2.platform !== "win32") {
|
|
1781
1781
|
if (launchWithNode) {
|
|
@@ -2558,7 +2558,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2558
2558
|
* @return {Command}
|
|
2559
2559
|
*/
|
|
2560
2560
|
nameFromFilename(filename) {
|
|
2561
|
-
this._name =
|
|
2561
|
+
this._name = path3.basename(filename, path3.extname(filename));
|
|
2562
2562
|
return this;
|
|
2563
2563
|
}
|
|
2564
2564
|
/**
|
|
@@ -2572,9 +2572,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2572
2572
|
* @param {string} [path]
|
|
2573
2573
|
* @return {string|null|Command}
|
|
2574
2574
|
*/
|
|
2575
|
-
executableDir(
|
|
2576
|
-
if (
|
|
2577
|
-
this._executableDir =
|
|
2575
|
+
executableDir(path4) {
|
|
2576
|
+
if (path4 === void 0) return this._executableDir;
|
|
2577
|
+
this._executableDir = path4;
|
|
2578
2578
|
return this;
|
|
2579
2579
|
}
|
|
2580
2580
|
/**
|
|
@@ -3634,15 +3634,15 @@ var require_route = __commonJS({
|
|
|
3634
3634
|
};
|
|
3635
3635
|
}
|
|
3636
3636
|
function wrapConversion(toModel, graph) {
|
|
3637
|
-
const
|
|
3637
|
+
const path3 = [graph[toModel].parent, toModel];
|
|
3638
3638
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
3639
3639
|
let cur = graph[toModel].parent;
|
|
3640
3640
|
while (graph[cur].parent) {
|
|
3641
|
-
|
|
3641
|
+
path3.unshift(graph[cur].parent);
|
|
3642
3642
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
3643
3643
|
cur = graph[cur].parent;
|
|
3644
3644
|
}
|
|
3645
|
-
fn.conversion =
|
|
3645
|
+
fn.conversion = path3;
|
|
3646
3646
|
return fn;
|
|
3647
3647
|
}
|
|
3648
3648
|
module2.exports = function(fromModel) {
|
|
@@ -3741,10 +3741,10 @@ var require_ansi_styles = __commonJS({
|
|
|
3741
3741
|
};
|
|
3742
3742
|
var ansi2ansi = (n) => n;
|
|
3743
3743
|
var rgb2rgb = (r, g, b) => [r, g, b];
|
|
3744
|
-
var setLazyProperty = (object, property,
|
|
3744
|
+
var setLazyProperty = (object, property, get2) => {
|
|
3745
3745
|
Object.defineProperty(object, property, {
|
|
3746
3746
|
get: () => {
|
|
3747
|
-
const value =
|
|
3747
|
+
const value = get2();
|
|
3748
3748
|
Object.defineProperty(object, property, {
|
|
3749
3749
|
value,
|
|
3750
3750
|
enumerable: true,
|
|
@@ -3882,7 +3882,7 @@ var require_has_flag = __commonJS({
|
|
|
3882
3882
|
var require_supports_color = __commonJS({
|
|
3883
3883
|
"node_modules/supports-color/index.js"(exports2, module2) {
|
|
3884
3884
|
"use strict";
|
|
3885
|
-
var
|
|
3885
|
+
var os2 = require("os");
|
|
3886
3886
|
var tty = require("tty");
|
|
3887
3887
|
var hasFlag = require_has_flag();
|
|
3888
3888
|
var { env } = process;
|
|
@@ -3930,7 +3930,7 @@ var require_supports_color = __commonJS({
|
|
|
3930
3930
|
return min;
|
|
3931
3931
|
}
|
|
3932
3932
|
if (process.platform === "win32") {
|
|
3933
|
-
const osRelease =
|
|
3933
|
+
const osRelease = os2.release().split(".");
|
|
3934
3934
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
3935
3935
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
3936
3936
|
}
|
|
@@ -6800,7 +6800,7 @@ var require_buffer_list = __commonJS({
|
|
|
6800
6800
|
}
|
|
6801
6801
|
}, {
|
|
6802
6802
|
key: "join",
|
|
6803
|
-
value: function
|
|
6803
|
+
value: function join5(s) {
|
|
6804
6804
|
if (this.length === 0) return "";
|
|
6805
6805
|
var p = this.head;
|
|
6806
6806
|
var ret = "" + p.data;
|
|
@@ -7377,7 +7377,7 @@ var require_stream_writable = __commonJS({
|
|
|
7377
7377
|
// because otherwise some prototype manipulation in
|
|
7378
7378
|
// userland will fail
|
|
7379
7379
|
enumerable: false,
|
|
7380
|
-
get: function
|
|
7380
|
+
get: function get2() {
|
|
7381
7381
|
return this._writableState && this._writableState.getBuffer();
|
|
7382
7382
|
}
|
|
7383
7383
|
});
|
|
@@ -7392,7 +7392,7 @@ var require_stream_writable = __commonJS({
|
|
|
7392
7392
|
// because otherwise some prototype manipulation in
|
|
7393
7393
|
// userland will fail
|
|
7394
7394
|
enumerable: false,
|
|
7395
|
-
get: function
|
|
7395
|
+
get: function get2() {
|
|
7396
7396
|
return this._writableState.highWaterMark;
|
|
7397
7397
|
}
|
|
7398
7398
|
});
|
|
@@ -7562,7 +7562,7 @@ var require_stream_writable = __commonJS({
|
|
|
7562
7562
|
// because otherwise some prototype manipulation in
|
|
7563
7563
|
// userland will fail
|
|
7564
7564
|
enumerable: false,
|
|
7565
|
-
get: function
|
|
7565
|
+
get: function get2() {
|
|
7566
7566
|
return this._writableState.length;
|
|
7567
7567
|
}
|
|
7568
7568
|
});
|
|
@@ -7635,7 +7635,7 @@ var require_stream_writable = __commonJS({
|
|
|
7635
7635
|
// because otherwise some prototype manipulation in
|
|
7636
7636
|
// userland will fail
|
|
7637
7637
|
enumerable: false,
|
|
7638
|
-
get: function
|
|
7638
|
+
get: function get2() {
|
|
7639
7639
|
if (this._writableState === void 0) {
|
|
7640
7640
|
return false;
|
|
7641
7641
|
}
|
|
@@ -7698,7 +7698,7 @@ var require_stream_duplex = __commonJS({
|
|
|
7698
7698
|
// because otherwise some prototype manipulation in
|
|
7699
7699
|
// userland will fail
|
|
7700
7700
|
enumerable: false,
|
|
7701
|
-
get: function
|
|
7701
|
+
get: function get2() {
|
|
7702
7702
|
return this._writableState.highWaterMark;
|
|
7703
7703
|
}
|
|
7704
7704
|
});
|
|
@@ -7707,7 +7707,7 @@ var require_stream_duplex = __commonJS({
|
|
|
7707
7707
|
// because otherwise some prototype manipulation in
|
|
7708
7708
|
// userland will fail
|
|
7709
7709
|
enumerable: false,
|
|
7710
|
-
get: function
|
|
7710
|
+
get: function get2() {
|
|
7711
7711
|
return this._writableState && this._writableState.getBuffer();
|
|
7712
7712
|
}
|
|
7713
7713
|
});
|
|
@@ -7716,7 +7716,7 @@ var require_stream_duplex = __commonJS({
|
|
|
7716
7716
|
// because otherwise some prototype manipulation in
|
|
7717
7717
|
// userland will fail
|
|
7718
7718
|
enumerable: false,
|
|
7719
|
-
get: function
|
|
7719
|
+
get: function get2() {
|
|
7720
7720
|
return this._writableState.length;
|
|
7721
7721
|
}
|
|
7722
7722
|
});
|
|
@@ -7732,7 +7732,7 @@ var require_stream_duplex = __commonJS({
|
|
|
7732
7732
|
// because otherwise some prototype manipulation in
|
|
7733
7733
|
// userland will fail
|
|
7734
7734
|
enumerable: false,
|
|
7735
|
-
get: function
|
|
7735
|
+
get: function get2() {
|
|
7736
7736
|
if (this._readableState === void 0 || this._writableState === void 0) {
|
|
7737
7737
|
return false;
|
|
7738
7738
|
}
|
|
@@ -8540,7 +8540,7 @@ var require_stream_readable = __commonJS({
|
|
|
8540
8540
|
// because otherwise some prototype manipulation in
|
|
8541
8541
|
// userland will fail
|
|
8542
8542
|
enumerable: false,
|
|
8543
|
-
get: function
|
|
8543
|
+
get: function get2() {
|
|
8544
8544
|
if (this._readableState === void 0) {
|
|
8545
8545
|
return false;
|
|
8546
8546
|
}
|
|
@@ -8823,7 +8823,7 @@ var require_stream_readable = __commonJS({
|
|
|
8823
8823
|
if (readable === src) {
|
|
8824
8824
|
if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
|
|
8825
8825
|
unpipeInfo.hasUnpiped = true;
|
|
8826
|
-
|
|
8826
|
+
cleanup2();
|
|
8827
8827
|
}
|
|
8828
8828
|
}
|
|
8829
8829
|
}
|
|
@@ -8834,7 +8834,7 @@ var require_stream_readable = __commonJS({
|
|
|
8834
8834
|
var ondrain = pipeOnDrain(src);
|
|
8835
8835
|
dest.on("drain", ondrain);
|
|
8836
8836
|
var cleanedUp = false;
|
|
8837
|
-
function
|
|
8837
|
+
function cleanup2() {
|
|
8838
8838
|
debug("cleanup");
|
|
8839
8839
|
dest.removeListener("close", onclose);
|
|
8840
8840
|
dest.removeListener("finish", onfinish);
|
|
@@ -9081,7 +9081,7 @@ var require_stream_readable = __commonJS({
|
|
|
9081
9081
|
// because otherwise some prototype manipulation in
|
|
9082
9082
|
// userland will fail
|
|
9083
9083
|
enumerable: false,
|
|
9084
|
-
get: function
|
|
9084
|
+
get: function get2() {
|
|
9085
9085
|
return this._readableState.highWaterMark;
|
|
9086
9086
|
}
|
|
9087
9087
|
});
|
|
@@ -9090,7 +9090,7 @@ var require_stream_readable = __commonJS({
|
|
|
9090
9090
|
// because otherwise some prototype manipulation in
|
|
9091
9091
|
// userland will fail
|
|
9092
9092
|
enumerable: false,
|
|
9093
|
-
get: function
|
|
9093
|
+
get: function get2() {
|
|
9094
9094
|
return this._readableState && this._readableState.buffer;
|
|
9095
9095
|
}
|
|
9096
9096
|
});
|
|
@@ -9099,7 +9099,7 @@ var require_stream_readable = __commonJS({
|
|
|
9099
9099
|
// because otherwise some prototype manipulation in
|
|
9100
9100
|
// userland will fail
|
|
9101
9101
|
enumerable: false,
|
|
9102
|
-
get: function
|
|
9102
|
+
get: function get2() {
|
|
9103
9103
|
return this._readableState.flowing;
|
|
9104
9104
|
},
|
|
9105
9105
|
set: function set(state) {
|
|
@@ -9114,7 +9114,7 @@ var require_stream_readable = __commonJS({
|
|
|
9114
9114
|
// because otherwise some prototype manipulation in
|
|
9115
9115
|
// userland will fail
|
|
9116
9116
|
enumerable: false,
|
|
9117
|
-
get: function
|
|
9117
|
+
get: function get2() {
|
|
9118
9118
|
return this._readableState.length;
|
|
9119
9119
|
}
|
|
9120
9120
|
});
|
|
@@ -9440,7 +9440,7 @@ var require_BufferList = __commonJS({
|
|
|
9440
9440
|
}
|
|
9441
9441
|
return offset;
|
|
9442
9442
|
};
|
|
9443
|
-
BufferList.prototype.get = function
|
|
9443
|
+
BufferList.prototype.get = function get2(index) {
|
|
9444
9444
|
if (index > this.length || index < 0) {
|
|
9445
9445
|
return void 0;
|
|
9446
9446
|
}
|
|
@@ -14965,6 +14965,8 @@ var {
|
|
|
14965
14965
|
var import_chalk2 = __toESM(require_source());
|
|
14966
14966
|
var import_ora = __toESM(require_ora());
|
|
14967
14967
|
var import_prompts = __toESM(require_prompts3());
|
|
14968
|
+
var path2 = __toESM(require("path"));
|
|
14969
|
+
var os = __toESM(require("os"));
|
|
14968
14970
|
|
|
14969
14971
|
// src/types/index.ts
|
|
14970
14972
|
var AI_TYPES = [
|
|
@@ -14984,6 +14986,22 @@ var AI_TYPES = [
|
|
|
14984
14986
|
"codebuddy",
|
|
14985
14987
|
"all"
|
|
14986
14988
|
];
|
|
14989
|
+
var AI_FOLDERS = {
|
|
14990
|
+
claude: [".claude"],
|
|
14991
|
+
cursor: [".cursor"],
|
|
14992
|
+
windsurf: [".windsurf"],
|
|
14993
|
+
antigravity: [".agent"],
|
|
14994
|
+
copilot: [".github"],
|
|
14995
|
+
kiro: [".kiro"],
|
|
14996
|
+
codex: [".codex"],
|
|
14997
|
+
qoder: [".qoder"],
|
|
14998
|
+
roocode: [".roo"],
|
|
14999
|
+
gemini: [".gemini"],
|
|
15000
|
+
trae: [".trae"],
|
|
15001
|
+
opencode: [".opencode"],
|
|
15002
|
+
continue: [".continue"],
|
|
15003
|
+
codebuddy: [".codebuddy"]
|
|
15004
|
+
};
|
|
14987
15005
|
|
|
14988
15006
|
// src/utils/template.ts
|
|
14989
15007
|
var import_promises = require("node:fs/promises");
|
|
@@ -14995,7 +15013,7 @@ var AI_TO_PLATFORM = {
|
|
|
14995
15013
|
claude: "claude",
|
|
14996
15014
|
cursor: "cursor",
|
|
14997
15015
|
windsurf: "windsurf",
|
|
14998
|
-
antigravity: "
|
|
15016
|
+
antigravity: "agent",
|
|
14999
15017
|
copilot: "copilot",
|
|
15000
15018
|
kiro: "kiro",
|
|
15001
15019
|
codex: "codex",
|
|
@@ -15007,9 +15025,9 @@ var AI_TO_PLATFORM = {
|
|
|
15007
15025
|
continue: "continue",
|
|
15008
15026
|
codebuddy: "codebuddy"
|
|
15009
15027
|
};
|
|
15010
|
-
async function exists(
|
|
15028
|
+
async function exists(path3) {
|
|
15011
15029
|
try {
|
|
15012
|
-
await (0, import_promises.access)(
|
|
15030
|
+
await (0, import_promises.access)(path3);
|
|
15013
15031
|
return true;
|
|
15014
15032
|
} catch {
|
|
15015
15033
|
return false;
|
|
@@ -15045,6 +15063,13 @@ async function renderSkillFile(config) {
|
|
|
15045
15063
|
let content = await loadTemplate("base/skill-content.md");
|
|
15046
15064
|
const frontmatter = renderFrontmatter(config.frontmatter);
|
|
15047
15065
|
content = content.replace(/\{\{TITLE\}\}/g, config.title).replace(/\{\{DESCRIPTION\}\}/g, config.description);
|
|
15066
|
+
if (config.sections.quickReference) {
|
|
15067
|
+
try {
|
|
15068
|
+
const quickRef = await loadTemplate("base/quick-reference.md");
|
|
15069
|
+
content = quickRef + "\n" + content;
|
|
15070
|
+
} catch {
|
|
15071
|
+
}
|
|
15072
|
+
}
|
|
15048
15073
|
return frontmatter + content;
|
|
15049
15074
|
}
|
|
15050
15075
|
async function copyTaiwanInvoiceAssets(targetSkillDir, sections) {
|
|
@@ -15194,7 +15219,186 @@ ${msg}
|
|
|
15194
15219
|
dim: (msg) => console.log(import_chalk.default.dim(msg))
|
|
15195
15220
|
};
|
|
15196
15221
|
|
|
15222
|
+
// src/utils/github.ts
|
|
15223
|
+
var https = __toESM(require("https"));
|
|
15224
|
+
var fs = __toESM(require("fs"));
|
|
15225
|
+
var REPO_OWNER = "Moksa1123";
|
|
15226
|
+
var REPO_NAME = "taiwan-invoice";
|
|
15227
|
+
async function fetchReleases() {
|
|
15228
|
+
return new Promise((resolve, reject) => {
|
|
15229
|
+
const options = {
|
|
15230
|
+
hostname: "api.github.com",
|
|
15231
|
+
path: `/repos/${REPO_OWNER}/${REPO_NAME}/releases`,
|
|
15232
|
+
headers: {
|
|
15233
|
+
"User-Agent": "taiwan-invoice-skill-cli",
|
|
15234
|
+
"Accept": "application/vnd.github.v3+json"
|
|
15235
|
+
}
|
|
15236
|
+
};
|
|
15237
|
+
https.get(options, (res) => {
|
|
15238
|
+
let data = "";
|
|
15239
|
+
res.on("data", (chunk) => data += chunk);
|
|
15240
|
+
res.on("end", () => {
|
|
15241
|
+
if (res.statusCode === 200) {
|
|
15242
|
+
try {
|
|
15243
|
+
resolve(JSON.parse(data));
|
|
15244
|
+
} catch (e) {
|
|
15245
|
+
reject(new Error("Failed to parse GitHub response"));
|
|
15246
|
+
}
|
|
15247
|
+
} else if (res.statusCode === 404) {
|
|
15248
|
+
resolve([]);
|
|
15249
|
+
} else {
|
|
15250
|
+
reject(new Error(`GitHub API error: ${res.statusCode}`));
|
|
15251
|
+
}
|
|
15252
|
+
});
|
|
15253
|
+
}).on("error", reject);
|
|
15254
|
+
});
|
|
15255
|
+
}
|
|
15256
|
+
async function getLatestRelease() {
|
|
15257
|
+
const releases = await fetchReleases();
|
|
15258
|
+
return releases.length > 0 ? releases[0] : null;
|
|
15259
|
+
}
|
|
15260
|
+
async function downloadRelease(url, dest) {
|
|
15261
|
+
return new Promise((resolve, reject) => {
|
|
15262
|
+
const file = fs.createWriteStream(dest);
|
|
15263
|
+
const request = (downloadUrl) => {
|
|
15264
|
+
https.get(downloadUrl, {
|
|
15265
|
+
headers: {
|
|
15266
|
+
"User-Agent": "taiwan-invoice-skill-cli",
|
|
15267
|
+
"Accept": "application/octet-stream"
|
|
15268
|
+
}
|
|
15269
|
+
}, (res) => {
|
|
15270
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
15271
|
+
const redirectUrl = res.headers.location;
|
|
15272
|
+
if (redirectUrl) {
|
|
15273
|
+
request(redirectUrl);
|
|
15274
|
+
return;
|
|
15275
|
+
}
|
|
15276
|
+
}
|
|
15277
|
+
if (res.statusCode !== 200) {
|
|
15278
|
+
file.close();
|
|
15279
|
+
fs.unlinkSync(dest);
|
|
15280
|
+
reject(new Error(`Download failed: ${res.statusCode}`));
|
|
15281
|
+
return;
|
|
15282
|
+
}
|
|
15283
|
+
res.pipe(file);
|
|
15284
|
+
file.on("finish", () => {
|
|
15285
|
+
file.close();
|
|
15286
|
+
resolve();
|
|
15287
|
+
});
|
|
15288
|
+
}).on("error", (err) => {
|
|
15289
|
+
file.close();
|
|
15290
|
+
fs.unlinkSync(dest);
|
|
15291
|
+
reject(err);
|
|
15292
|
+
});
|
|
15293
|
+
};
|
|
15294
|
+
request(url);
|
|
15295
|
+
});
|
|
15296
|
+
}
|
|
15297
|
+
function getSourceZipUrl(release) {
|
|
15298
|
+
return `https://github.com/${REPO_OWNER}/${REPO_NAME}/archive/refs/tags/${release.tag_name}.zip`;
|
|
15299
|
+
}
|
|
15300
|
+
|
|
15301
|
+
// src/utils/extract.ts
|
|
15302
|
+
var fs2 = __toESM(require("fs"));
|
|
15303
|
+
var path = __toESM(require("path"));
|
|
15304
|
+
var import_child_process = require("child_process");
|
|
15305
|
+
async function extractZip(zipPath, destDir) {
|
|
15306
|
+
if (!fs2.existsSync(destDir)) {
|
|
15307
|
+
fs2.mkdirSync(destDir, { recursive: true });
|
|
15308
|
+
}
|
|
15309
|
+
const isWindows = process.platform === "win32";
|
|
15310
|
+
if (isWindows) {
|
|
15311
|
+
const psCommand = `Expand-Archive -Path "${zipPath}" -DestinationPath "${destDir}" -Force`;
|
|
15312
|
+
(0, import_child_process.execSync)(`powershell -Command "${psCommand}"`, { stdio: "pipe" });
|
|
15313
|
+
} else {
|
|
15314
|
+
(0, import_child_process.execSync)(`unzip -o "${zipPath}" -d "${destDir}"`, { stdio: "pipe" });
|
|
15315
|
+
}
|
|
15316
|
+
}
|
|
15317
|
+
async function copyFolders(sourceDir, targetDir, aiType) {
|
|
15318
|
+
const copiedFolders = [];
|
|
15319
|
+
const foldersToCheck = AI_FOLDERS[aiType];
|
|
15320
|
+
for (const folder of foldersToCheck) {
|
|
15321
|
+
const sourcePath = path.join(sourceDir, folder);
|
|
15322
|
+
const targetPath = path.join(targetDir, folder);
|
|
15323
|
+
if (fs2.existsSync(sourcePath)) {
|
|
15324
|
+
copyDirRecursive(sourcePath, targetPath);
|
|
15325
|
+
copiedFolders.push(folder);
|
|
15326
|
+
}
|
|
15327
|
+
}
|
|
15328
|
+
return copiedFolders;
|
|
15329
|
+
}
|
|
15330
|
+
function copyDirRecursive(src, dest) {
|
|
15331
|
+
if (!fs2.existsSync(dest)) {
|
|
15332
|
+
fs2.mkdirSync(dest, { recursive: true });
|
|
15333
|
+
}
|
|
15334
|
+
const entries = fs2.readdirSync(src, { withFileTypes: true });
|
|
15335
|
+
for (const entry of entries) {
|
|
15336
|
+
const srcPath = path.join(src, entry.name);
|
|
15337
|
+
const destPath = path.join(dest, entry.name);
|
|
15338
|
+
if (entry.isDirectory()) {
|
|
15339
|
+
copyDirRecursive(srcPath, destPath);
|
|
15340
|
+
} else {
|
|
15341
|
+
fs2.copyFileSync(srcPath, destPath);
|
|
15342
|
+
}
|
|
15343
|
+
}
|
|
15344
|
+
}
|
|
15345
|
+
function findExtractedFolder(destDir) {
|
|
15346
|
+
const entries = fs2.readdirSync(destDir, { withFileTypes: true });
|
|
15347
|
+
const dirs = entries.filter((e) => e.isDirectory());
|
|
15348
|
+
const releaseDir = dirs.find(
|
|
15349
|
+
(d) => d.name.includes("taiwan-invoice") || d.name.startsWith("taiwan-invoice")
|
|
15350
|
+
);
|
|
15351
|
+
return releaseDir ? path.join(destDir, releaseDir.name) : null;
|
|
15352
|
+
}
|
|
15353
|
+
async function installFromZip(zipPath, targetDir, aiType) {
|
|
15354
|
+
const tempDir = path.join(path.dirname(zipPath), "taiwan-invoice-extracted");
|
|
15355
|
+
if (fs2.existsSync(tempDir)) {
|
|
15356
|
+
fs2.rmSync(tempDir, { recursive: true, force: true });
|
|
15357
|
+
}
|
|
15358
|
+
await extractZip(zipPath, tempDir);
|
|
15359
|
+
const extractedDir = findExtractedFolder(tempDir) || tempDir;
|
|
15360
|
+
const copiedFolders = await copyFolders(extractedDir, targetDir, aiType);
|
|
15361
|
+
return { copiedFolders, tempDir };
|
|
15362
|
+
}
|
|
15363
|
+
function cleanup(tempDir, zipPath) {
|
|
15364
|
+
if (tempDir && fs2.existsSync(tempDir)) {
|
|
15365
|
+
fs2.rmSync(tempDir, { recursive: true, force: true });
|
|
15366
|
+
}
|
|
15367
|
+
if (zipPath && fs2.existsSync(zipPath)) {
|
|
15368
|
+
fs2.unlinkSync(zipPath);
|
|
15369
|
+
}
|
|
15370
|
+
}
|
|
15371
|
+
|
|
15197
15372
|
// src/commands/init.ts
|
|
15373
|
+
async function tryGitHubDownload(aiType, targetDir) {
|
|
15374
|
+
const spinner = (0, import_ora.default)("Checking for latest release on GitHub...").start();
|
|
15375
|
+
try {
|
|
15376
|
+
const release = await getLatestRelease();
|
|
15377
|
+
if (!release) {
|
|
15378
|
+
spinner.info("No releases found, using bundled assets");
|
|
15379
|
+
return { success: false, folders: [] };
|
|
15380
|
+
}
|
|
15381
|
+
spinner.text = `Found release: ${release.tag_name}`;
|
|
15382
|
+
const zipUrl = getSourceZipUrl(release);
|
|
15383
|
+
const tempDir = os.tmpdir();
|
|
15384
|
+
const zipPath = path2.join(tempDir, `taiwan-invoice-${release.tag_name}.zip`);
|
|
15385
|
+
spinner.text = "Downloading release...";
|
|
15386
|
+
await downloadRelease(zipUrl, zipPath);
|
|
15387
|
+
spinner.text = "Extracting and installing...";
|
|
15388
|
+
const { copiedFolders, tempDir: extractedDir } = await installFromZip(zipPath, targetDir, aiType);
|
|
15389
|
+
cleanup(extractedDir, zipPath);
|
|
15390
|
+
if (copiedFolders.length > 0) {
|
|
15391
|
+
spinner.succeed(`Installed from GitHub release ${release.tag_name}`);
|
|
15392
|
+
return { success: true, folders: copiedFolders };
|
|
15393
|
+
} else {
|
|
15394
|
+
spinner.info("No matching folders in release, using bundled assets");
|
|
15395
|
+
return { success: false, folders: [] };
|
|
15396
|
+
}
|
|
15397
|
+
} catch (error) {
|
|
15398
|
+
spinner.info("GitHub download failed, using bundled assets");
|
|
15399
|
+
return { success: false, folders: [] };
|
|
15400
|
+
}
|
|
15401
|
+
}
|
|
15198
15402
|
async function initCommand(options) {
|
|
15199
15403
|
logger.title("Taiwan Invoice Skill Installer");
|
|
15200
15404
|
let aiType = options.ai;
|
|
@@ -15220,16 +15424,26 @@ async function initCommand(options) {
|
|
|
15220
15424
|
aiType = response.aiType;
|
|
15221
15425
|
}
|
|
15222
15426
|
logger.info(`Installing for: ${import_chalk2.default.cyan(getAITypeDescription(aiType))}`);
|
|
15223
|
-
const spinner = (0, import_ora.default)("Generating skill files from templates...").start();
|
|
15224
15427
|
const cwd = process.cwd();
|
|
15225
15428
|
let copiedFolders = [];
|
|
15429
|
+
let usedGitHub = false;
|
|
15226
15430
|
try {
|
|
15227
|
-
if (aiType
|
|
15228
|
-
|
|
15229
|
-
|
|
15230
|
-
|
|
15431
|
+
if (!options.offline && aiType !== "all") {
|
|
15432
|
+
const result = await tryGitHubDownload(aiType, cwd);
|
|
15433
|
+
if (result.success) {
|
|
15434
|
+
copiedFolders = result.folders;
|
|
15435
|
+
usedGitHub = true;
|
|
15436
|
+
}
|
|
15437
|
+
}
|
|
15438
|
+
if (!usedGitHub) {
|
|
15439
|
+
const spinner = (0, import_ora.default)("Generating skill files from bundled templates...").start();
|
|
15440
|
+
if (aiType === "all") {
|
|
15441
|
+
copiedFolders = await generateAllPlatformFiles(cwd);
|
|
15442
|
+
} else {
|
|
15443
|
+
copiedFolders = await generatePlatformFiles(cwd, aiType);
|
|
15444
|
+
}
|
|
15445
|
+
spinner.succeed("Generated from bundled templates!");
|
|
15231
15446
|
}
|
|
15232
|
-
spinner.succeed("Generated from templates!");
|
|
15233
15447
|
console.log();
|
|
15234
15448
|
logger.info("Installed folders:");
|
|
15235
15449
|
copiedFolders.forEach((folder) => {
|
|
@@ -15243,7 +15457,7 @@ async function initCommand(options) {
|
|
|
15243
15457
|
console.log(import_chalk2.default.dim(' 2. Try: "Help me integrate ECPay invoice API"'));
|
|
15244
15458
|
console.log();
|
|
15245
15459
|
} catch (error) {
|
|
15246
|
-
|
|
15460
|
+
logger.error("Installation failed");
|
|
15247
15461
|
if (error instanceof Error) {
|
|
15248
15462
|
logger.error(error.message);
|
|
15249
15463
|
}
|
|
@@ -15318,21 +15532,11 @@ async function infoCommand() {
|
|
|
15318
15532
|
var import_chalk5 = __toESM(require_source());
|
|
15319
15533
|
var import_ora2 = __toESM(require_ora());
|
|
15320
15534
|
var VERSION2 = "2.0.0";
|
|
15321
|
-
var REPO_API = "https://api.github.com/repos/Moksa1123/taiwan-invoice/releases";
|
|
15322
15535
|
async function versionsCommand() {
|
|
15323
15536
|
logger.title("Taiwan Invoice Skill - Available Versions");
|
|
15324
15537
|
const spinner = (0, import_ora2.default)("Fetching releases from GitHub...").start();
|
|
15325
15538
|
try {
|
|
15326
|
-
const
|
|
15327
|
-
headers: {
|
|
15328
|
-
"Accept": "application/vnd.github.v3+json",
|
|
15329
|
-
"User-Agent": "taiwan-invoice-skill-cli"
|
|
15330
|
-
}
|
|
15331
|
-
});
|
|
15332
|
-
if (!response.ok) {
|
|
15333
|
-
throw new Error(`GitHub API error: ${response.status}`);
|
|
15334
|
-
}
|
|
15335
|
-
const releases = await response.json();
|
|
15539
|
+
const releases = await fetchReleases();
|
|
15336
15540
|
spinner.succeed("Fetched releases from GitHub");
|
|
15337
15541
|
console.log();
|
|
15338
15542
|
console.log(import_chalk5.default.cyan("Available Versions:"));
|
|
@@ -15413,7 +15617,8 @@ program2.command("init").description("Install Taiwan Invoice skill to current pr
|
|
|
15413
15617
|
await initCommand({
|
|
15414
15618
|
ai: options.ai,
|
|
15415
15619
|
force: options.force,
|
|
15416
|
-
global: options.global
|
|
15620
|
+
global: options.global,
|
|
15621
|
+
offline: options.offline
|
|
15417
15622
|
});
|
|
15418
15623
|
});
|
|
15419
15624
|
program2.command("list").description("List supported AI platforms").action(listCommand);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taiwan-invoice-skill",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "CLI to install Taiwan E-Invoice skill for AI coding assistants",
|
|
5
5
|
"bin": {
|
|
6
6
|
"taiwan-invoice": "./dist/index.js"
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"assets"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "node scripts/build.js"
|
|
13
|
+
"build": "node scripts/build.js",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
14
15
|
},
|
|
15
16
|
"keywords": [
|
|
16
17
|
"taiwan",
|