@xiashe/skill 0.1.26 → 0.1.27

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 CHANGED
@@ -44,9 +44,9 @@ node packages/xiashe-skill-cli/bin/xiashe-skill.mjs snippet . --target js
44
44
  node packages/xiashe-skill-cli/bin/xiashe-skill.mjs track . --event skill_invoked --hub red --dry-run --json
45
45
  ```
46
46
 
47
- Use the `claimUrl` returned with a dashboard dynamic code exactly as issued. `publish` runs the same preflight automatically before it consumes a code: it verifies the exact registry origin, protocol version, and environment id exposed by that deployment. A dynamic code without an explicit `--claim-url` is rejected before the code is consumed, so development, CN, and global codes cannot accidentally be sent to the production registry. For an existing Skill update, use the single public `--registry-origin https://<registry-host>` option. The CLI derives its routes, compares that origin and the registry environment id with the local private manifest, and stops before writing or uploading when they differ. Do not copy individual internal endpoint overrides into an update task.
47
+ Use the `claimUrl` returned with a dashboard dynamic code exactly as issued. `publish` validates that destination before it consumes a code, so a code cannot accidentally be sent to a different service. For an existing Skill update, run the normal publish command from the original project folder. The CLI reads and validates its saved local connection before it writes or uploads anything. Do not copy internal endpoint options into a user-facing update task.
48
48
 
49
- When an existing project was originally linked through XiaShe, `@agentpie/skill publish` may adopt its `.xiashe/xiashe.skill.json` only for an update without a dynamic code or explicit public token. The legacy manifest must identify itself as XiaShe and contain its saved registry origin and environment. The CLI verifies both, then writes a separate `.agentpie/agentpie.skill.json`; the XiaShe manifest is retained. A missing value or mismatch stops before a manifest write or package upload, so development, CN, and global Skill identities stay isolated.
49
+ When an existing project was originally linked through XiaShe, `@agentpie/skill publish` can reuse that local connection only for an update without a dynamic code or public token. It validates the recorded connection first, then creates a separate AgentPie local connection while retaining the XiaShe original. If it cannot verify the link, it stops before changing files or uploading a package. This keeps distinct services isolated without asking users to understand internal deployment details.
50
50
 
51
51
  ## Reliable publish and recovery
52
52
 
@@ -68,7 +68,7 @@ function isTransportError(error) {
68
68
  }
69
69
 
70
70
  const LOCAL_ENV_DEFAULTS = loadLocalEnvDefaults();
71
- const VERSION = process.env.XIASHE_SKILL_CLI_VERSION || '0.1.25';
71
+ const VERSION = process.env.XIASHE_SKILL_CLI_VERSION || '0.1.27';
72
72
  const COMMAND_NAME = process.env.XIASHE_SKILL_CLI_NAME || 'xiashe-skill';
73
73
  const PRODUCT_NAME = process.env.XIASHE_SKILL_PRODUCT_NAME || (COMMAND_NAME === 'agentpie-skill' ? 'AgentPie' : 'XiaShe');
74
74
  const REGISTRY_PROVIDER = process.env.XIASHE_SKILL_REGISTRY_PROVIDER || (COMMAND_NAME === 'agentpie-skill' ? 'agentpie' : 'xiashe');
@@ -341,7 +341,7 @@ Usage:
341
341
  Options:
342
342
  --public-token <token> Public write token issued by ${PRODUCT_NAME} registry.
343
343
  --code <dynamic-code> One-time ${PRODUCT_NAME} dashboard code used to claim registry identity.
344
- --registry-origin <url> Existing Skill update origin. Derives all registry routes and verifies the saved environment.
344
+ --registry-origin <url> Advanced recovery option for an existing Skill. Normal updates do not need it.
345
345
  --claim-url <url> Code claim endpoint. Defaults to XIASHE_SKILL_CLAIM_URL or ${DEFAULT_CLAIM_URL}
346
346
  --registry-doctor-url <url> Registry preflight endpoint. Defaults to the claim URL origin.
347
347
  --skill-id <id> Public ${PRODUCT_NAME} Skill registry id.
