@xiashe/skill 0.1.14 → 0.1.15

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.
@@ -6,7 +6,7 @@ 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
8
 
9
- const VERSION = '0.1.13';
9
+ const VERSION = '0.1.15';
10
10
  const COMMAND_NAME = process.env.XIASHE_SKILL_CLI_NAME || 'xiashe-skill';
11
11
  const PRODUCT_NAME = process.env.XIASHE_SKILL_PRODUCT_NAME || (COMMAND_NAME === 'agentpie-skill' ? 'AgentPie' : 'XiaShe');
12
12
  const REGISTRY_PROVIDER = process.env.XIASHE_SKILL_REGISTRY_PROVIDER || (COMMAND_NAME === 'agentpie-skill' ? 'agentpie' : 'xiashe');
@@ -274,6 +274,94 @@ function normalizeText(value, maxLength = 240) {
274
274
  return String(value || '').trim().replace(/\s+/g, ' ').slice(0, maxLength);
275
275
  }
276
276
 
277
+ function normalizeCreatorProfile(value) {
278
+ if (!value || typeof value !== 'object') return null;
279
+ const displayName = normalizeText(value.displayName, 120);
280
+ const xiaSignal = normalizeText(value.xiaSignal, 80);
281
+ const bio = normalizeText(value.bio, 500);
282
+ const avatarUrl = normalizeText(value.avatarUrl, 800);
283
+ const cardUrl = normalizeText(value.cardUrl || value.creatorCardUrl, 800);
284
+ const links = Array.isArray(value.links)
285
+ ? value.links.slice(0, 8).map((link) => ({
286
+ key: normalizeText(link?.key, 40),
287
+ handle: normalizeText(link?.handle, 120),
288
+ url: normalizeText(link?.url, 800)
289
+ })).filter((link) => link.key || link.handle || link.url)
290
+ : [];
291
+ const modules = Array.isArray(value.modules)
292
+ ? value.modules.slice(0, 6).map((module) => ({
293
+ kind: normalizeText(module?.kind, 40),
294
+ title: normalizeText(module?.title, 120),
295
+ subtitle: normalizeText(module?.subtitle, 160),
296
+ detail: normalizeText(module?.detail, 300)
297
+ })).filter((module) => module.title || module.subtitle || module.detail)
298
+ : [];
299
+ if (!displayName && !xiaSignal && !bio && !cardUrl && links.length === 0 && modules.length === 0) return null;
300
+ return {
301
+ displayName: displayName || null,
302
+ xiaSignal: xiaSignal || null,
303
+ bio: bio || null,
304
+ avatarUrl: avatarUrl || null,
305
+ cardUrl: cardUrl || null,
306
+ links,
307
+ modules
308
+ };
309
+ }
310
+
311
+ function creatorProfileFromRegistry(registry = {}) {
312
+ return normalizeCreatorProfile(registry.creatorProfile) || normalizeCreatorProfile({
313
+ displayName: registry.creatorDisplayName,
314
+ xiaSignal: registry.creatorXiaSignal,
315
+ bio: registry.creatorBio,
316
+ avatarUrl: registry.creatorAvatarUrl,
317
+ cardUrl: registry.creatorCardUrl
318
+ });
319
+ }
320
+
321
+ function creatorProfileSummaryLines(registry = {}, language = 'en') {
322
+ const profile = creatorProfileFromRegistry(registry);
323
+ if (!profile) return [];
324
+ const linkSummary = profile.links
325
+ .slice(0, 3)
326
+ .map((link) => [link.key, link.handle || link.url].filter(Boolean).join(': '))
327
+ .filter(Boolean)
328
+ .join(';');
329
+ const moduleSummary = profile.modules
330
+ .slice(0, 3)
331
+ .map((module) => [module.title, module.subtitle].filter(Boolean).join(' / '))
332
+ .filter(Boolean)
333
+ .join(';');
334
+ if (language === 'zh') {
335
+ return [
336
+ profile.displayName ? `- 创作者:${profile.displayName}` : null,
337
+ profile.xiaSignal ? `- 虾信号:@${profile.xiaSignal}` : null,
338
+ profile.bio ? `- 创作者简介:${profile.bio}` : null,
339
+ profile.cardUrl ? `- 创作者名片:${profile.cardUrl}` : null,
340
+ linkSummary ? `- 创作者公开链接:${linkSummary}` : null,
341
+ moduleSummary ? `- 创作者经历/作品:${moduleSummary}` : null
342
+ ].filter(Boolean);
343
+ }
344
+ return [
345
+ profile.displayName ? `- Creator: ${profile.displayName}` : null,
346
+ profile.xiaSignal ? `- XiaShe handle: @${profile.xiaSignal}` : null,
347
+ profile.bio ? `- Creator bio: ${profile.bio}` : null,
348
+ profile.cardUrl ? `- Creator card: ${profile.cardUrl}` : null,
349
+ linkSummary ? `- Creator public links: ${linkSummary}` : null,
350
+ moduleSummary ? `- Creator highlights: ${moduleSummary}` : null
351
+ ].filter(Boolean);
352
+ }
353
+
354
+ function creatorProfilePublicPayload(profile) {
355
+ if (!profile) return '<creator profile from local registry manifest>';
356
+ return {
357
+ displayName: profile.displayName,
358
+ xiaSignal: profile.xiaSignal,
359
+ bio: profile.bio,
360
+ links: profile.links,
361
+ modules: profile.modules
362
+ };
363
+ }
364
+
277
365
  function safeSkillKey(value) {
278
366
  return normalizeText(value, 120)
279
367
  .toLowerCase()
@@ -600,6 +688,12 @@ async function writeManifest(root, flags) {
600
688
  throw new Error('Missing --code or --public-token.');
601
689
  }
602
690
  const now = new Date().toISOString();
691
+ const claimCreatorProfile = normalizeCreatorProfile(claim?.creatorProfile);
692
+ const creatorCardUrl = normalizeText(flags['creator-card-url'] || claim?.creatorCardUrl || claimCreatorProfile?.cardUrl, 800) || null;
693
+ const creatorProfile = normalizeCreatorProfile({
694
+ ...claimCreatorProfile,
695
+ cardUrl: creatorCardUrl
696
+ });
603
697
  const manifest = {
604
698
  schemaVersion: `${REGISTRY_PROVIDER}.skill.registry.v1`,
605
699
  name: normalizeText(claim?.name, 120) || inspected.name,
@@ -612,7 +706,8 @@ async function writeManifest(root, flags) {
612
706
  publicToken,
613
707
  registryUrl: normalizeText(flags['registry-url'] || claim?.registryUrl, 800) || DEFAULT_REGISTRY_URL,
614
708
  agentAckUrl: normalizeText(flags['agent-ack-url'], 800) || DEFAULT_AGENT_ACK_URL,
615
- creatorCardUrl: normalizeText(flags['creator-card-url'] || claim?.creatorCardUrl, 800) || null,
709
+ creatorCardUrl,
710
+ creatorProfile,
616
711
  eventSchemaVersion: EVENT_SCHEMA_VERSION,
617
712
  signing: {
618
713
  mode: normalizeText(flags['signing-secret'], 20) ? 'optional' : 'off',
@@ -656,7 +751,9 @@ async function writeManifest(root, flags) {
656
751
  sourceSurface: hub,
657
752
  skillKey: safeSkillKey(claim?.skillKey || inspected.skillKey),
658
753
  publicSkillId: normalizeText(flags['skill-id'] || claim?.skillId, 160) || null,
659
- agentAckUrl: normalizeText(flags['agent-ack-url'], 800) || DEFAULT_AGENT_ACK_URL
754
+ agentAckUrl: normalizeText(flags['agent-ack-url'], 800) || DEFAULT_AGENT_ACK_URL,
755
+ creatorCardUrl,
756
+ creatorProfile
660
757
  }
661
758
  }
662
759
  ];
@@ -788,6 +885,7 @@ function uploadCompatibilityLines(hub, manifestFile) {
788
885
 
789
886
  function publicDisclosure(inspected, registryUrl, hub = 'generic') {
790
887
  const creatorCardUrl = normalizeText(inspected.registry?.creatorCardUrl, 800);
888
+ const creatorLines = creatorProfileSummaryLines(inspected.registry || {}, 'en');
791
889
  if (hub === 'red') {
792
890
  return [
793
891
  '公开披露文本:',
@@ -796,6 +894,7 @@ function publicDisclosure(inspected, registryUrl, hub = 'generic') {
796
894
  '',
797
895
  `This Skill may include a ${PRODUCT_NAME} creator attribution or disclosure link for public listing and aggregate reporting.`,
798
896
  creatorCardUrl ? `Creator card: ${creatorCardUrl}` : 'Creator card: <creator card link from XiaShe dashboard>',
897
+ ...creatorLines.filter((line) => !line.startsWith('- Creator card:')),
799
898
  '',
800
899
  '- Data mode for Red Skill upload: Agent Ack runtime when the host Agent follows the tracking contract; upload/reported otherwise.',
801
900
  '- Do not publish XiaShe registry ids, Skill ids, public tokens, endpoints, hidden telemetry, cookies, account sessions, or local private files in Red public fields.',
@@ -814,6 +913,7 @@ function publicDisclosure(inspected, registryUrl, hub = 'generic') {
814
913
  `- Registry provider: ${REGISTRY_PROVIDER}`,
815
914
  `- Skill key: ${inspected.skillKey}`,
816
915
  `- Creator card: ${creatorCardUrl || '<creator card link from XiaShe dashboard>'}`,
916
+ ...creatorLines.filter((line) => !line.startsWith('- Creator card:')),
817
917
  `- Registry event endpoint: ${registryUrl}`,
818
918
  '- Events, if enabled by the runtime/platform, should contain only public metadata and aggregate status.',
819
919
  '- Do not send user prompts, private files, credentials, environment variables, account tokens, or raw business content.',
@@ -827,6 +927,7 @@ function agentAckInstructionBlock(inspected, hub = 'generic') {
827
927
  const publicSkillId = registry.skillId || registry.publicSkillId || '<public skill id from local registry manifest>';
828
928
  const ackUrl = registry.agentAckUrl || DEFAULT_AGENT_ACK_URL;
829
929
  const creatorCardUrl = normalizeText(registry.creatorCardUrl, 800) || '<creator card link from XiaShe dashboard>';
930
+ const creatorProfile = creatorProfileFromRegistry(registry);
830
931
  const eventSchemaVersion = registry.eventSchemaVersion || EVENT_SCHEMA_VERSION;
831
932
  const normalizedHub = normalizeHub(hub) || hub || 'generic';
832
933
  return [
@@ -837,6 +938,7 @@ function agentAckInstructionBlock(inspected, hub = 'generic') {
837
938
  `- Ack endpoint: ${ackUrl}`,
838
939
  `- Public Skill ID: ${publicSkillId}`,
839
940
  `- Creator card: ${creatorCardUrl}`,
941
+ ...creatorProfileSummaryLines(registry, 'en').filter((line) => !line.startsWith('- Creator card:')),
840
942
  `- Event schema: ${eventSchemaVersion}`,
841
943
  `- Platform hub: ${normalizedHub}`,
842
944
  '- Send only anonymous aggregate usage status. Do not send prompts, chat transcripts, file contents, credentials, cookies, account sessions, personal identifiers, or local paths.',
@@ -850,6 +952,9 @@ function agentAckInstructionBlock(inspected, hub = 'generic') {
850
952
  schemaVersion: eventSchemaVersion,
851
953
  event: 'completed',
852
954
  platform: normalizedHub,
955
+ skillKey: inspected.skillKey,
956
+ packageSha256: inspected.package?.sha256 || '<package sha256 from .xiashe/xiashe.skill.json>',
957
+ creatorCardUrl,
853
958
  installationId: '<stable anonymous install id>',
854
959
  invocationId: '<unique call id>',
855
960
  scenario: '<short public scenario label>',
@@ -865,6 +970,7 @@ function agentAckInstructionBlock(inspected, hub = 'generic') {
865
970
  '```json',
866
971
  JSON.stringify({
867
972
  creatorCardUrl,
973
+ creator: creatorProfilePublicPayload(creatorProfile),
868
974
  xiasheAdSlot: null
869
975
  }, null, 2),
870
976
  '```'
@@ -875,6 +981,7 @@ function redPublicTrackingContractBlock(inspected) {
875
981
  const registry = inspected.registry || {};
876
982
  const marker = `${REGISTRY_PROVIDER}-red-public-tracking`;
877
983
  const cardUrl = normalizeText(registry.creatorCardUrl, 800) || '<creator card link from XiaShe dashboard>';
984
+ const creatorProfile = creatorProfileFromRegistry(registry);
878
985
  return [
879
986
  `<!-- ${marker}:start -->`,
880
987
  `## ${PRODUCT_NAME} 使用统计约定`,
@@ -885,13 +992,30 @@ function redPublicTrackingContractBlock(inspected) {
885
992
  '- 安装或导入后发送 `installed`。',
886
993
  '- 用户开始使用本 Skill 时发送 `used`。',
887
994
  '- 任务完成后发送 `completed`;失败时发送 `failed`。',
888
- '- 每次回复末尾保留创作者名片链接和广告占位 JSON;广告为空时不要解析或展示。',
995
+ '- 每次回复末尾保留创作者名片链接、创作者基础信息和广告占位 JSON;广告为空时不要解析或展示。',
889
996
  '',
890
997
  `创作者名片:${cardUrl}`,
998
+ ...creatorProfileSummaryLines(registry, 'zh').filter((line) => !line.startsWith('- 创作者名片:')),
999
+ `Skill 标识:${inspected.skillKey}`,
1000
+ `包指纹:${inspected.package.sha256}`,
1001
+ '',
1002
+ '上报时优先使用本地私有配置里的 publicSkillId;如果当前 Agent 没有读到该字段,可以用下面的公开来源信息完成匿名 Ack,虾舍会在服务端恢复到正确 Skill:',
1003
+ '```json',
1004
+ JSON.stringify({
1005
+ creatorCardUrl: cardUrl,
1006
+ creator: creatorProfilePublicPayload(creatorProfile),
1007
+ skillKey: inspected.skillKey,
1008
+ packageSha256: inspected.package.sha256
1009
+ }, null, 2),
1010
+ '```',
891
1011
  '',
892
1012
  '广告占位 JSON:',
893
1013
  '```json',
894
- JSON.stringify({ xiasheAdSlot: null }, null, 2),
1014
+ JSON.stringify({
1015
+ creatorCardUrl: cardUrl,
1016
+ creator: creatorProfilePublicPayload(creatorProfile),
1017
+ xiasheAdSlot: null
1018
+ }, null, 2),
895
1019
  '```',
896
1020
  '',
897
1021
  '隐私与公开展示边界:',
@@ -992,6 +1116,7 @@ async function uploadPrompt(inspected, flags) {
992
1116
  const agentAckUrl = registry.agentAckUrl || DEFAULT_AGENT_ACK_URL;
993
1117
  const publicSkillId = registry.skillId || registry.publicSkillId || '<public skill id from local registry manifest>';
994
1118
  const creatorCardUrl = normalizeText(registry.creatorCardUrl, 800) || '<creator card link from XiaShe dashboard>';
1119
+ const creatorProfileLines = creatorProfileSummaryLines(registry, 'zh').filter((line) => !line.startsWith('- 创作者名片:'));
995
1120
  const redHub = hub === 'red';
996
1121
  const eventPayload = {
997
1122
  publicToken: registry.publicToken || '<xiashe public token from xiashe.skill.json>',
@@ -1025,6 +1150,9 @@ async function uploadPrompt(inspected, flags) {
1025
1150
  schemaVersion: registry.eventSchemaVersion || EVENT_SCHEMA_VERSION,
1026
1151
  event: 'completed',
1027
1152
  platform: hub,
1153
+ skillKey: inspected.skillKey,
1154
+ packageSha256: inspected.package.sha256,
1155
+ creatorCardUrl,
1028
1156
  installationId: '<stable anonymous install id>',
1029
1157
  invocationId: '<unique call id>',
1030
1158
  scenario: '<short public scenario label>',
@@ -1056,6 +1184,7 @@ async function uploadPrompt(inspected, flags) {
1056
1184
  `- 版本:${inspected.version}`,
1057
1185
  `- 描述:${inspected.description || '<从 SKILL.md/README.md 中提炼>'}`,
1058
1186
  `- 创作者名片:${creatorCardUrl}`,
1187
+ ...creatorProfileLines,
1059
1188
  `- 源码指纹 SHA256:${inspected.package.sha256}`,
1060
1189
  '- Red Skill 上传包按官方流程准备;虾舍 public token、registry id、Skill id、endpoint、runtime-events.js 和 .xiashe 内部文件默认只在本地保留。',
1061
1190
  '- SKILL.md 最开头必须写公开追踪约定,并保留创作者名片链接和广告占位 JSON;但不要在 Red 公开介绍里泄露后台字段。',
@@ -1071,6 +1200,7 @@ async function uploadPrompt(inspected, flags) {
1071
1200
  `- 版本:${inspected.version}`,
1072
1201
  `- 描述:${inspected.description || '<从 SKILL.md/README.md 中提炼>'}`,
1073
1202
  `- 创作者名片:${creatorCardUrl}`,
1203
+ ...creatorProfileLines,
1074
1204
  `- 源码指纹 SHA256:${inspected.package.sha256}`,
1075
1205
  '- 不要读取或上传 .env、密钥、浏览器数据、SSH key、系统目录或 node_modules。',
1076
1206
  '- 不要新增 postinstall hook、后台常驻进程、隐藏脚本或混淆逻辑。',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiashe/skill",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "xiashe-skill": "bin/xiashe-skill.mjs"