@xiashe/cli 0.1.8 → 0.1.10
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 +22 -2
- package/bin/xiashe.mjs +90 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,20 +17,40 @@ node packages/xiashe-cli/bin/xiashe.mjs login --email you@example.com --password
|
|
|
17
17
|
xiashe skills list
|
|
18
18
|
xiashe skills install copywriting --connection MaxClaw-1 --watch
|
|
19
19
|
xiashe agent issue --name "Local WorkBuddy"
|
|
20
|
-
xiashe agent connect --token "<token>" --name "Local WorkBuddy"
|
|
20
|
+
xiashe agent connect --token "<token>" --name "Local WorkBuddy" --transport npx
|
|
21
21
|
xiashe agent run --ack
|
|
22
22
|
xiashe chat send --chat "New Chat" --content "帮我处理这个文件" --file ./report.pdf --agent "Local WorkBuddy"
|
|
23
|
-
xiashe skills publish draft . --source xiashe
|
|
23
|
+
xiashe skills publish draft . --source xiashe
|
|
24
24
|
xiashe skills publish doctor "<submission-id>"
|
|
25
25
|
xiashe skills publish submit "<submission-id>"
|
|
26
|
+
xiashe payment doctor
|
|
27
|
+
# After the Agent shows the Skill and purpose and the user explicitly agrees:
|
|
28
|
+
xiashe payment pay --resource-url "https://<actions-site>/payment/alipay-ai-collect?orderId=<id>" --intent-summary "使用付费 Skill:<name>" --confirm
|
|
29
|
+
xiashe payment status --resource-url "https://<actions-site>/payment/alipay-ai-collect?orderId=<id>"
|
|
26
30
|
```
|
|
27
31
|
|
|
28
32
|
Local state is stored in `~/.xiashe/config.json`.
|
|
29
33
|
|
|
34
|
+
`skills publish draft` reads `.xiashe/xiashe.skill.json` when present. If the local CLI is not signed in, it can create or reuse the XiaShe Store draft with that registry public token; creator login is only required when the registry token is missing or rejected.
|
|
35
|
+
|
|
30
36
|
`xiashe agent run --ack` is the recommended lightweight receiver for shell-capable Agents. It sends cheap heartbeats and only lists/executes work when the backend reports pending tasks or transfers. Default cadence is about 30s while idle, 10s while work is active, and up to 2 minutes after long idle periods.
|
|
31
37
|
|
|
38
|
+
Supported transport labels are `a2a`, `mcp`, `http`, `npx`, `claw`, and `manual`. The label is advisory for routing and diagnostics; the runtime token, task lease, ack, and complete events remain the source of truth.
|
|
39
|
+
|
|
32
40
|
Production defaults:
|
|
33
41
|
|
|
34
42
|
- Convex: `https://api.xiashe.chat`
|
|
35
43
|
- Actions: `https://actions.xiashe.chat`
|
|
36
44
|
- Relay: `https://relay.xiashe.chat`
|
|
45
|
+
|
|
46
|
+
## Alipay AI Pay local bridge
|
|
47
|
+
|
|
48
|
+
`xiashe payment` is the shell-capable Agent path for Alipay AI Pay. It delegates only to the official local `alipay-bot` supplied by `@alipay/agent-payment`; it does not implement or expose `Payment-Needed` / `Payment-Proof` itself.
|
|
49
|
+
|
|
50
|
+
- `xiashe payment doctor` checks whether the local wallet is enabled.
|
|
51
|
+
- `xiashe payment pay` requires an HTTPS AI-Collect resource URL, a visible purchase-purpose summary, and `--confirm`. The command then waits for the user to approve in Alipay App.
|
|
52
|
+
- `xiashe payment status` returns a normalized status only. No wallet protocol payload or proof is printed.
|
|
53
|
+
|
|
54
|
+
An Agent must never add `--confirm` before the user has explicitly agreed to the displayed purpose. If the wallet is unavailable, obtain permission before running the official `@alipay/agent-payment` setup, then run `payment doctor` again.
|
|
55
|
+
|
|
56
|
+
For a clean Codex Task, the XiaShe MCP response provides a version-pinned ephemeral command such as `npx -y @xiashe/cli@0.1.10 payment doctor`. No global `xiashe` installation is required for that path.
|
package/bin/xiashe.mjs
CHANGED
|
@@ -34,7 +34,10 @@ const {
|
|
|
34
34
|
postJson,
|
|
35
35
|
mcpCall,
|
|
36
36
|
decodeMcpToolResult,
|
|
37
|
-
nowIso
|
|
37
|
+
nowIso,
|
|
38
|
+
checkAlipayWallet,
|
|
39
|
+
payAlipay402Resource,
|
|
40
|
+
queryAlipay402Resource
|
|
38
41
|
} = sdk;
|
|
39
42
|
|
|
40
43
|
const EXIT_USAGE = 2;
|
|
@@ -75,7 +78,7 @@ Usage:
|
|
|
75
78
|
${c} skills publish release <submission-id>
|
|
76
79
|
|
|
77
80
|
${c} agent issue [--name <name>] [--kind <kind>] [--json]
|
|
78
|
-
${c} agent connect --token <token> [--name <name>] [--kind <kind>] [--webhook-url <https-url>] [--webhook-token <secret>]
|
|
81
|
+
${c} agent connect --token <token> [--name <name>] [--kind <kind>] [--transport a2a|mcp|http|npx|claw|manual] [--webhook-url <https-url>] [--webhook-token <secret>]
|
|
79
82
|
${c} agent heartbeat [--webhook-url <https-url>] [--webhook-token <secret>|--disable-webhook]
|
|
80
83
|
${c} agent list
|
|
81
84
|
${c} agent revoke --agent <id-or-name>
|
|
@@ -92,6 +95,10 @@ Usage:
|
|
|
92
95
|
${c} files upload <path>
|
|
93
96
|
${c} files list
|
|
94
97
|
|
|
98
|
+
${c} payment doctor
|
|
99
|
+
${c} payment pay --resource-url <https-url> --intent-summary <text> --confirm
|
|
100
|
+
${c} payment status --resource-url <https-url>
|
|
101
|
+
|
|
95
102
|
${c} ops doctor
|
|
96
103
|
|
|
97
104
|
Global flags:
|
|
@@ -580,17 +587,47 @@ async function cmdSkillPublish(flags, client, global) {
|
|
|
580
587
|
if (action === 'draft' || action === 'create') {
|
|
581
588
|
const skillDir = flags._[1] && !String(flags._[1]).startsWith('--') ? flags._[1] : '.';
|
|
582
589
|
const draft = await inferPublishDraft(skillDir, flags, client);
|
|
590
|
+
const printableDraft = redactPublishDraft(draft);
|
|
583
591
|
const result = await client.createSkillSubmissionDraft(draft);
|
|
584
592
|
if (global.json) {
|
|
585
|
-
print({ ok: true, ...result, draft }, global);
|
|
593
|
+
print({ ok: true, ...result, draft: printableDraft }, global);
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
if (result.reused) {
|
|
597
|
+
print(
|
|
598
|
+
[
|
|
599
|
+
`Reused existing Skill submission: ${result.submissionId}`,
|
|
600
|
+
`Status: ${result.status || 'existing'}`,
|
|
601
|
+
`Name: ${printableDraft.name}`,
|
|
602
|
+
`Registry: ${printableDraft.registryPublicSkillId || printableDraft.registryEntryId || 'attached'}`,
|
|
603
|
+
'',
|
|
604
|
+
'Duplicate XiaShe Store upload was skipped. Continue with registry/runtime verification and external platform preparation.'
|
|
605
|
+
].join('\n'),
|
|
606
|
+
global
|
|
607
|
+
);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
if (result.searchable || result.skillCatalogId) {
|
|
611
|
+
print(
|
|
612
|
+
[
|
|
613
|
+
`Published searchable Skill listing: ${result.skillCatalogId || result.submissionId}`,
|
|
614
|
+
`Submission: ${result.submissionId}`,
|
|
615
|
+
`Name: ${printableDraft.name}`,
|
|
616
|
+
`Market: ${printableDraft.market}`,
|
|
617
|
+
`Source fingerprint: ${printableDraft.packageSha256 || 'not attached'}`,
|
|
618
|
+
'',
|
|
619
|
+
'No extra creator login is required. Continue with Red Skill upload and Agent Ack verification.'
|
|
620
|
+
].join('\n'),
|
|
621
|
+
global
|
|
622
|
+
);
|
|
586
623
|
return;
|
|
587
624
|
}
|
|
588
625
|
print(
|
|
589
626
|
[
|
|
590
627
|
`Created Skill submission draft: ${result.submissionId}`,
|
|
591
|
-
`Name: ${
|
|
592
|
-
`Market: ${
|
|
593
|
-
`Source fingerprint: ${
|
|
628
|
+
`Name: ${printableDraft.name}`,
|
|
629
|
+
`Market: ${printableDraft.market}`,
|
|
630
|
+
`Source fingerprint: ${printableDraft.packageSha256}`,
|
|
594
631
|
'',
|
|
595
632
|
`Next: ${COMMAND_NAME} skills publish doctor ${result.submissionId}`,
|
|
596
633
|
`Then: ${COMMAND_NAME} skills publish submit ${result.submissionId}`
|
|
@@ -620,7 +657,12 @@ async function cmdSkillPublish(flags, client, global) {
|
|
|
620
657
|
print(result, global);
|
|
621
658
|
return;
|
|
622
659
|
}
|
|
623
|
-
print(
|
|
660
|
+
print(
|
|
661
|
+
result.searchable
|
|
662
|
+
? `Published searchable Skill listing: ${result.skillCatalogId || submissionId}`
|
|
663
|
+
: `Submitted Skill for review: ${submissionId}`,
|
|
664
|
+
global
|
|
665
|
+
);
|
|
624
666
|
return;
|
|
625
667
|
}
|
|
626
668
|
if (action === 'admin-list') {
|
|
@@ -660,6 +702,13 @@ async function cmdSkillPublish(flags, client, global) {
|
|
|
660
702
|
fail(`Unknown skills publish command: ${action}`, EXIT_USAGE);
|
|
661
703
|
}
|
|
662
704
|
|
|
705
|
+
function redactPublishDraft(draft) {
|
|
706
|
+
const clean = { ...draft };
|
|
707
|
+
delete clean._registryPublicToken;
|
|
708
|
+
delete clean.registryPublicToken;
|
|
709
|
+
return clean;
|
|
710
|
+
}
|
|
711
|
+
|
|
663
712
|
async function watchSkillJob(client, connectionId, jobId, global) {
|
|
664
713
|
const deadline = Date.now() + Number(global.watchTimeoutMs || 180_000);
|
|
665
714
|
let latest = null;
|
|
@@ -1092,6 +1141,33 @@ async function cmdFiles(sub, args, global) {
|
|
|
1092
1141
|
fail(`Unknown files command: ${sub}`, EXIT_USAGE);
|
|
1093
1142
|
}
|
|
1094
1143
|
|
|
1144
|
+
async function cmdPayment(sub, args, global) {
|
|
1145
|
+
const flags = parseFlags(args);
|
|
1146
|
+
if (sub === 'doctor' || sub === 'wallet' || sub === 'wallet-status') {
|
|
1147
|
+
const result = await checkAlipayWallet({ timeoutMs: global.timeoutMs });
|
|
1148
|
+
print(result, global);
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
if (sub === 'pay') {
|
|
1152
|
+
const resourceUrl = requireArg(flags['resource-url'] || flags.resourceUrl || flags.r, '--resource-url');
|
|
1153
|
+
const intentSummary = requireArg(flags['intent-summary'] || flags.intentSummary || flags.i, '--intent-summary');
|
|
1154
|
+
const result = await payAlipay402Resource({
|
|
1155
|
+
resourceUrl,
|
|
1156
|
+
intentSummary,
|
|
1157
|
+
confirm: flags.confirm === true
|
|
1158
|
+
}, { timeoutMs: global.timeoutMs });
|
|
1159
|
+
print(result, global);
|
|
1160
|
+
return;
|
|
1161
|
+
}
|
|
1162
|
+
if (sub === 'status') {
|
|
1163
|
+
const resourceUrl = requireArg(flags['resource-url'] || flags.resourceUrl || flags.r, '--resource-url');
|
|
1164
|
+
const result = await queryAlipay402Resource({ resourceUrl }, { timeoutMs: global.timeoutMs });
|
|
1165
|
+
print(result, global);
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
fail(`Usage: ${COMMAND_NAME} payment doctor|pay|status`, EXIT_USAGE);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1095
1171
|
async function cmdOps(sub, args, global) {
|
|
1096
1172
|
const flags = parseFlags(args);
|
|
1097
1173
|
const { client } = await makeClient(global);
|
|
@@ -1221,6 +1297,10 @@ async function inferPublishDraft(skillDir, flags, client) {
|
|
|
1221
1297
|
const packageJson = await readJson(path.join(root, 'package.json'));
|
|
1222
1298
|
const skillMd = await readSmallText(path.join(root, 'SKILL.md'));
|
|
1223
1299
|
const readme = await readSmallText(path.join(root, 'README.md'));
|
|
1300
|
+
const registryManifest =
|
|
1301
|
+
await readJson(path.join(root, '.xiashe', 'xiashe.skill.json')) ||
|
|
1302
|
+
await readJson(path.join(root, 'xiashe.skill.json'));
|
|
1303
|
+
const registry = registryManifest?.registry || {};
|
|
1224
1304
|
const text = `${skillMd}\n\n${readme}`;
|
|
1225
1305
|
const digest = await hashPublishDirectory(root);
|
|
1226
1306
|
const name = flags.name || packageJson?.name || firstHeading(text) || path.basename(root);
|
|
@@ -1251,7 +1331,8 @@ async function inferPublishDraft(skillDir, flags, client) {
|
|
|
1251
1331
|
category: flags.category || undefined,
|
|
1252
1332
|
tags: parseCsv(flags.tags),
|
|
1253
1333
|
registryEntryId: flags['registry-entry'] || flags.registryEntryId || undefined,
|
|
1254
|
-
registryPublicSkillId: flags['registry-public-skill-id'] || flags.registryPublicSkillId || undefined,
|
|
1334
|
+
registryPublicSkillId: flags['registry-public-skill-id'] || flags.registryPublicSkillId || registry.skillId || undefined,
|
|
1335
|
+
_registryPublicToken: flags['registry-public-token'] || flags.registryPublicToken || registry.publicToken || undefined,
|
|
1255
1336
|
packageSha256: digest.sha256
|
|
1256
1337
|
};
|
|
1257
1338
|
}
|
|
@@ -1301,6 +1382,7 @@ async function main() {
|
|
|
1301
1382
|
if (command === 'agent' || command === 'agents') return await cmdAgent(sub, args, global);
|
|
1302
1383
|
if (command === 'chat' || command === 'chats') return await cmdChat(sub, args, global);
|
|
1303
1384
|
if (command === 'files' || command === 'file') return await cmdFiles(sub, args, global);
|
|
1385
|
+
if (command === 'payment' || command === 'payments') return await cmdPayment(sub, args, global);
|
|
1304
1386
|
if (command === 'ops') return await cmdOps(sub, args, global);
|
|
1305
1387
|
fail(`Unknown command: ${command}\n\n${usage()}`, EXIT_USAGE);
|
|
1306
1388
|
} catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiashe/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"xiashe": "bin/xiashe.mjs"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"README.md"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@xiashe/sdk": "0.1.
|
|
13
|
+
"@xiashe/sdk": "0.1.10"
|
|
14
14
|
},
|
|
15
15
|
"engines": {
|
|
16
16
|
"node": ">=20"
|