@xiashe/skill 0.1.20 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/xiashe-skill.mjs +153 -32
  2. package/package.json +1 -1
@@ -1,19 +1,97 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { createHash, createHmac } from 'node:crypto';
4
- import { existsSync } from 'node:fs';
4
+ import { existsSync, readFileSync } from 'node:fs';
5
5
  import { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';
6
6
  import os from 'node:os';
7
7
  import path from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
8
9
  import { promisify } from 'node:util';
9
10
  import { gzip } from 'node:zlib';
10
11
 
11
- const VERSION = '0.1.20';
12
+ function parseEnvFile(filePath) {
13
+ if (!existsSync(filePath)) return {};
14
+ const parsed = {};
15
+ const raw = readFileSync(filePath, 'utf8');
16
+ for (const line of raw.split(/\r?\n/)) {
17
+ const trimmed = line.trim();
18
+ if (!trimmed || trimmed.startsWith('#')) continue;
19
+ const match = trimmed.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
20
+ if (!match) continue;
21
+ let value = match[2].trim();
22
+ if (
23
+ (value.startsWith('"') && value.endsWith('"')) ||
24
+ (value.startsWith("'") && value.endsWith("'"))
25
+ ) {
26
+ value = value.slice(1, -1);
27
+ }
28
+ parsed[match[1]] = value;
29
+ }
30
+ return parsed;
31
+ }
32
+
33
+ function nearestEnvFiles() {
34
+ const files = [];
35
+ let cursor = process.cwd();
36
+ for (let index = 0; index < 8; index += 1) {
37
+ files.push(path.join(cursor, '.env.local'));
38
+ files.push(path.join(cursor, 'convex', '.env.local'));
39
+ const next = path.dirname(cursor);
40
+ if (next === cursor) break;
41
+ cursor = next;
42
+ }
43
+ return files;
44
+ }
45
+
46
+ function loadLocalEnvDefaults() {
47
+ const cliDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
48
+ const candidates = [
49
+ path.join(cliDir, '.env.local'),
50
+ path.join(cliDir, 'convex', '.env.local'),
51
+ ...nearestEnvFiles()
52
+ ];
53
+ const env = {};
54
+ for (const filePath of candidates) {
55
+ Object.assign(env, parseEnvFile(filePath));
56
+ }
57
+ return env;
58
+ }
59
+
60
+ function normalizeBaseUrl(value) {
61
+ const text = String(value || '').trim().replace(/\/+$/, '');
62
+ return /^https?:\/\//i.test(text) ? text : '';
63
+ }
64
+
65
+ function isTransportError(error) {
66
+ const message = error instanceof Error ? `${error.name || ''} ${error.message || ''}` : String(error || '');
67
+ return /abort|timeout|fetch failed|network|enotfound|eai_again|econnrefused|econnreset|etimedout|unable to verify|certificate/i.test(message);
68
+ }
69
+
70
+ const LOCAL_ENV_DEFAULTS = loadLocalEnvDefaults();
71
+ const VERSION = process.env.XIASHE_SKILL_CLI_VERSION || '0.1.22';
12
72
  const COMMAND_NAME = process.env.XIASHE_SKILL_CLI_NAME || 'xiashe-skill';
13
73
  const PRODUCT_NAME = process.env.XIASHE_SKILL_PRODUCT_NAME || (COMMAND_NAME === 'agentpie-skill' ? 'AgentPie' : 'XiaShe');
14
74
  const REGISTRY_PROVIDER = process.env.XIASHE_SKILL_REGISTRY_PROVIDER || (COMMAND_NAME === 'agentpie-skill' ? 'agentpie' : 'xiashe');
75
+ const LOCAL_AGENTPIE_BASE_URL = normalizeBaseUrl(
76
+ process.env.AGENTPIE_SKILL_DEFAULT_BASE_URL ||
77
+ LOCAL_ENV_DEFAULTS.AGENTPIE_SKILL_DEFAULT_BASE_URL ||
78
+ process.env.AGENTPIE_SKILL_REGISTRY_PUBLIC_URL ||
79
+ LOCAL_ENV_DEFAULTS.AGENTPIE_SKILL_REGISTRY_PUBLIC_URL ||
80
+ process.env.AGENTPIE_ACTIONS_URL ||
81
+ LOCAL_ENV_DEFAULTS.AGENTPIE_ACTIONS_URL ||
82
+ process.env.CREATOR_SKILL_REGISTRY_PUBLIC_URL ||
83
+ LOCAL_ENV_DEFAULTS.CREATOR_SKILL_REGISTRY_PUBLIC_URL ||
84
+ process.env.AGENTPIE_MCP_PUBLIC_URL ||
85
+ LOCAL_ENV_DEFAULTS.AGENTPIE_MCP_PUBLIC_URL ||
86
+ process.env.PUBLIC_CONVEX_SITE_URL ||
87
+ LOCAL_ENV_DEFAULTS.PUBLIC_CONVEX_SITE_URL ||
88
+ process.env.CONVEX_SITE_URL ||
89
+ LOCAL_ENV_DEFAULTS.CONVEX_SITE_URL ||
90
+ process.env.EXPO_PUBLIC_CONVEX_SITE_URL ||
91
+ LOCAL_ENV_DEFAULTS.EXPO_PUBLIC_CONVEX_SITE_URL
92
+ );
15
93
  const DEFAULT_BASE_URL = process.env.XIASHE_SKILL_DEFAULT_BASE_URL || (COMMAND_NAME === 'agentpie-skill'
16
- ? 'https://actions.agentpie.app'
94
+ ? LOCAL_AGENTPIE_BASE_URL || 'https://agentpie.app'
17
95
  : 'https://actions.xiashe.chat');
18
96
  const MANIFEST_FILE = process.env.XIASHE_SKILL_MANIFEST_FILE || (COMMAND_NAME === 'agentpie-skill'
19
97
  ? 'agentpie.skill.json'
@@ -32,10 +110,11 @@ const EVENT_SCHEMA_VERSION = process.env.XIASHE_SKILL_EVENT_SCHEMA_VERSION || (R
32
110
  const RUNTIME_SCHEMA_VERSION = process.env.XIASHE_SKILL_RUNTIME_SCHEMA_VERSION || (REGISTRY_PROVIDER === 'agentpie'
33
111
  ? 'agentpie.skill.runtime.v1'
34
112
  : 'xiashe.skill.runtime.v1');
35
- const SUPPORTED_HUBS = ['xiashe', 'red', 'clawhub', 'skillhub', 'claude', 'codex', 'cursor', 'workbuddy', 'dify', 'coze', 'generic'];
36
- const DEFAULT_SETUP_HUBS = ['xiashe', 'red'];
113
+ const FIRST_PARTY_HUB = REGISTRY_PROVIDER === 'agentpie' ? 'agentpie' : 'xiashe';
114
+ const SUPPORTED_HUBS = ['agentpie', 'xiashe', 'red', 'clawhub', 'skillhub', 'claude', 'codex', 'cursor', 'workbuddy', 'dify', 'coze', 'generic'];
115
+ const DEFAULT_SETUP_HUBS = [FIRST_PARTY_HUB, 'red'];
37
116
  const ACK_EVENTS = ['installed', 'used', 'completed', 'failed'];
38
- const RUNTIME_DISTRIBUTION_PLATFORMS = ['xiaohongshu-redskill', 'xiashe', 'coze-store', 'local', 'unknown'];
117
+ const RUNTIME_DISTRIBUTION_PLATFORMS = ['xiaohongshu-redskill', 'agentpie', 'xiashe', 'coze-store', 'local', 'unknown'];
39
118
  const RUNTIME_AGENTS = ['codex', 'workbuddy', 'coze', 'claude', 'cursor', 'dify', 'custom-agent', 'unknown'];
40
119
  const RUNTIME_HOSTS = ['codex-desktop', 'coze-app', 'web-chat', 'desktop', 'web', 'server', 'mobile', 'unknown'];
41
120
  const RUNTIME_SOURCE_SURFACES = ['install', 'first-use-backfill', 'chat-use', 'manual-test', 'creator-card', 'dashboard', 'unknown'];
@@ -79,6 +158,16 @@ const FORBIDDEN_ACK_FIELDS = [
79
158
  'privateResearchMaterial'
80
159
  ];
81
160
  const PLATFORM_REVIEW_PROFILES = {
161
+ agentpie: {
162
+ label: 'AgentPie Registry',
163
+ packageMode: 'full_skill_package',
164
+ manifestPolicy: 'upload_allowed',
165
+ disclosurePlacement: ['Skill public page', 'README', `${WORK_DIR}/REGISTRY_DISCLOSURE.md`],
166
+ runtimeDataPolicy: 'runtime_capable',
167
+ defaultDataSource: 'runtime',
168
+ allowedFilePolicy: 'Upload the complete reviewed Skill package, including the local registry manifest.',
169
+ forbiddenPublicFiles: ['.env', 'credentials', 'node_modules', 'dist', 'build', 'browser profiles', 'SSH keys']
170
+ },
82
171
  xiashe: {
83
172
  label: 'XiaShe Store',
84
173
  packageMode: 'full_skill_package',
@@ -224,14 +313,14 @@ function usage() {
224
313
 
225
314
  Usage:
226
315
  ${COMMAND_NAME} inspect [skill-dir] [--json]
227
- ${COMMAND_NAME} publish [skill-dir] --code <dynamic-code> [--to xiashe,red]
228
- ${COMMAND_NAME} setup [skill-dir] --code <dynamic-code> [--hub all|xiashe|red]
229
- ${COMMAND_NAME} setup [skill-dir] --public-token <token> --skill-id <id> [--hub all|xiashe|red]
316
+ ${COMMAND_NAME} publish [skill-dir] --code <dynamic-code> [--to ${FIRST_PARTY_HUB},red]
317
+ ${COMMAND_NAME} setup [skill-dir] --code <dynamic-code> [--hub all|${FIRST_PARTY_HUB}|red]
318
+ ${COMMAND_NAME} setup [skill-dir] --public-token <token> --skill-id <id> [--hub all|${FIRST_PARTY_HUB}|red]
230
319
  ${COMMAND_NAME} doctor [skill-dir] [--json]
231
320
  ${COMMAND_NAME} verify [skill-dir] [--hub <hub>] [--scenario <label>] [--dry-run]
232
321
  ${COMMAND_NAME} attach [skill-dir] --code <dynamic-code> [--name <name>]
233
322
  ${COMMAND_NAME} attach [skill-dir] --public-token <token> [--skill-id <id>] [--name <name>]
234
- ${COMMAND_NAME} prompt [skill-dir] --hub <xiashe|red> [--source-url <url>] [--out <file>]
323
+ ${COMMAND_NAME} prompt [skill-dir] --hub <${FIRST_PARTY_HUB}|red> [--source-url <url>] [--out <file>]
235
324
  ${COMMAND_NAME} snippet [skill-dir] [--target js|curl] [--out <file>]
236
325
  ${COMMAND_NAME} track [skill-dir] --event <event> [--hub <hub>] [--installation-id <id>] [--invocation-id <id>]
237
326
 
@@ -244,7 +333,7 @@ Options:
244
333
  --agent-ack-url <url> No-secret Agent Ack endpoint written to the local manifest.
245
334
  --name <name> Skill display name override.
246
335
  --description <text> Skill description override.
247
- --hub <hub> Target Skill hub prompt style. setup defaults to xiashe,red.
336
+ --hub <hub> Target Skill hub prompt style. setup defaults to ${DEFAULT_SETUP_HUBS.join(',')}.
248
337
  --to <hub[,hub]> High-level publish targets. Alias for --hub in publish mode.
249
338
  --event <event> Runtime event to submit for testing.
250
339
  --installation-id <id> Stable anonymous install id for runtime analytics.
@@ -266,11 +355,12 @@ Options:
266
355
  --signing-secret <secret> Optional HMAC secret for signed runtime events.
267
356
  --source-url <url> User-provided source URL an Agent can use during third-party upload.
268
357
  --package-url <url> Deprecated alias for --source-url.
358
+ --skill-version <version> Override the Skill release version without editing package.json.
269
359
  --package-upload-url <url> Package upload ticket endpoint. Defaults to ${DEFAULT_PACKAGE_UPLOAD_URL}
270
360
  --package-artifact-url <url> Package artifact attach endpoint. Defaults to ${DEFAULT_PACKAGE_ARTIFACT_URL}
271
361
  --out <path> Output prompt or snippet file.
272
362
  --out-dir <path> Output directory for setup artifacts. Defaults to ${WORK_DIR}/.
273
- --no-xiashe-package-upload Skip automatic ${PRODUCT_NAME} complete package upload.
363
+ --no-package-upload Skip automatic ${PRODUCT_NAME} complete package upload.
274
364
  --embed-skill-md Also write a clearly marked registry section into SKILL.md.
275
365
  --no-skill-md Do not write registry text into SKILL.md. Red hub embeds by default.
276
366
  --no-snippet Setup should skip writing the runtime analytics snippet.
@@ -289,7 +379,7 @@ function fail(message, code = 1) {
289
379
 
290
380
  function parseArgs(argv) {
291
381
  const args = { _: [], json: false, dryRun: false };
292
- const booleanFlags = new Set(['embed-skill-md', 'no-skill-md', 'no-snippet', 'no-track', 'no-xiashe-package-upload']);
382
+ const booleanFlags = new Set(['embed-skill-md', 'no-skill-md', 'no-snippet', 'no-track', 'no-package-upload', 'no-xiashe-package-upload']);
293
383
  for (let i = 0; i < argv.length; i += 1) {
294
384
  const value = argv[i];
295
385
  if (value === '--help' || value === '-h') {
@@ -486,6 +576,9 @@ function normalizeHub(value) {
486
576
  if (hub === 'xiashechat' || hub === 'xia-she' || hub === 'xiashe-store') {
487
577
  return 'xiashe';
488
578
  }
579
+ if (hub === 'agent-pie' || hub === 'agentpieapp' || hub === 'agentpie-registry' || hub === 'agentpieregistry') {
580
+ return 'agentpie';
581
+ }
489
582
  if (hub === 'claudecode' || hub === 'claude-code') {
490
583
  return 'claude';
491
584
  }
@@ -676,7 +769,7 @@ async function inferSkillMetadata(root, flags = {}) {
676
769
  name,
677
770
  skillKey: safeSkillKey(flags['skill-key'] || manifest?.skillKey || packageJson?.name || name),
678
771
  description: normalizeText(flags.description || manifest?.description || packageJson?.description || firstParagraph || '', 500),
679
- version: normalizeText(flags.version || manifest?.version || packageJson?.version || '0.1.0', 80),
772
+ version: normalizeText(flags['skill-version'] || packageJson?.version || manifest?.version || '0.1.0', 80),
680
773
  registry: manifest?.registry || null
681
774
  };
682
775
  }
@@ -741,6 +834,12 @@ async function postJson(url, body, timeoutMs = 20_000) {
741
834
  throw new Error(payload.error || payload.message || `HTTP ${response.status}`);
742
835
  }
743
836
  return payload;
837
+ } catch (error) {
838
+ const message = error instanceof Error ? error.message : String(error || 'unknown error');
839
+ if (!isTransportError(error)) {
840
+ throw error;
841
+ }
842
+ throw new Error(`Network request failed for ${url}: ${message}`);
744
843
  } finally {
745
844
  clearTimeout(timer);
746
845
  }
@@ -895,10 +994,10 @@ async function buildXiashePackageArtifact(root, inspected, flags = {}) {
895
994
  const skillMarkdownPresent = files.some((file) => /^SKILL(\.[a-z0-9]+)?$/i.test(file.relative));
896
995
  const manifestPresent = files.some((file) => file.relative === manifestRelative);
897
996
  if (!skillMarkdownPresent) {
898
- throw new Error('SKILL.md is required before uploading the XiaShe complete package.');
997
+ throw new Error(`SKILL.md is required before uploading the ${PRODUCT_NAME} complete package.`);
899
998
  }
900
999
  if (!manifestPresent) {
901
- throw new Error(`${manifestRelative} is required before uploading the XiaShe complete package.`);
1000
+ throw new Error(`${manifestRelative} is required before uploading the ${PRODUCT_NAME} complete package.`);
902
1001
  }
903
1002
  const artifact = await createTarGz(files);
904
1003
  const artifactDir = path.resolve(flags['package-out-dir'] || path.join(absoluteRoot, WORK_DIR, 'package-artifact'));
@@ -946,13 +1045,19 @@ async function uploadBytesToStorage(uploadUrl, bytes, contentType, timeoutMs = 6
946
1045
  throw new Error('Upload response did not include storageId.');
947
1046
  }
948
1047
  return { ...payload, storageId };
1048
+ } catch (error) {
1049
+ const message = error instanceof Error ? error.message : String(error || 'unknown error');
1050
+ if (!isTransportError(error)) {
1051
+ throw error;
1052
+ }
1053
+ throw new Error(`Package upload failed for ${uploadUrl}: ${message}`);
949
1054
  } finally {
950
1055
  clearTimeout(timer);
951
1056
  }
952
1057
  }
953
1058
 
954
1059
  async function uploadXiashePackageArtifact(root, flags, manifestResult) {
955
- if (flags.dryRun || flags['no-xiashe-package-upload']) {
1060
+ if (flags.dryRun || flags['no-package-upload'] || flags['no-xiashe-package-upload']) {
956
1061
  return {
957
1062
  ok: true,
958
1063
  skipped: true,
@@ -963,7 +1068,7 @@ async function uploadXiashePackageArtifact(root, flags, manifestResult) {
963
1068
  const registry = manifestResult.manifest?.registry || inspected.registry || {};
964
1069
  const publicToken = normalizeText(registry.publicToken, 512);
965
1070
  if (!publicToken) {
966
- throw new Error('Cannot upload XiaShe package without registry publicToken.');
1071
+ throw new Error(`Cannot upload ${PRODUCT_NAME} package without registry publicToken.`);
967
1072
  }
968
1073
  const artifact = await buildXiashePackageArtifact(root, inspected, flags);
969
1074
  const registrySourceSha256 =
@@ -1003,7 +1108,7 @@ async function uploadXiashePackageArtifact(root, flags, manifestResult) {
1003
1108
  manifestPresent: artifact.manifestPresent,
1004
1109
  skillMarkdownPresent: artifact.skillMarkdownPresent,
1005
1110
  creatorCardUrl: normalizeText(registry.creatorCardUrl, 800) || undefined,
1006
- platformSource: 'xiashe',
1111
+ platformSource: REGISTRY_PROVIDER,
1007
1112
  source: `${REGISTRY_PROVIDER}_skill_cli`
1008
1113
  },
1009
1114
  Number(flags['timeout-ms'] || 20_000)
@@ -1182,6 +1287,9 @@ async function writeManifest(root, flags) {
1182
1287
  }
1183
1288
 
1184
1289
  function hubInstruction(hub) {
1290
+ if (hub === 'agentpie') {
1291
+ return 'AgentPie Registry publish is the full Skill package and registry manifest flow. Keep public disclosure, attribution, and runtime analytics callbacks; if the local manifest has a registry public token or a creator-authenticated CLI/API session exists, create or reuse the AgentPie registry draft.';
1292
+ }
1185
1293
  if (hub === 'xiashe') {
1186
1294
  return '虾舍商店发布是完整 Skill 包和 registry manifest 的主流程。请保留公开披露、归因和 runtime analytics 回传能力;如果本地 manifest 有 registry public token 或已有创作者认证 CLI/API 会话,就创建或复用虾舍商店草稿。';
1187
1295
  }
@@ -1216,6 +1324,9 @@ function hubInstruction(hub) {
1216
1324
  }
1217
1325
 
1218
1326
  function platformPromptPlaceholder(hub) {
1327
+ if (hub === 'agentpie') {
1328
+ return 'If the user is publishing to AgentPie Registry and the current environment has a creator-authenticated CLI/API session, create the AgentPie registry draft first; otherwise finish registry setup, disclosure, platform profile, and handoff files. Do not apply third-party marketplace limits to the AgentPie complete Skill package.';
1329
+ }
1219
1330
  if (hub === 'xiashe') {
1220
1331
  return '如果用户要发布到虾舍商店,并且当前环境已有创作者认证 CLI/API 会话,请优先创建虾舍商店草稿;如果没有认证会话,请完成 registry setup、披露、平台 profile 和 handoff 文件,不要要求 Agent 宿主登录或索取账号凭证。不要把第三方平台限制套用到虾舍完整 Skill 包。';
1221
1332
  }
@@ -1251,6 +1362,14 @@ function platformPromptPlaceholder(hub) {
1251
1362
 
1252
1363
  function uploadCompatibilityLines(hub, manifestFile) {
1253
1364
  const localManifest = `${WORK_DIR}/${manifestFile}`;
1365
+ if (hub === 'agentpie') {
1366
+ return [
1367
+ 'AgentPie Registry compatibility requirements:',
1368
+ `- AgentPie Registry can receive the complete Skill package and ${localManifest} registry manifest.`,
1369
+ '- Keep public disclosure text, attribution links, and runtime event callbacks; do not remove the registry manifest.',
1370
+ '- Before submitting a draft, still exclude .env, keys, node_modules, dist/build, and unrelated local files.'
1371
+ ];
1372
+ }
1254
1373
  if (hub === 'xiashe') {
1255
1374
  return [
1256
1375
  '虾舍商店兼容性要求:',
@@ -1541,6 +1660,7 @@ function yamlStringList(values, indent = 6) {
1541
1660
  function runtimeDistributionPlatformForHub(hub) {
1542
1661
  const normalized = normalizeHub(hub) || 'unknown';
1543
1662
  if (normalized === 'red') return 'xiaohongshu-redskill';
1663
+ if (normalized === 'agentpie') return 'agentpie';
1544
1664
  if (normalized === 'xiashe') return 'xiashe';
1545
1665
  if (normalized === 'coze') return 'coze-store';
1546
1666
  if (normalized === 'codex' || normalized === 'claude' || normalized === 'cursor' || normalized === 'workbuddy') return 'local';
@@ -2649,12 +2769,13 @@ async function setupAgentWorkflow(root, flags) {
2649
2769
  promptResults,
2650
2770
  packagePlans
2651
2771
  });
2652
- const xiashePackageArtifact = hubs.includes('xiashe') && REGISTRY_PROVIDER === 'xiashe'
2772
+ const firstPartyPackageHubSelected = hubs.includes(FIRST_PARTY_HUB);
2773
+ const firstPartyPackageArtifact = firstPartyPackageHubSelected && (REGISTRY_PROVIDER === 'xiashe' || REGISTRY_PROVIDER === 'agentpie')
2653
2774
  ? await uploadXiashePackageArtifact(absoluteRoot, flags, manifestResult)
2654
2775
  : {
2655
2776
  ok: true,
2656
2777
  skipped: true,
2657
- reason: hubs.includes('xiashe') ? 'non_xiashe_provider' : 'xiashe_not_selected'
2778
+ reason: firstPartyPackageHubSelected ? 'unsupported_registry_provider' : 'first_party_registry_not_selected'
2658
2779
  };
2659
2780
 
2660
2781
  const warnings = [];
@@ -2690,14 +2811,14 @@ async function setupAgentWorkflow(root, flags) {
2690
2811
  agentAckPath,
2691
2812
  disclosurePath,
2692
2813
  snippetPath: snippetResult ? snippetResult.outPath : null,
2693
- xiashePackageArtifact,
2814
+ firstPartyPackageArtifact,
2694
2815
  promptEvents,
2695
2816
  warnings,
2696
2817
  publicProtocol,
2697
2818
  next: [
2698
- xiashePackageArtifact?.skipped
2699
- ? `XiaShe complete package upload was skipped (${xiashePackageArtifact.reason}).`
2700
- : `XiaShe complete package uploaded: ${path.relative(absoluteRoot, xiashePackageArtifact.artifactPath)} (${xiashePackageArtifact.publishStatus || 'queued'}).`,
2819
+ firstPartyPackageArtifact?.skipped
2820
+ ? `${PRODUCT_NAME} complete package upload was skipped (${firstPartyPackageArtifact.reason}).`
2821
+ : `${PRODUCT_NAME} complete package uploaded: ${path.relative(absoluteRoot, firstPartyPackageArtifact.artifactPath)} (${firstPartyPackageArtifact.publishStatus || 'queued'}).`,
2701
2822
  `Use ${path.relative(absoluteRoot, handoffPath)} as the single Agent handoff. The Agent should not ask the user to manually pick registry files.`,
2702
2823
  `Use ${path.relative(absoluteRoot, profilesPath)} and package-<hub>.json as the platform review profiles and upload allowlists.`,
2703
2824
  publicProtocol
@@ -2755,7 +2876,7 @@ async function main() {
2755
2876
  if (command === 'publish') {
2756
2877
  const result = await setupAgentWorkflow(root, flags);
2757
2878
  if (flags.json) {
2758
- print({ ok: true, mode: 'xiashe-publish', ...result }, true);
2879
+ print({ ok: true, mode: `${REGISTRY_PROVIDER}-publish`, ...result }, true);
2759
2880
  } else {
2760
2881
  const lines = [
2761
2882
  `${PRODUCT_NAME} publish handoff prepared.`,
@@ -2766,8 +2887,8 @@ async function main() {
2766
2887
  ...result.packagePlanPaths.map((item) => `Package plan (${item.hub}): ${item.planPath}`),
2767
2888
  result.skillMdPath ? `Updated: ${result.skillMdPath}` : null,
2768
2889
  result.publicProtocol ? `Public Red protocol: ${result.publicProtocol.runtimePath}, ${result.publicProtocol.agentAckPath}, ${result.publicProtocol.disclosurePath}` : null,
2769
- result.xiashePackageArtifact && !result.xiashePackageArtifact.skipped
2770
- ? `XiaShe package: ${result.xiashePackageArtifact.artifactPath} (${result.xiashePackageArtifact.publishStatus || 'queued'})`
2890
+ result.firstPartyPackageArtifact && !result.firstPartyPackageArtifact.skipped
2891
+ ? `${PRODUCT_NAME} package: ${result.firstPartyPackageArtifact.artifactPath} (${result.firstPartyPackageArtifact.publishStatus || 'queued'})`
2771
2892
  : null,
2772
2893
  `Disclosure: ${result.disclosurePath}`,
2773
2894
  result.snippetPath ? `Runtime snippet: ${result.snippetPath}` : null,
@@ -2775,8 +2896,8 @@ async function main() {
2775
2896
  '',
2776
2897
  'Next:',
2777
2898
  '- Treat the target platform official upload flow as authoritative.',
2778
- '- Use the handoff file as the only XiaShe registry checklist.',
2779
- '- XiaShe complete package upload is already handled by this command when the xiashe target is selected.',
2899
+ `- Use the handoff file as the only ${PRODUCT_NAME} registry checklist.`,
2900
+ `- ${PRODUCT_NAME} complete package upload is already handled by this command when the first-party registry target is selected.`,
2780
2901
  '- Before uploading to third-party targets, check whether this Skill already has a draft, submitted review, or published listing for the selected target; skip duplicate uploads and verify/update the existing record when possible.',
2781
2902
  '- Check upload readiness and runtime readiness separately before submission.',
2782
2903
  '- Only ask for creator CLI login if a separate store-management command is needed and the registry public token is missing or rejected.',
@@ -2801,8 +2922,8 @@ async function main() {
2801
2922
  result.publicProtocol ? `Wrote ${result.publicProtocol.runtimePath}` : null,
2802
2923
  result.publicProtocol ? `Wrote ${result.publicProtocol.agentAckPath}` : null,
2803
2924
  result.publicProtocol ? `Wrote ${result.publicProtocol.disclosurePath}` : null,
2804
- result.xiashePackageArtifact && !result.xiashePackageArtifact.skipped
2805
- ? `Uploaded XiaShe package ${result.xiashePackageArtifact.artifactPath} (${result.xiashePackageArtifact.publishStatus || 'queued'})`
2925
+ result.firstPartyPackageArtifact && !result.firstPartyPackageArtifact.skipped
2926
+ ? `Uploaded ${PRODUCT_NAME} package ${result.firstPartyPackageArtifact.artifactPath} (${result.firstPartyPackageArtifact.publishStatus || 'queued'})`
2806
2927
  : null,
2807
2928
  `Wrote ${result.disclosurePath}`,
2808
2929
  result.snippetPath ? `Wrote ${result.snippetPath}` : null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiashe/skill",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "xiashe-skill": "bin/xiashe-skill.mjs"