@@ -543,7 +543,7 @@ function latestVersionEndpoint(inspectedOrRegistry = {}) {
543
543
  // Existing Skills must keep checking the registry that originally issued
544
544
  // their manifest. Falling back to a CLI default here would make a dev
545
545
  // package discover Global/CN updates after a machine-level config change.
546
- const registryOrigin = normalizeBaseUrl(registry.registryOrigin) || DEFAULT_BASE_URL;
546
+ const registryOrigin = resolveStoredRegistryOrigin(registry) || DEFAULT_BASE_URL;
547
547
  const params = new URLSearchParams();
548
548
  if (publicSkillId) {
549
549
  params.set('publicSkillId', publicSkillId);
@@ -990,13 +990,13 @@ async function resolveExistingSkillRoot(root, flags = {}) {
990
990
  }
991
991
  if (candidates.length > 1) {
992
992
  throw new Error(
993
- 'CREATOR_SKILL_MANIFEST_AMBIGUOUS: more than one matching local Skill connection was found. ' +
994
- 'The CLI did not update or create any Skill. Run the command from the intended Skill folder.'
993
+ 'CREATOR_SKILL_SOURCE_AMBIGUOUS: more than one Skill project matches this update. ' +
994
+ 'No Skill was changed. Run this task from the intended Skill project folder.'
995
995
  );
996
996
  }
997
997
  throw new Error(
998
- 'CREATOR_SKILL_MANIFEST_NOT_FOUND: no matching local Skill connection was found in this project. ' +
999
- 'The CLI did not update or create any Skill. Run the command from the original Skill folder.'
998
+ 'CREATOR_SKILL_SOURCE_NOT_FOUND: this task does not include the original Skill project. ' +
999
+ 'No Skill was created or changed. Add that project folder and retry.'
1000
1000
  );
1001
1001
  }
1002
1002
 
@@ -1123,11 +1123,14 @@ function claimUrlForCode(flags = {}) {
1123
1123
  }
1124
1124
 
1125
1125
  function claimUrlForExistingManifest(flags = {}, registry = {}) {
1126
- return (
1127
- explicitClaimUrl(flags) ||
1128
- claimUrlFromRegistryOrigin(registry.registryOrigin) ||
1129
- DEFAULT_CLAIM_URL
1130
- );
1126
+ const claimUrl = explicitClaimUrl(flags) || claimUrlFromRegistryOrigin(resolveStoredRegistryOrigin(registry));
1127
+ if (!claimUrl) {
1128
+ throw new Error(
1129
+ 'CREATOR_SKILL_CONNECTION_UNVERIFIABLE: this local Skill connection cannot be verified safely. ' +
1130
+ 'No Skill was created or changed. Add the original Skill project folder and retry.'
1131
+ );
1132
+ }
1133
+ return claimUrl;
1131
1134
  }
1132
1135
 
1133
1136
  function normalizeRegistryOrigin(value) {
@@ -1154,6 +1157,55 @@ function registryOriginFromFlags(flags = {}) {
1154
1157
  return normalizeRegistryOrigin(flags['registry-origin']);
1155
1158
  }
1156
1159
 
1160
+ const STORED_REGISTRY_ENDPOINT_PATHS = new Set([
1161
+ '/registry/skill/claim',
1162
+ '/registry/skill-events',
1163
+ '/registry/agent-ack',
1164
+ '/registry/skill/latest',
1165
+ '/registry/skill/package-upload-url',
1166
+ '/registry/skill/package-status'
1167
+ ]);
1168
+
1169
+ function registryOriginFromStoredEndpoint(value) {
1170
+ const raw = normalizeText(value, 2_000);
1171
+ if (!raw) return '';
1172
+ let url;
1173
+ try {
1174
+ url = new URL(raw);
1175
+ } catch {
1176
+ return '';
1177
+ }
1178
+ if (url.username || url.password || url.hash) return '';
1179
+ const pathname = url.pathname.replace(/\/+$/, '') || '/';
1180
+ if (!STORED_REGISTRY_ENDPOINT_PATHS.has(pathname)) return '';
1181
+ try {
1182
+ return normalizeRegistryOrigin(url.origin);
1183
+ } catch {
1184
+ return '';
1185
+ }
1186
+ }
1187
+
1188
+ function resolveStoredRegistryOrigin(registry = {}) {
1189
+ const directOrigin = normalizeBaseUrl(registry.registryOrigin);
1190
+ if (directOrigin) {
1191
+ try {
1192
+ return normalizeRegistryOrigin(directOrigin);
1193
+ } catch {
1194
+ return '';
1195
+ }
1196
+ }
1197
+ for (const endpoint of [
1198
+ registry.claimUrl,
1199
+ registry.registryUrl,
1200
+ registry.agentAckUrl,
1201
+ registry.latestVersionEndpoint
1202
+ ]) {
1203
+ const origin = registryOriginFromStoredEndpoint(endpoint);
1204
+ if (origin) return origin;
1205
+ }
1206
+ return '';
1207
+ }
1208
+
1157
1209
  function applyRegistryOriginFlags(flags = {}) {
1158
1210
  const registryOrigin = registryOriginFromFlags(flags);
1159
1211
  if (!registryOrigin) return flags;
@@ -1572,15 +1624,15 @@ async function uploadXiashePackageArtifact(root, flags, manifestResult) {
1572
1624
  // to the production registry, then verify that origin before any write.
1573
1625
  const claimUrl = claimUrlForExistingManifest(flags, registry);
1574
1626
  const registryPreflight = await preflightRegistryClaim(claimUrl, flags);
1575
- const expectedRegistryOrigin = normalizeBaseUrl(registry.registryOrigin);
1627
+ const expectedRegistryOrigin = resolveStoredRegistryOrigin(registry);
1576
1628
  const expectedEnvironmentId = normalizeText(registry.environmentId, 160);
1577
1629
  if (
1578
1630
  (expectedRegistryOrigin && expectedRegistryOrigin !== registryPreflight.registryOrigin) ||
1579
1631
  (expectedEnvironmentId && expectedEnvironmentId !== registryPreflight.environmentId)
1580
1632
  ) {
1581
1633
  throw new Error(
1582
- 'CREATOR_SKILL_REGISTRY_ENVIRONMENT_MISMATCH: the local manifest belongs to a different registry environment. ' +
1583
- 'Do not upload or claim a new code; switch to the original environment or start a new dashboard task.'
1634
+ 'CREATOR_SKILL_CONNECTION_MISMATCH: this project is linked to a different Skill service. ' +
1635
+ 'No package was uploaded.'
1584
1636
  );
1585
1637
  }
1586
1638
  const uploadTicket =
@@ -1712,22 +1764,25 @@ async function inspectSkill(root, flags = {}) {
1712
1764
  async function writeManifest(root, flags) {
1713
1765
  const inspected = await inspectSkill(root, flags);
1714
1766
  const code = normalizeText(flags.code, 80);
1715
- const existingRegistry = inspected.registry || {};
1716
- const savedRegistryOrigin = normalizeBaseUrl(existingRegistry.registryOrigin);
1767
+ const rawExistingRegistry = inspected.registry || {};
1768
+ const savedRegistryOrigin = resolveStoredRegistryOrigin(rawExistingRegistry);
1769
+ const existingRegistry = savedRegistryOrigin && rawExistingRegistry.registryOrigin !== savedRegistryOrigin
1770
+ ? { ...rawExistingRegistry, registryOrigin: savedRegistryOrigin }
1771
+ : rawExistingRegistry;
1717
1772
  const savedEnvironmentId = normalizeText(existingRegistry.environmentId, 160);
1718
1773
  const requestedRegistryOrigin = registryOriginFromFlags(flags);
1719
1774
  const suppliedPublicToken = normalizeText(flags['public-token'], 512);
1720
1775
  const isLegacyXiaSheMigration = inspected.manifestSource === 'legacy_xiashe';
1721
1776
  if (
1722
1777
  isLegacyXiaSheMigration &&
1723
- (existingRegistry.provider !== 'xiashe' || !savedRegistryOrigin || !savedEnvironmentId)
1778
+ (existingRegistry.provider !== 'xiashe' || !savedRegistryOrigin)
1724
1779
  ) {
1725
1780
  throw new Error(
1726
- 'CREATOR_SKILL_LEGACY_MANIFEST_UNVERIFIABLE: this XiaShe local connection does not contain a verifiable registry origin and environment. ' +
1727
- 'No AgentPie manifest was written. Update from the original XiaShe connection or attach the Skill explicitly.'
1781
+ 'CREATOR_SKILL_LEGACY_CONNECTION_UNVERIFIABLE: this older XiaShe Skill connection cannot be verified safely. ' +
1782
+ 'No AgentPie Skill was created or changed. Use the original Skill project folder and refresh its connection before updating.'
1728
1783
  );
1729
1784
  }
1730
- if (!code && suppliedPublicToken && !explicitClaimUrl(flags) && !claimUrlFromRegistryOrigin(existingRegistry.registryOrigin)) {
1785
+ if (!code && suppliedPublicToken && !explicitClaimUrl(flags) && !savedRegistryOrigin) {
1731
1786
  throw new Error(
1732
1787
  'CREATOR_SKILL_CLAIM_URL_REQUIRED: a new manifest created from --public-token must include --claim-url. ' +
1733
1788
  'Existing manifests resume through their saved registry origin.'
@@ -1735,19 +1790,20 @@ async function writeManifest(root, flags) {
1735
1790
  }
1736
1791
  if (!code && !savedRegistryOrigin && !requestedRegistryOrigin) {
1737
1792
  throw new Error(
1738
- 'CREATOR_SKILL_REGISTRY_ORIGIN_REQUIRED: existing Skill updates must include --registry-origin so the CLI can verify the original environment before writing or uploading.'
1793
+ 'CREATOR_SKILL_CONNECTION_UNVERIFIABLE: this local Skill connection cannot be verified safely. ' +
1794
+ 'No Skill was created or changed. Add the original Skill project folder and retry.'
1739
1795
  );
1740
1796
  }
1741
1797
  if (!code && savedRegistryOrigin && requestedRegistryOrigin && savedRegistryOrigin !== requestedRegistryOrigin) {
1742
- throw new Error('CREATOR_SKILL_REGISTRY_ENVIRONMENT_MISMATCH: the supplied registry origin differs from the original Skill manifest. No files were changed.');
1798
+ throw new Error('CREATOR_SKILL_CONNECTION_MISMATCH: this project is linked to a different Skill service. No files were changed.');
1743
1799
  }
1744
1800
  const claimUrl = code ? claimUrlForCode(flags) : claimUrlForExistingManifest(flags, existingRegistry);
1745
1801
  const registryPreflight = await preflightRegistryClaim(claimUrl, flags);
1746
1802
  if (!code && savedRegistryOrigin && savedRegistryOrigin !== registryPreflight.registryOrigin) {
1747
- throw new Error('CREATOR_SKILL_REGISTRY_ENVIRONMENT_MISMATCH: the saved Skill manifest belongs to a different registry origin. No files were changed.');
1803
+ throw new Error('CREATOR_SKILL_CONNECTION_MISMATCH: this project is linked to a different Skill service. No files were changed.');
1748
1804
  }
1749
1805
  if (!code && savedEnvironmentId && savedEnvironmentId !== registryPreflight.environmentId) {
1750
- throw new Error('CREATOR_SKILL_REGISTRY_ENVIRONMENT_MISMATCH: the saved Skill manifest belongs to a different registry environment. No files were changed.');
1806
+ throw new Error('CREATOR_SKILL_CONNECTION_MISMATCH: this project is linked to a different Skill service. No files were changed.');
1751
1807
  }
1752
1808
  const claim = code
1753
1809
  ? await postJson(
@@ -1778,12 +1834,15 @@ async function writeManifest(root, flags) {
1778
1834
  const claimEnvironment = normalizeText(claim.registry?.environmentId, 160);
1779
1835
  const claimOrigin = normalizeBaseUrl(claim.registry?.registryOrigin);
1780
1836
  if (claimEnvironment !== registryPreflight.environmentId || claimOrigin !== registryPreflight.registryOrigin) {
1781
- throw new Error('CREATOR_SKILL_REGISTRY_ENVIRONMENT_MISMATCH: the claimed Skill identity was returned by a different registry environment. No package upload was attempted.');
1837
+ throw new Error('CREATOR_SKILL_CONNECTION_MISMATCH: the returned Skill identity does not match this local connection. No package upload was attempted.');
1782
1838
  }
1783
1839
  }
1784
1840
  const publicToken = normalizeText(flags['public-token'] || claim?.publicToken || existingRegistry.publicToken, 512);
1785
1841
  if (!publicToken) {
1786
- throw new Error('Missing --code or --public-token.');
1842
+ throw new Error(
1843
+ 'CREATOR_SKILL_CONNECTION_UNVERIFIABLE: this local Skill connection cannot be verified safely. ' +
1844
+ 'No Skill was created or changed. Add the original Skill project folder and retry.'
1845
+ );
1787
1846
  }
1788
1847
  const now = new Date().toISOString();
1789
1848
  const claimCreatorProfile = normalizeCreatorProfile(claim?.creatorProfile);
@@ -3508,7 +3567,7 @@ async function setupAgentWorkflow(root, flags) {
3508
3567
  ? 'An existing local Skill connection was found automatically; no new registry entry was created.'
3509
3568
  : null,
3510
3569
  manifestResult.adoptedLegacyXiaSheManifest
3511
- ? 'A compatible XiaShe local connection was reused after the registry origin and environment check; a separate AgentPie manifest was created.'
3570
+ ? 'A compatible XiaShe local connection was reused safely; a separate AgentPie local connection was created.'
3512
3571
  : null,
3513
3572
  firstPartyPackageArtifact?.skipped
3514
3573
  ? `${PRODUCT_NAME} complete package upload was skipped (${firstPartyPackageArtifact.reason}).`
@@ -3573,10 +3632,8 @@ async function main() {
3573
3632
  flags
3574
3633
  );
3575
3634
  print(flags.json ? result : [
3576
- `${PRODUCT_NAME} registry preflight passed.`,
3577
- `Environment: ${result.environmentId}`,
3578
- `Registry: ${result.registryOrigin}`,
3579
- `Protocol: ${result.protocolVersion}`
3635
+ `${PRODUCT_NAME} preflight passed.`,
3636
+ 'Connection verified.'
3580
3637
  ].join('\n'), flags.json);
3581
3638
  return;
3582
3639
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiashe/skill",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "xiashe-skill": "bin/xiashe-skill.mjs"