reskill 1.14.0 → 1.15.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.
|
@@ -49,6 +49,21 @@ export declare function checkGitVersion(): CheckResult;
|
|
|
49
49
|
* Check Git authentication
|
|
50
50
|
*/
|
|
51
51
|
export declare function checkGitAuth(): CheckResult;
|
|
52
|
+
/**
|
|
53
|
+
* Check registry authentication status
|
|
54
|
+
*
|
|
55
|
+
* Verifies actual token availability, not just file existence.
|
|
56
|
+
* Uses AuthManager.getToken() which checks RESKILL_TOKEN env first,
|
|
57
|
+
* then reads ~/.reskillrc for the configured registry.
|
|
58
|
+
*/
|
|
59
|
+
export declare function checkAuthStatus(): CheckResult;
|
|
60
|
+
/**
|
|
61
|
+
* Check environment variables used by reskill
|
|
62
|
+
*
|
|
63
|
+
* Security: Only report variable names, never values.
|
|
64
|
+
* RESKILL_TOKEN contains a secret and must not be displayed.
|
|
65
|
+
*/
|
|
66
|
+
export declare function checkEnvVars(): CheckResult;
|
|
52
67
|
/**
|
|
53
68
|
* Check cache directory
|
|
54
69
|
*/
|
|
@@ -65,6 +80,14 @@ export declare function checkRegistryConflicts(cwd: string): CheckResult[];
|
|
|
65
80
|
* Check for dangerous installDir configuration
|
|
66
81
|
*/
|
|
67
82
|
export declare function checkInstallDir(cwd: string): CheckResult | null;
|
|
83
|
+
/**
|
|
84
|
+
* Check for invalid installMode configuration
|
|
85
|
+
*/
|
|
86
|
+
export declare function checkInstallMode(cwd: string): CheckResult | null;
|
|
87
|
+
/**
|
|
88
|
+
* Check for invalid publishRegistry configuration
|
|
89
|
+
*/
|
|
90
|
+
export declare function checkPublishRegistry(cwd: string): CheckResult | null;
|
|
68
91
|
/**
|
|
69
92
|
* Check for invalid targetAgents configuration
|
|
70
93
|
*/
|
|
@@ -95,6 +118,17 @@ export interface SkillIssue {
|
|
|
95
118
|
* Only checks for SKILL.md since that's the sole source of metadata
|
|
96
119
|
*/
|
|
97
120
|
export declare function checkInstalledSkills(cwd: string): CheckResult[];
|
|
121
|
+
/**
|
|
122
|
+
* Check detected agents
|
|
123
|
+
*/
|
|
124
|
+
export declare function checkDetectedAgents(): Promise<CheckResult>;
|
|
125
|
+
/**
|
|
126
|
+
* Get custom registry URLs for network checks
|
|
127
|
+
*
|
|
128
|
+
* Reads registries from skills.json and publishRegistry,
|
|
129
|
+
* excluding built-in github.com/gitlab.com and deduplicating.
|
|
130
|
+
*/
|
|
131
|
+
export declare function getCustomRegistryUrls(cwd: string): string[];
|
|
98
132
|
/**
|
|
99
133
|
* Check network connectivity
|
|
100
134
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -5237,6 +5237,133 @@ class RegistryResolver {
|
|
|
5237
5237
|
}
|
|
5238
5238
|
return false;
|
|
5239
5239
|
}
|
|
5240
|
+
/**
|
|
5241
|
+
* AuthManager - Handle authentication token management
|
|
5242
|
+
*
|
|
5243
|
+
* Manages tokens for registry authentication.
|
|
5244
|
+
* Tokens are stored in ~/.reskillrc or via RESKILL_TOKEN environment variable.
|
|
5245
|
+
*/ // ============================================================================
|
|
5246
|
+
// Constants
|
|
5247
|
+
// ============================================================================
|
|
5248
|
+
const CONFIG_FILE_NAME = '.reskillrc';
|
|
5249
|
+
// ============================================================================
|
|
5250
|
+
// AuthManager Class
|
|
5251
|
+
// ============================================================================
|
|
5252
|
+
class AuthManager {
|
|
5253
|
+
configPath;
|
|
5254
|
+
constructor(){
|
|
5255
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
5256
|
+
this.configPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(home, CONFIG_FILE_NAME);
|
|
5257
|
+
}
|
|
5258
|
+
/**
|
|
5259
|
+
* Get the default registry URL from environment variable
|
|
5260
|
+
*
|
|
5261
|
+
* Returns undefined if no registry is configured - there is no hardcoded default
|
|
5262
|
+
* to prevent accidental publishing to unintended registries.
|
|
5263
|
+
*/ getDefaultRegistry() {
|
|
5264
|
+
return process.env.RESKILL_REGISTRY;
|
|
5265
|
+
}
|
|
5266
|
+
/**
|
|
5267
|
+
* Get path to config file
|
|
5268
|
+
*/ getConfigPath() {
|
|
5269
|
+
return this.configPath;
|
|
5270
|
+
}
|
|
5271
|
+
/**
|
|
5272
|
+
* Get token for a registry
|
|
5273
|
+
*
|
|
5274
|
+
* Priority:
|
|
5275
|
+
* 1. RESKILL_TOKEN environment variable
|
|
5276
|
+
* 2. Token from ~/.reskillrc for the specified registry
|
|
5277
|
+
*/ getToken(registry) {
|
|
5278
|
+
// Check environment variable first
|
|
5279
|
+
const envToken = process.env.RESKILL_TOKEN;
|
|
5280
|
+
if (envToken) return envToken;
|
|
5281
|
+
// Read from config file
|
|
5282
|
+
const config = this.readConfig();
|
|
5283
|
+
if (!config?.registries) return;
|
|
5284
|
+
const targetRegistry = registry || this.getDefaultRegistry();
|
|
5285
|
+
if (!targetRegistry) return;
|
|
5286
|
+
const auth = config.registries[targetRegistry];
|
|
5287
|
+
return auth?.token;
|
|
5288
|
+
}
|
|
5289
|
+
/**
|
|
5290
|
+
* Check if token exists for a registry
|
|
5291
|
+
*/ hasToken(registry) {
|
|
5292
|
+
return void 0 !== this.getToken(registry);
|
|
5293
|
+
}
|
|
5294
|
+
/**
|
|
5295
|
+
* Get email for a registry
|
|
5296
|
+
*/ getEmail(registry) {
|
|
5297
|
+
const config = this.readConfig();
|
|
5298
|
+
if (!config?.registries) return;
|
|
5299
|
+
const targetRegistry = registry || this.getDefaultRegistry();
|
|
5300
|
+
if (!targetRegistry) return;
|
|
5301
|
+
const auth = config.registries[targetRegistry];
|
|
5302
|
+
return auth?.email;
|
|
5303
|
+
}
|
|
5304
|
+
/**
|
|
5305
|
+
* Get handle for a registry
|
|
5306
|
+
*/ getHandle(registry) {
|
|
5307
|
+
const config = this.readConfig();
|
|
5308
|
+
if (!config?.registries) return;
|
|
5309
|
+
const targetRegistry = registry || this.getDefaultRegistry();
|
|
5310
|
+
if (!targetRegistry) return;
|
|
5311
|
+
const auth = config.registries[targetRegistry];
|
|
5312
|
+
return auth?.handle;
|
|
5313
|
+
}
|
|
5314
|
+
/**
|
|
5315
|
+
* Set token for a registry
|
|
5316
|
+
*
|
|
5317
|
+
* Note: When no registry is specified and RESKILL_REGISTRY env var is not set,
|
|
5318
|
+
* this method will throw an error. The calling code should ensure a registry
|
|
5319
|
+
* is always provided (either explicitly or via environment variable).
|
|
5320
|
+
*/ setToken(token, registry, email, handle) {
|
|
5321
|
+
const config = this.readConfig() || {};
|
|
5322
|
+
const targetRegistry = registry || this.getDefaultRegistry();
|
|
5323
|
+
if (!targetRegistry) throw new Error('No registry specified. Set RESKILL_REGISTRY environment variable or provide registry explicitly.');
|
|
5324
|
+
if (!config.registries) config.registries = {};
|
|
5325
|
+
config.registries[targetRegistry] = {
|
|
5326
|
+
token,
|
|
5327
|
+
...email && {
|
|
5328
|
+
email
|
|
5329
|
+
},
|
|
5330
|
+
...handle && {
|
|
5331
|
+
handle
|
|
5332
|
+
}
|
|
5333
|
+
};
|
|
5334
|
+
this.writeConfig(config);
|
|
5335
|
+
}
|
|
5336
|
+
/**
|
|
5337
|
+
* Remove token for a registry
|
|
5338
|
+
*/ removeToken(registry) {
|
|
5339
|
+
const config = this.readConfig();
|
|
5340
|
+
if (!config?.registries) return;
|
|
5341
|
+
const targetRegistry = registry || this.getDefaultRegistry();
|
|
5342
|
+
if (!targetRegistry) return;
|
|
5343
|
+
delete config.registries[targetRegistry];
|
|
5344
|
+
this.writeConfig(config);
|
|
5345
|
+
}
|
|
5346
|
+
/**
|
|
5347
|
+
* Read config file
|
|
5348
|
+
*/ readConfig() {
|
|
5349
|
+
try {
|
|
5350
|
+
if (!external_node_fs_.existsSync(this.configPath)) return null;
|
|
5351
|
+
const content = external_node_fs_.readFileSync(this.configPath, 'utf-8');
|
|
5352
|
+
if (!content.trim()) return null;
|
|
5353
|
+
return JSON.parse(content);
|
|
5354
|
+
} catch {
|
|
5355
|
+
return null;
|
|
5356
|
+
}
|
|
5357
|
+
}
|
|
5358
|
+
/**
|
|
5359
|
+
* Write config file
|
|
5360
|
+
*/ writeConfig(config) {
|
|
5361
|
+
const content = JSON.stringify(config, null, 2);
|
|
5362
|
+
external_node_fs_.writeFileSync(this.configPath, content, {
|
|
5363
|
+
mode: 384
|
|
5364
|
+
});
|
|
5365
|
+
}
|
|
5366
|
+
}
|
|
5240
5367
|
/**
|
|
5241
5368
|
* Get status icon
|
|
5242
5369
|
*/ function getStatusIcon(status) {
|
|
@@ -5444,6 +5571,73 @@ class RegistryResolver {
|
|
|
5444
5571
|
hint: 'For private repos, add SSH key: ssh-keygen -t ed25519'
|
|
5445
5572
|
};
|
|
5446
5573
|
}
|
|
5574
|
+
/**
|
|
5575
|
+
* Valid install modes
|
|
5576
|
+
*
|
|
5577
|
+
* Must stay in sync with InstallMode type from installer.ts ('symlink' | 'copy').
|
|
5578
|
+
* TypeScript literal union types are erased at runtime, so we maintain this list manually.
|
|
5579
|
+
*/ const VALID_INSTALL_MODES = [
|
|
5580
|
+
'symlink',
|
|
5581
|
+
'copy'
|
|
5582
|
+
];
|
|
5583
|
+
/**
|
|
5584
|
+
* Check registry authentication status
|
|
5585
|
+
*
|
|
5586
|
+
* Verifies actual token availability, not just file existence.
|
|
5587
|
+
* Uses AuthManager.getToken() which checks RESKILL_TOKEN env first,
|
|
5588
|
+
* then reads ~/.reskillrc for the configured registry.
|
|
5589
|
+
*/ function checkAuthStatus() {
|
|
5590
|
+
const hasEnvToken = !!process.env.RESKILL_TOKEN;
|
|
5591
|
+
if (hasEnvToken) return {
|
|
5592
|
+
name: 'Registry auth',
|
|
5593
|
+
status: 'ok',
|
|
5594
|
+
message: 'RESKILL_TOKEN set'
|
|
5595
|
+
};
|
|
5596
|
+
// Check if ~/.reskillrc has any valid tokens
|
|
5597
|
+
const authManager = new AuthManager();
|
|
5598
|
+
const configPath = authManager.getConfigPath();
|
|
5599
|
+
if (!(0, external_node_fs_.existsSync)(configPath)) return {
|
|
5600
|
+
name: 'Registry auth',
|
|
5601
|
+
status: 'warn',
|
|
5602
|
+
message: 'no token configured',
|
|
5603
|
+
hint: 'Run: reskill login (needed for publish and private skills)'
|
|
5604
|
+
};
|
|
5605
|
+
// File exists — check if it actually contains a token for any registry
|
|
5606
|
+
const hasToken = authManager.hasToken();
|
|
5607
|
+
if (hasToken) return {
|
|
5608
|
+
name: 'Registry auth',
|
|
5609
|
+
status: 'ok',
|
|
5610
|
+
message: 'token configured via ~/.reskillrc'
|
|
5611
|
+
};
|
|
5612
|
+
return {
|
|
5613
|
+
name: 'Registry auth',
|
|
5614
|
+
status: 'warn',
|
|
5615
|
+
message: '~/.reskillrc exists but no token found for current registry',
|
|
5616
|
+
hint: 'Run: reskill login (needed for publish and private skills)'
|
|
5617
|
+
};
|
|
5618
|
+
}
|
|
5619
|
+
/**
|
|
5620
|
+
* Check environment variables used by reskill
|
|
5621
|
+
*
|
|
5622
|
+
* Security: Only report variable names, never values.
|
|
5623
|
+
* RESKILL_TOKEN contains a secret and must not be displayed.
|
|
5624
|
+
*/ function checkEnvVars() {
|
|
5625
|
+
// Only collect names, never values (RESKILL_TOKEN is a secret)
|
|
5626
|
+
const vars = [];
|
|
5627
|
+
if (process.env.RESKILL_TOKEN) vars.push('RESKILL_TOKEN');
|
|
5628
|
+
if (process.env.RESKILL_REGISTRY) vars.push('RESKILL_REGISTRY');
|
|
5629
|
+
if (process.env.RESKILL_CACHE_DIR) vars.push('RESKILL_CACHE_DIR');
|
|
5630
|
+
if (0 === vars.length) return {
|
|
5631
|
+
name: 'Environment vars',
|
|
5632
|
+
status: 'ok',
|
|
5633
|
+
message: 'none set'
|
|
5634
|
+
};
|
|
5635
|
+
return {
|
|
5636
|
+
name: 'Environment vars',
|
|
5637
|
+
status: 'ok',
|
|
5638
|
+
message: `${vars.join(', ')} set`
|
|
5639
|
+
};
|
|
5640
|
+
}
|
|
5447
5641
|
/**
|
|
5448
5642
|
* Check cache directory
|
|
5449
5643
|
*/ function checkCacheDir() {
|
|
@@ -5535,12 +5729,21 @@ class RegistryResolver {
|
|
|
5535
5729
|
try {
|
|
5536
5730
|
const config = configLoader.load();
|
|
5537
5731
|
const registries = config.registries || {};
|
|
5538
|
-
for (const name of Object.
|
|
5539
|
-
name
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5732
|
+
for (const [name, url] of Object.entries(registries)){
|
|
5733
|
+
if (RESERVED_REGISTRIES.includes(name.toLowerCase())) results.push({
|
|
5734
|
+
name: 'Registry conflict',
|
|
5735
|
+
status: 'warn',
|
|
5736
|
+
message: `"${name}" overrides built-in registry`,
|
|
5737
|
+
hint: 'Consider using a different name for custom registries'
|
|
5738
|
+
});
|
|
5739
|
+
// Validate URL format
|
|
5740
|
+
if ('string' == typeof url && !/^https?:\/\//.test(url)) results.push({
|
|
5741
|
+
name: 'Invalid registry URL',
|
|
5742
|
+
status: 'error',
|
|
5743
|
+
message: `"${name}": "${url}" is not a valid URL`,
|
|
5744
|
+
hint: 'Registry URLs must start with http:// or https://'
|
|
5745
|
+
});
|
|
5746
|
+
}
|
|
5544
5747
|
} catch {
|
|
5545
5748
|
// Ignore parse errors, handled by checkSkillsJson
|
|
5546
5749
|
}
|
|
@@ -5575,6 +5778,46 @@ class RegistryResolver {
|
|
|
5575
5778
|
}
|
|
5576
5779
|
return null;
|
|
5577
5780
|
}
|
|
5781
|
+
/**
|
|
5782
|
+
* Check for invalid installMode configuration
|
|
5783
|
+
*/ function checkInstallMode(cwd) {
|
|
5784
|
+
const configLoader = new ConfigLoader(cwd);
|
|
5785
|
+
if (!configLoader.exists()) return null;
|
|
5786
|
+
try {
|
|
5787
|
+
const defaults = configLoader.getDefaults();
|
|
5788
|
+
const installMode = defaults.installMode;
|
|
5789
|
+
if (!installMode) return null;
|
|
5790
|
+
if (!VALID_INSTALL_MODES.includes(installMode)) return {
|
|
5791
|
+
name: 'Invalid installMode',
|
|
5792
|
+
status: 'error',
|
|
5793
|
+
message: `"${installMode}" is not a valid install mode`,
|
|
5794
|
+
hint: 'Valid values: symlink, copy'
|
|
5795
|
+
};
|
|
5796
|
+
} catch {
|
|
5797
|
+
// Ignore parse errors
|
|
5798
|
+
}
|
|
5799
|
+
return null;
|
|
5800
|
+
}
|
|
5801
|
+
/**
|
|
5802
|
+
* Check for invalid publishRegistry configuration
|
|
5803
|
+
*/ function checkPublishRegistry(cwd) {
|
|
5804
|
+
const configLoader = new ConfigLoader(cwd);
|
|
5805
|
+
if (!configLoader.exists()) return null;
|
|
5806
|
+
try {
|
|
5807
|
+
const defaults = configLoader.getDefaults();
|
|
5808
|
+
const publishRegistry = defaults.publishRegistry;
|
|
5809
|
+
if (!publishRegistry) return null;
|
|
5810
|
+
if (!/^https?:\/\//.test(publishRegistry)) return {
|
|
5811
|
+
name: 'Invalid publishRegistry',
|
|
5812
|
+
status: 'warn',
|
|
5813
|
+
message: `"${publishRegistry}" is not a valid URL`,
|
|
5814
|
+
hint: 'publishRegistry must start with http:// or https://'
|
|
5815
|
+
};
|
|
5816
|
+
} catch {
|
|
5817
|
+
// Ignore parse errors
|
|
5818
|
+
}
|
|
5819
|
+
return null;
|
|
5820
|
+
}
|
|
5578
5821
|
/**
|
|
5579
5822
|
* Check for invalid targetAgents configuration
|
|
5580
5823
|
*/ function checkTargetAgents(cwd) {
|
|
@@ -5711,6 +5954,15 @@ class RegistryResolver {
|
|
|
5711
5954
|
hint: 'Run: reskill install'
|
|
5712
5955
|
};
|
|
5713
5956
|
}
|
|
5957
|
+
// Check lockfile version compatibility before sync check
|
|
5958
|
+
// If version is unsupported, sync results would be meaningless
|
|
5959
|
+
const lockData = lockManager.load();
|
|
5960
|
+
if (lockData.lockfileVersion !== LOCKFILE_VERSION) return {
|
|
5961
|
+
name: 'skills.lock',
|
|
5962
|
+
status: 'warn',
|
|
5963
|
+
message: `unsupported lockfile version: ${lockData.lockfileVersion}`,
|
|
5964
|
+
hint: 'Run: reskill install to regenerate'
|
|
5965
|
+
};
|
|
5714
5966
|
// Check if lock is in sync with config
|
|
5715
5967
|
const configSkills = configLoader.getSkills();
|
|
5716
5968
|
const lockedSkills = lockManager.getAll();
|
|
@@ -5821,6 +6073,66 @@ class RegistryResolver {
|
|
|
5821
6073
|
}
|
|
5822
6074
|
return results;
|
|
5823
6075
|
}
|
|
6076
|
+
/**
|
|
6077
|
+
* Check detected agents
|
|
6078
|
+
*/ async function checkDetectedAgents() {
|
|
6079
|
+
try {
|
|
6080
|
+
const installed = await detectInstalledAgents();
|
|
6081
|
+
if (0 === installed.length) return {
|
|
6082
|
+
name: 'Detected agents',
|
|
6083
|
+
status: 'ok',
|
|
6084
|
+
message: 'none detected'
|
|
6085
|
+
};
|
|
6086
|
+
return {
|
|
6087
|
+
name: 'Detected agents',
|
|
6088
|
+
status: 'ok',
|
|
6089
|
+
message: `${installed.length} detected: ${installed.join(', ')}`
|
|
6090
|
+
};
|
|
6091
|
+
} catch {
|
|
6092
|
+
return {
|
|
6093
|
+
name: 'Detected agents',
|
|
6094
|
+
status: 'warn',
|
|
6095
|
+
message: 'detection failed'
|
|
6096
|
+
};
|
|
6097
|
+
}
|
|
6098
|
+
}
|
|
6099
|
+
/**
|
|
6100
|
+
* Normalize a URL to its origin for comparison.
|
|
6101
|
+
* Handles trailing slashes and case differences (e.g., GITHUB.COM → github.com).
|
|
6102
|
+
*/ function normalizeUrlOrigin(url) {
|
|
6103
|
+
try {
|
|
6104
|
+
return new URL(url).origin;
|
|
6105
|
+
} catch {
|
|
6106
|
+
return url;
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
6109
|
+
/**
|
|
6110
|
+
* Get custom registry URLs for network checks
|
|
6111
|
+
*
|
|
6112
|
+
* Reads registries from skills.json and publishRegistry,
|
|
6113
|
+
* excluding built-in github.com/gitlab.com and deduplicating.
|
|
6114
|
+
*/ function getCustomRegistryUrls(cwd) {
|
|
6115
|
+
const urls = new Set();
|
|
6116
|
+
const builtinOrigins = new Set(Object.values(DEFAULT_REGISTRIES).map((u)=>normalizeUrlOrigin(u)));
|
|
6117
|
+
try {
|
|
6118
|
+
const configLoader = new ConfigLoader(cwd);
|
|
6119
|
+
if (!configLoader.exists()) return [];
|
|
6120
|
+
// Collect custom registry URLs
|
|
6121
|
+
const config = configLoader.load();
|
|
6122
|
+
const registries = config.registries || {};
|
|
6123
|
+
for (const url of Object.values(registries))if ('string' == typeof url && /^https?:\/\//.test(url) && !builtinOrigins.has(normalizeUrlOrigin(url))) urls.add(url);
|
|
6124
|
+
// Collect publishRegistry
|
|
6125
|
+
const defaults = configLoader.getDefaults();
|
|
6126
|
+
if (defaults.publishRegistry && /^https?:\/\//.test(defaults.publishRegistry)) {
|
|
6127
|
+
if (!builtinOrigins.has(normalizeUrlOrigin(defaults.publishRegistry))) urls.add(defaults.publishRegistry);
|
|
6128
|
+
}
|
|
6129
|
+
} catch {
|
|
6130
|
+
// Ignore errors
|
|
6131
|
+
}
|
|
6132
|
+
return [
|
|
6133
|
+
...urls
|
|
6134
|
+
];
|
|
6135
|
+
}
|
|
5824
6136
|
/**
|
|
5825
6137
|
* Check network connectivity
|
|
5826
6138
|
*/ async function checkNetwork(host) {
|
|
@@ -5867,23 +6179,32 @@ class RegistryResolver {
|
|
|
5867
6179
|
*/ async function runDoctorChecks(options) {
|
|
5868
6180
|
const { cwd, packageName, packageVersion, skipNetwork, skipConfigChecks } = options;
|
|
5869
6181
|
const results = [];
|
|
5870
|
-
//
|
|
6182
|
+
// Environment checks
|
|
5871
6183
|
results.push(await checkReskillVersion(packageVersion, packageName));
|
|
5872
6184
|
results.push(checkNodeVersion());
|
|
5873
6185
|
results.push(checkGitVersion());
|
|
5874
6186
|
results.push(checkGitAuth());
|
|
6187
|
+
results.push(checkAuthStatus());
|
|
6188
|
+
results.push(checkEnvVars());
|
|
5875
6189
|
// Directory checks
|
|
5876
6190
|
results.push(checkCacheDir());
|
|
5877
6191
|
results.push(checkSkillsJson(cwd));
|
|
5878
6192
|
results.push(checkSkillsLock(cwd));
|
|
5879
6193
|
results.push(...checkInstalledSkills(cwd));
|
|
6194
|
+
results.push(await checkDetectedAgents());
|
|
5880
6195
|
// Deep config checks (can be skipped for faster checks)
|
|
5881
6196
|
if (!skipConfigChecks) {
|
|
5882
|
-
// Registry conflicts
|
|
6197
|
+
// Registry conflicts + URL validation
|
|
5883
6198
|
results.push(...checkRegistryConflicts(cwd));
|
|
5884
6199
|
// installDir validation
|
|
5885
6200
|
const installDirCheck = checkInstallDir(cwd);
|
|
5886
6201
|
if (installDirCheck) results.push(installDirCheck);
|
|
6202
|
+
// installMode validation
|
|
6203
|
+
const installModeCheck = checkInstallMode(cwd);
|
|
6204
|
+
if (installModeCheck) results.push(installModeCheck);
|
|
6205
|
+
// publishRegistry validation
|
|
6206
|
+
const publishRegistryCheck = checkPublishRegistry(cwd);
|
|
6207
|
+
if (publishRegistryCheck) results.push(publishRegistryCheck);
|
|
5887
6208
|
// targetAgents validation
|
|
5888
6209
|
results.push(...checkTargetAgents(cwd));
|
|
5889
6210
|
// Skill reference format validation
|
|
@@ -5895,6 +6216,9 @@ class RegistryResolver {
|
|
|
5895
6216
|
if (!skipNetwork) {
|
|
5896
6217
|
results.push(await checkNetwork('https://github.com'));
|
|
5897
6218
|
results.push(await checkNetwork('https://gitlab.com'));
|
|
6219
|
+
// Custom registry connectivity
|
|
6220
|
+
const customUrls = getCustomRegistryUrls(cwd);
|
|
6221
|
+
for (const url of customUrls)results.push(await checkNetwork(url));
|
|
5898
6222
|
}
|
|
5899
6223
|
return results;
|
|
5900
6224
|
}
|
|
@@ -6191,133 +6515,6 @@ const DEFAULT_INSTALL_DIR = '.skills';
|
|
|
6191
6515
|
// Display summary (use options.installDir directly since we just set it)
|
|
6192
6516
|
displayConfigSummary(options.installDir);
|
|
6193
6517
|
});
|
|
6194
|
-
/**
|
|
6195
|
-
* AuthManager - Handle authentication token management
|
|
6196
|
-
*
|
|
6197
|
-
* Manages tokens for registry authentication.
|
|
6198
|
-
* Tokens are stored in ~/.reskillrc or via RESKILL_TOKEN environment variable.
|
|
6199
|
-
*/ // ============================================================================
|
|
6200
|
-
// Constants
|
|
6201
|
-
// ============================================================================
|
|
6202
|
-
const CONFIG_FILE_NAME = '.reskillrc';
|
|
6203
|
-
// ============================================================================
|
|
6204
|
-
// AuthManager Class
|
|
6205
|
-
// ============================================================================
|
|
6206
|
-
class AuthManager {
|
|
6207
|
-
configPath;
|
|
6208
|
-
constructor(){
|
|
6209
|
-
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
6210
|
-
this.configPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(home, CONFIG_FILE_NAME);
|
|
6211
|
-
}
|
|
6212
|
-
/**
|
|
6213
|
-
* Get the default registry URL from environment variable
|
|
6214
|
-
*
|
|
6215
|
-
* Returns undefined if no registry is configured - there is no hardcoded default
|
|
6216
|
-
* to prevent accidental publishing to unintended registries.
|
|
6217
|
-
*/ getDefaultRegistry() {
|
|
6218
|
-
return process.env.RESKILL_REGISTRY;
|
|
6219
|
-
}
|
|
6220
|
-
/**
|
|
6221
|
-
* Get path to config file
|
|
6222
|
-
*/ getConfigPath() {
|
|
6223
|
-
return this.configPath;
|
|
6224
|
-
}
|
|
6225
|
-
/**
|
|
6226
|
-
* Get token for a registry
|
|
6227
|
-
*
|
|
6228
|
-
* Priority:
|
|
6229
|
-
* 1. RESKILL_TOKEN environment variable
|
|
6230
|
-
* 2. Token from ~/.reskillrc for the specified registry
|
|
6231
|
-
*/ getToken(registry) {
|
|
6232
|
-
// Check environment variable first
|
|
6233
|
-
const envToken = process.env.RESKILL_TOKEN;
|
|
6234
|
-
if (envToken) return envToken;
|
|
6235
|
-
// Read from config file
|
|
6236
|
-
const config = this.readConfig();
|
|
6237
|
-
if (!config?.registries) return;
|
|
6238
|
-
const targetRegistry = registry || this.getDefaultRegistry();
|
|
6239
|
-
if (!targetRegistry) return;
|
|
6240
|
-
const auth = config.registries[targetRegistry];
|
|
6241
|
-
return auth?.token;
|
|
6242
|
-
}
|
|
6243
|
-
/**
|
|
6244
|
-
* Check if token exists for a registry
|
|
6245
|
-
*/ hasToken(registry) {
|
|
6246
|
-
return void 0 !== this.getToken(registry);
|
|
6247
|
-
}
|
|
6248
|
-
/**
|
|
6249
|
-
* Get email for a registry
|
|
6250
|
-
*/ getEmail(registry) {
|
|
6251
|
-
const config = this.readConfig();
|
|
6252
|
-
if (!config?.registries) return;
|
|
6253
|
-
const targetRegistry = registry || this.getDefaultRegistry();
|
|
6254
|
-
if (!targetRegistry) return;
|
|
6255
|
-
const auth = config.registries[targetRegistry];
|
|
6256
|
-
return auth?.email;
|
|
6257
|
-
}
|
|
6258
|
-
/**
|
|
6259
|
-
* Get handle for a registry
|
|
6260
|
-
*/ getHandle(registry) {
|
|
6261
|
-
const config = this.readConfig();
|
|
6262
|
-
if (!config?.registries) return;
|
|
6263
|
-
const targetRegistry = registry || this.getDefaultRegistry();
|
|
6264
|
-
if (!targetRegistry) return;
|
|
6265
|
-
const auth = config.registries[targetRegistry];
|
|
6266
|
-
return auth?.handle;
|
|
6267
|
-
}
|
|
6268
|
-
/**
|
|
6269
|
-
* Set token for a registry
|
|
6270
|
-
*
|
|
6271
|
-
* Note: When no registry is specified and RESKILL_REGISTRY env var is not set,
|
|
6272
|
-
* this method will throw an error. The calling code should ensure a registry
|
|
6273
|
-
* is always provided (either explicitly or via environment variable).
|
|
6274
|
-
*/ setToken(token, registry, email, handle) {
|
|
6275
|
-
const config = this.readConfig() || {};
|
|
6276
|
-
const targetRegistry = registry || this.getDefaultRegistry();
|
|
6277
|
-
if (!targetRegistry) throw new Error('No registry specified. Set RESKILL_REGISTRY environment variable or provide registry explicitly.');
|
|
6278
|
-
if (!config.registries) config.registries = {};
|
|
6279
|
-
config.registries[targetRegistry] = {
|
|
6280
|
-
token,
|
|
6281
|
-
...email && {
|
|
6282
|
-
email
|
|
6283
|
-
},
|
|
6284
|
-
...handle && {
|
|
6285
|
-
handle
|
|
6286
|
-
}
|
|
6287
|
-
};
|
|
6288
|
-
this.writeConfig(config);
|
|
6289
|
-
}
|
|
6290
|
-
/**
|
|
6291
|
-
* Remove token for a registry
|
|
6292
|
-
*/ removeToken(registry) {
|
|
6293
|
-
const config = this.readConfig();
|
|
6294
|
-
if (!config?.registries) return;
|
|
6295
|
-
const targetRegistry = registry || this.getDefaultRegistry();
|
|
6296
|
-
if (!targetRegistry) return;
|
|
6297
|
-
delete config.registries[targetRegistry];
|
|
6298
|
-
this.writeConfig(config);
|
|
6299
|
-
}
|
|
6300
|
-
/**
|
|
6301
|
-
* Read config file
|
|
6302
|
-
*/ readConfig() {
|
|
6303
|
-
try {
|
|
6304
|
-
if (!external_node_fs_.existsSync(this.configPath)) return null;
|
|
6305
|
-
const content = external_node_fs_.readFileSync(this.configPath, 'utf-8');
|
|
6306
|
-
if (!content.trim()) return null;
|
|
6307
|
-
return JSON.parse(content);
|
|
6308
|
-
} catch {
|
|
6309
|
-
return null;
|
|
6310
|
-
}
|
|
6311
|
-
}
|
|
6312
|
-
/**
|
|
6313
|
-
* Write config file
|
|
6314
|
-
*/ writeConfig(config) {
|
|
6315
|
-
const content = JSON.stringify(config, null, 2);
|
|
6316
|
-
external_node_fs_.writeFileSync(this.configPath, content, {
|
|
6317
|
-
mode: 384
|
|
6318
|
-
});
|
|
6319
|
-
}
|
|
6320
|
-
}
|
|
6321
6518
|
// ============================================================================
|
|
6322
6519
|
// Utility Functions
|
|
6323
6520
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock-manager.d.ts","sourceRoot":"","sources":["../../src/core/lock-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"lock-manager.d.ts","sourceRoot":"","sources":["../../src/core/lock-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGjE;;GAEG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAA2B;gBAE/B,WAAW,CAAC,EAAE,MAAM;IAKhC;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,IAAI,IAAI,UAAU;IAsBlB;;OAEG;IACH,MAAM,IAAI,UAAU;IAKpB;;OAEG;IACH,IAAI,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI;IASnC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAK1C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI;IAM3C;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAU7B;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GACA,WAAW;IAmBd;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC;IAKrC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAK1B;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAQtD;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,MAAM,IAAI,IAAI;CAOf;AAED,eAAe,WAAW,CAAC"}
|