@sysprompthub/cli 0.1.0 → 1.0.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.
package/README.md CHANGED
@@ -12,78 +12,68 @@ npm install -g @sysprompthub/cli
12
12
 
13
13
  ## CLI Usage
14
14
 
15
- ### Sync Command
15
+ ### Init Command
16
16
 
17
- Sync a prompt pack to your project:
17
+ Initialize SysPromptHub configuration for your project:
18
18
 
19
19
  ```bash
20
- # Basic usage
21
- sysprompthub sync user/pack/latest
20
+ sysprompthub init
21
+ ```
22
22
 
23
- # Specify assistants
24
- sysprompthub sync user/pack/123 --copilot --claude
23
+ This interactive command will:
24
+ 1. Prompt for your API key (stored in `~/.sysprompthub/config.json`)
25
+ 2. Let you search and select a prompt pack
26
+ 3. Let you select your AI assistants (Copilot, Claude, or custom path)
27
+ 4. Save workspace configuration to `.sysprompthub.json`
25
28
 
26
- # Output to stdout instead of writing files
27
- sysprompthub sync user/pack/latest --stdout
29
+ ### Sync Command
28
30
 
29
- # Use custom API URL
30
- sysprompthub sync user/pack/latest --api-url https://api.custom.com
31
+ Sync prompts from your configured pack:
31
32
 
32
- # Use custom working directory
33
- sysprompthub sync user/pack/latest --cwd /path/to/project
33
+ ```bash
34
+ sysprompthub sync
34
35
  ```
35
36
 
36
- ### Init Command
37
+ Options:
38
+ - `-e, --environment <ENV>` - API environment to use (local, development, staging, production)
37
39
 
38
- Create a `.sysprompthub.json` configuration file:
40
+ ### Configuration
39
41
 
40
- ```bash
41
- # Interactive setup
42
- sysprompthub init
43
-
44
- # With options
45
- sysprompthub init --pack user/pack/latest --copilot --claude
42
+ #### User-level Config (`~/.sysprompthub/config.json`)
43
+ Stores your API key:
44
+ ```json
45
+ {
46
+ "apiKey": "your-40-character-api-key"
47
+ }
46
48
  ```
47
49
 
48
- ### Configuration File
49
-
50
- Create a `.sysprompthub.json` file in your project root:
51
-
50
+ #### Workspace-level Config (`.sysprompthub.json`)
51
+ Stores project-specific settings:
52
52
  ```json
53
53
  {
54
- "packName": "user/pack/latest",
54
+ "packName": "owner/pack/latest",
55
55
  "assistants": ["copilot", "claude"],
56
- "apiUrl": "https://api-dev.sysprompthub.com"
56
+ "environment": "production"
57
57
  }
58
58
  ```
59
59
 
60
- When a config file exists, you can run `sysprompthub sync` without arguments.
61
-
62
- ## SDK Usage
63
-
64
- For programmatic usage in your Node.js applications, use the [@sysprompthub/sdk](../nodejs_sdk) package:
65
-
66
- ```bash
67
- npm install @sysprompthub/sdk
60
+ You can also use a custom path instead of assistants:
61
+ ```json
62
+ {
63
+ "packName": "owner/pack/latest",
64
+ "path": "prompts/system-prompt.md"
65
+ }
68
66
  ```
69
67
 
70
- See the [SDK documentation](../nodejs_sdk/README.md) for API details.
71
-
72
- ## Development
68
+ ## Workflow
73
69
 
74
- ```bash
75
- # Install dependencies
76
- npm install
77
-
78
- # Build
79
- npm run build
70
+ 1. **First time setup**: Run `sysprompthub init` to configure your API key and project
71
+ 2. **Sync prompts**: Run `sysprompthub sync` to download and install prompts
72
+ 3. **Update**: Run `sysprompthub init` again to change configuration
80
73
 
81
- # Type check
82
- npm run typecheck
74
+ ## Contributing
83
75
 
84
- # Run CLI in development
85
- npm run dev -- sync user/pack/latest
86
- ```
76
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for development instructions.
87
77
 
88
78
  ## License
89
79
 
@@ -0,0 +1,6 @@
1
+ import { Option } from "commander";
2
+ export class BaseCommand {
3
+ static envOption = new Option('-e, --environment [env]')
4
+ .choices(['production', 'development', 'local'])
5
+ .env('SYSPROMPTHUB_ENVIRONMENT');
6
+ }
@@ -1,60 +1,184 @@
1
+ import { checkbox, confirm, input, search } from '@inquirer/prompts';
1
2
  import { Command } from 'commander';
2
- import { writeFile } from 'fs/promises';
3
- import { join } from 'path';
4
- import { CONFIG_FILE_NAME, VscodeConfigManager } from '@sysprompthub/sdk';
5
- function getAssistants(copilot, claude) {
6
- const assistants = [];
7
- if (copilot)
8
- assistants.push('copilot');
9
- if (claude)
10
- assistants.push('claude');
11
- return assistants.length > 0 ? assistants : ['copilot'];
12
- }
13
- export function createInitCommand() {
14
- const command = new Command('init');
15
- command
16
- .description('Initialize a .sysprompthub.json config file')
17
- .option('--pack <name>', 'Prompt pack name')
18
- .option('--copilot', 'Enable GitHub Copilot', false)
19
- .option('--claude', 'Enable Claude', false)
20
- .option('--environment <env>', 'Environment (local or development)', 'development')
21
- .option('--vscode', 'Create .vscode/settings.json instead of .sysprompthub.json', false)
22
- .option('--cwd <dir>', 'Working directory', process.cwd())
23
- .action(async (options) => {
24
- try {
25
- if (options.vscode) {
26
- const vscodeManager = new VscodeConfigManager(options.cwd);
27
- const settings = await vscodeManager.init({
28
- pack: options.pack,
29
- copilot: options.copilot,
30
- claude: options.claude,
31
- environment: options.environment
32
- });
33
- console.log(`✓ Created .vscode/settings.json`);
34
- console.log(JSON.stringify(settings, null, 2));
3
+ import { API_KEY_LENGTH, AssistantManager, DefaultConfigManager, NodeFileSystem, SysPromptHubClient, UserConfigManager } from '@sysprompthub/sdk';
4
+ import { isAbsolute } from 'path';
5
+ import isValidPath from 'is-valid-path';
6
+ import open from 'open';
7
+ import { BaseCommand } from "./base-command.js";
8
+ export class InitCommand extends BaseCommand {
9
+ fs = new NodeFileSystem();
10
+ workspaceConfigManager = new DefaultConfigManager();
11
+ userConfigManager = new UserConfigManager();
12
+ async run({ environment }) {
13
+ console.log('Welcome to SysPromptHub! Let\'s configure your project.\n');
14
+ // Load existing configs
15
+ const existingUserConfig = await this.userConfigManager.load(this.fs);
16
+ const existingWorkspaceConfig = await this.workspaceConfigManager.load(this.fs) || {};
17
+ // Step 1: API Key (user-level)
18
+ const apiKey = await this.promptForApiKey(existingUserConfig?.apiKey);
19
+ await this.userConfigManager.save(this.fs, { apiKey });
20
+ // Environment
21
+ let workspaceConfig = { ...existingWorkspaceConfig };
22
+ if (environment)
23
+ workspaceConfig.environment = environment;
24
+ // console.info('env', environment, 'ws', workspaceConfig);
25
+ // Step 2: Pack Name (workspace-level)
26
+ const client = new SysPromptHubClient(apiKey, workspaceConfig.environment);
27
+ workspaceConfig.packName = await this.promptForPackName(client, workspaceConfig.packName);
28
+ // Step 3: Assistants (workspace-level)
29
+ workspaceConfig.assistants = await this.promptForAssistants(workspaceConfig.assistants);
30
+ // Step 4: Custom Path (workspace-level, if no assistants selected)
31
+ if (!workspaceConfig.assistants || workspaceConfig.assistants.length === 0) {
32
+ workspaceConfig.path = await this.promptForCustomPath(workspaceConfig.path);
33
+ }
34
+ // Save workspace configuration
35
+ await this.workspaceConfigManager.update(this.fs, workspaceConfig);
36
+ console.log('\n✓ User config saved to ~/.sysprompthub/config.json');
37
+ console.log('✓ Project config saved to .sysprompthub.json');
38
+ console.log('Run "sysprompthub sync" to download your prompts.\n');
39
+ }
40
+ async promptForApiKey(existing) {
41
+ const apiKey = await input({
42
+ message: 'Enter your API key (' + (existing ? 'leave blank to keep existing' : 'leave blank to create one') + '):',
43
+ validate: (value) => {
44
+ if (value.length === 0)
45
+ return true;
46
+ if (value.length !== API_KEY_LENGTH)
47
+ return `API key must be ${API_KEY_LENGTH} characters`;
48
+ return true;
35
49
  }
36
- else {
37
- const config = {
38
- packName: options.pack,
39
- assistants: getAssistants(options.copilot, options.claude),
40
- environment: options.environment
41
- };
42
- const configPath = join(options.cwd, CONFIG_FILE_NAME);
43
- await writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
44
- console.log(`✓ Created ${CONFIG_FILE_NAME}`);
45
- console.log(JSON.stringify(config, null, 2));
50
+ });
51
+ if (apiKey.length === 0 && existing) {
52
+ return existing;
53
+ }
54
+ if (apiKey.length === 0) {
55
+ console.log('\nTo create an API key:');
56
+ console.log('1. Visit https://app.sysprompthub.com/api-keys');
57
+ console.log('2. Create a new API key');
58
+ console.log('3. Copy the key and return here\n');
59
+ const shouldOpen = await confirm({
60
+ message: 'Open your browser now?',
61
+ default: true
62
+ });
63
+ if (shouldOpen) {
64
+ await open('https://app.sysprompthub.com/api-keys');
46
65
  }
66
+ return this.promptForApiKey(existing);
47
67
  }
48
- catch (error) {
49
- if (error instanceof Error) {
50
- console.error(`Error: ${error.message}`);
68
+ return apiKey;
69
+ }
70
+ async promptForPackName(client, existing) {
71
+ if (existing) {
72
+ const keepExisting = await confirm({
73
+ message: `Keep existing pack "${existing}"?`,
74
+ default: true
75
+ });
76
+ if (keepExisting) {
77
+ return existing;
51
78
  }
52
- else {
53
- console.error('An unknown error occurred');
79
+ }
80
+ const searchResults = await search({
81
+ message: 'Select a pack:',
82
+ source: async (term) => {
83
+ if (!term || term.length < 2) {
84
+ return [];
85
+ }
86
+ try {
87
+ const results = await client.searchPacks(term);
88
+ const choices = [];
89
+ for (const result of results) {
90
+ console.info(`Found pack "${JSON.stringify(result)}"`);
91
+ const baseDescription = `Current version: ${result.version}`;
92
+ // Option 1: /latest
93
+ choices.push({
94
+ name: `${result.name}/latest`,
95
+ value: `${result.name}/latest`,
96
+ description: `${baseDescription} (always use latest)`
97
+ });
98
+ // Option 2: /current_version
99
+ choices.push({
100
+ name: `${result.name}/${result.version}`,
101
+ value: `${result.name}/${result.version}`,
102
+ description: `${baseDescription} (pin to current)`
103
+ });
104
+ // Option 3: Custom version
105
+ choices.push({
106
+ name: `${result.name}/[custom version]`,
107
+ value: `custom:${result.name}:${result.version}`,
108
+ description: `${baseDescription} (enter specific version)`
109
+ });
110
+ }
111
+ return choices;
112
+ }
113
+ catch (error) {
114
+ console.error('Error searching for packs:', error);
115
+ return [];
116
+ }
54
117
  }
55
- process.exit(1);
118
+ });
119
+ // Handle custom version selection
120
+ if (searchResults.startsWith('custom:')) {
121
+ const [, fullName, maxVersionStr] = searchResults.split(':');
122
+ const maxVersion = parseInt(maxVersionStr, 10);
123
+ const customVersion = await input({
124
+ message: `Enter version number for ${fullName} (1-${maxVersion}):`,
125
+ validate: (value) => {
126
+ if (!value) {
127
+ return 'Version is required';
128
+ }
129
+ if (!SysPromptHubClient.validateVersion(value, maxVersion)) {
130
+ return `Version must be between 1 and ${maxVersion}`;
131
+ }
132
+ return true;
133
+ }
134
+ });
135
+ return `${fullName}/${customVersion}`;
56
136
  }
57
- });
58
- return command;
137
+ return searchResults;
138
+ }
139
+ async promptForAssistants(existing) {
140
+ const am = new AssistantManager();
141
+ const choices = [];
142
+ am.forEach((assistant) => {
143
+ choices.push({
144
+ value: assistant.type,
145
+ name: assistant.type,
146
+ checked: existing?.includes(assistant.type) || assistant.type === 'copilot'
147
+ });
148
+ });
149
+ choices.push({
150
+ value: 'other',
151
+ name: 'Other (custom path)',
152
+ checked: existing?.includes('other')
153
+ });
154
+ const selected = await checkbox({
155
+ message: 'Select your coding assistants:',
156
+ choices
157
+ });
158
+ return selected.filter((s) => s !== 'other');
159
+ }
160
+ async promptForCustomPath(existing) {
161
+ const path = await input({
162
+ message: 'Enter the location where you want to save the prompt:',
163
+ default: existing,
164
+ validate: (value) => {
165
+ if (value.length === 0)
166
+ return true;
167
+ if (isAbsolute(value))
168
+ return 'Path must be relative to the current working directory';
169
+ if (!isValidPath(value))
170
+ return 'Please enter a valid path';
171
+ return true;
172
+ }
173
+ });
174
+ return path.length > 0 ? path : undefined;
175
+ }
176
+ create() {
177
+ const command = new Command('init');
178
+ command
179
+ .description('Initialize project system prompt configuration')
180
+ .addOption(InitCommand.envOption)
181
+ .action(async (env) => await this.run(env));
182
+ return command;
183
+ }
59
184
  }
60
- //# sourceMappingURL=init.js.map
@@ -0,0 +1,161 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { InitCommand } from './init.js';
3
+ vi.mock('@inquirer/prompts', () => ({
4
+ input: vi.fn(),
5
+ search: vi.fn(),
6
+ checkbox: vi.fn(),
7
+ confirm: vi.fn()
8
+ }));
9
+ vi.mock('open', () => ({
10
+ default: vi.fn()
11
+ }));
12
+ vi.mock('@sysprompthub/sdk', () => {
13
+ const mockFs = {
14
+ exists: vi.fn(),
15
+ read: vi.fn(),
16
+ write: vi.fn(),
17
+ createDir: vi.fn()
18
+ };
19
+ const mockWorkspaceConfig = {
20
+ load: vi.fn(),
21
+ update: vi.fn()
22
+ };
23
+ const mockUserConfig = {
24
+ load: vi.fn(),
25
+ save: vi.fn()
26
+ };
27
+ const mockClient = {
28
+ searchPacks: vi.fn()
29
+ };
30
+ const mockAssistantManager = {
31
+ forEach: vi.fn()
32
+ };
33
+ return {
34
+ NodeFileSystem: class {
35
+ exists = mockFs.exists;
36
+ read = mockFs.read;
37
+ write = mockFs.write;
38
+ createDir = mockFs.createDir;
39
+ },
40
+ DefaultConfigManager: class {
41
+ load = mockWorkspaceConfig.load;
42
+ update = mockWorkspaceConfig.update;
43
+ },
44
+ UserConfigManager: class {
45
+ load = mockUserConfig.load;
46
+ save = mockUserConfig.save;
47
+ },
48
+ SysPromptHubClient: class {
49
+ searchPacks = mockClient.searchPacks;
50
+ },
51
+ AssistantManager: class {
52
+ forEach = mockAssistantManager.forEach;
53
+ },
54
+ API_KEY_LENGTH: 40,
55
+ __mocks: {
56
+ mockFs,
57
+ mockWorkspaceConfig,
58
+ mockUserConfig,
59
+ mockClient,
60
+ mockAssistantManager
61
+ }
62
+ };
63
+ });
64
+ describe('InitCommand', () => {
65
+ let initCommand;
66
+ let consoleLogSpy;
67
+ let mocks;
68
+ let promptMocks;
69
+ let openMock;
70
+ beforeEach(async () => {
71
+ const sdk = await import('@sysprompthub/sdk');
72
+ const prompts = await import('@inquirer/prompts');
73
+ const open = await import('open');
74
+ mocks = sdk.__mocks;
75
+ promptMocks = {
76
+ input: vi.mocked(prompts.input),
77
+ search: vi.mocked(prompts.search),
78
+ checkbox: vi.mocked(prompts.checkbox),
79
+ confirm: vi.mocked(prompts.confirm)
80
+ };
81
+ openMock = vi.mocked(open.default);
82
+ vi.clearAllMocks();
83
+ mocks.mockFs.exists.mockReset().mockResolvedValue(false);
84
+ mocks.mockFs.read.mockReset();
85
+ mocks.mockFs.write.mockReset();
86
+ mocks.mockFs.createDir.mockReset();
87
+ mocks.mockWorkspaceConfig.load.mockReset().mockResolvedValue(null);
88
+ mocks.mockWorkspaceConfig.update.mockReset();
89
+ mocks.mockUserConfig.load.mockReset().mockResolvedValue(null);
90
+ mocks.mockUserConfig.save.mockReset();
91
+ mocks.mockClient.searchPacks.mockReset().mockResolvedValue([]);
92
+ mocks.mockAssistantManager.forEach.mockReset().mockImplementation((cb) => {
93
+ cb({ type: 'copilot' });
94
+ cb({ type: 'claude' });
95
+ });
96
+ promptMocks.input.mockReset();
97
+ promptMocks.search.mockReset();
98
+ promptMocks.checkbox.mockReset();
99
+ promptMocks.confirm.mockReset();
100
+ openMock.mockReset();
101
+ consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
102
+ initCommand = new InitCommand();
103
+ });
104
+ afterEach(() => {
105
+ consoleLogSpy.mockRestore();
106
+ });
107
+ describe('create', () => {
108
+ it('should create a Command with correct configuration', () => {
109
+ const command = initCommand.create();
110
+ expect(command.name()).toBe('init');
111
+ expect(command.description()).toBe('Initialize project system prompt configuration');
112
+ });
113
+ });
114
+ describe('run', () => {
115
+ it('should prompt for API key, pack name, and assistants', async () => {
116
+ promptMocks.input.mockResolvedValue('a'.repeat(40));
117
+ promptMocks.search.mockResolvedValue('owner/pack/latest');
118
+ promptMocks.checkbox.mockResolvedValue(['copilot']);
119
+ await initCommand.run({});
120
+ expect(promptMocks.input).toHaveBeenCalled();
121
+ expect(promptMocks.search).toHaveBeenCalled();
122
+ expect(promptMocks.checkbox).toHaveBeenCalled();
123
+ expect(mocks.mockUserConfig.save).toHaveBeenCalledWith(expect.any(Object), { apiKey: 'a'.repeat(40) });
124
+ expect(mocks.mockWorkspaceConfig.update).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({
125
+ packName: 'owner/pack/latest',
126
+ assistants: ['copilot']
127
+ }));
128
+ });
129
+ it('should keep existing API key if blank entered', async () => {
130
+ mocks.mockUserConfig.load.mockResolvedValue({ apiKey: 'existing'.padEnd(40, 'x') });
131
+ promptMocks.input.mockResolvedValueOnce(''); // API key blank
132
+ promptMocks.search.mockResolvedValue('owner/pack/latest');
133
+ promptMocks.checkbox.mockResolvedValue(['copilot']);
134
+ await initCommand.run({});
135
+ expect(mocks.mockUserConfig.save).toHaveBeenCalledWith(expect.any(Object), { apiKey: 'existing'.padEnd(40, 'x') });
136
+ });
137
+ it('should prompt for custom path when no assistants selected', async () => {
138
+ promptMocks.input.mockResolvedValueOnce('a'.repeat(40)); // API key
139
+ promptMocks.input.mockResolvedValueOnce('custom/path'); // custom path
140
+ promptMocks.search.mockResolvedValue('owner/pack/latest');
141
+ promptMocks.checkbox.mockResolvedValue([]);
142
+ await initCommand.run({});
143
+ expect(mocks.mockWorkspaceConfig.update).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({
144
+ path: 'custom/path'
145
+ }));
146
+ });
147
+ it('should not set path when blank entered for custom path', async () => {
148
+ promptMocks.input.mockResolvedValueOnce('a'.repeat(40)); // API key
149
+ promptMocks.input.mockResolvedValueOnce(''); // blank custom path
150
+ promptMocks.search.mockResolvedValue('owner/pack/latest');
151
+ promptMocks.checkbox.mockResolvedValue([]);
152
+ await initCommand.run({});
153
+ expect(mocks.mockWorkspaceConfig.update).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({
154
+ packName: 'owner/pack/latest',
155
+ assistants: []
156
+ }));
157
+ const updateCall = mocks.mockWorkspaceConfig.update.mock.calls[0][1];
158
+ expect(updateCall.path).toBeUndefined();
159
+ });
160
+ });
161
+ });
@@ -1,94 +1,44 @@
1
1
  import { Command } from 'commander';
2
- import { SyncManager, ConfigManager, DEFAULT_ENVIRONMENT, VSCODE_SETTINGS_PATH } from '@sysprompthub/sdk';
3
- import { existsSync } from 'fs';
4
- import { join } from 'path';
5
- export function createSyncCommand() {
6
- const command = new Command('sync');
7
- command
8
- .description('Sync system prompts from SysPromptHub')
9
- .argument('[pack]', 'Prompt pack name in format user/pack/version')
10
- .option('--copilot', 'Enable GitHub Copilot')
11
- .option('--claude', 'Enable Claude')
12
- .option('--stdout', 'Output to stdout instead of writing files', false)
13
- .option('--vscode', 'Use .vscode/settings.json instead of .sysprompthub.json', false)
14
- .option('--cwd <dir>', 'Working directory', process.cwd())
15
- .option('-e, --environment <env>', '')
16
- .action(async (packArg, options) => {
17
- try {
18
- // Load config file
19
- const configManager = new ConfigManager(options.cwd);
20
- const config = await configManager.load();
21
- // Determine pack name
22
- const packName = packArg || config?.packName;
23
- if (!packName) {
24
- console.error('Error: Pack name is required. Provide it as an argument or in .sysprompthub.json');
25
- process.exit(1);
26
- }
27
- if (!ConfigManager.validatePackName(packName)) {
28
- console.error('Error: Invalid pack name format. Expected: user/pack/version (e.g., example-user/example-pack/latest)');
29
- process.exit(1);
30
- }
31
- // Determine assistants
32
- let assistants;
33
- if (options.copilot !== undefined || options.claude !== undefined) {
34
- assistants = [];
35
- if (options.copilot)
36
- assistants.push('copilot');
37
- if (options.claude)
38
- assistants.push('claude');
39
- }
40
- else {
41
- assistants = config?.assistants || ['copilot'];
42
- }
43
- // Determine environment
44
- const environment = options.environment || config?.environment || DEFAULT_ENVIRONMENT;
45
- // Check if config needs updating or creating
46
- const configChanged = !config || (config.packName !== packName ||
47
- JSON.stringify(config.assistants?.sort()) !== JSON.stringify(assistants.sort()));
48
- // Update or create config if needed
49
- if (configChanged && !options.stdout) {
50
- const updates = {
51
- packName,
52
- assistants,
53
- environment
54
- };
55
- // Check which config file to use
56
- const vscodeSettingsPath = join(options.cwd, VSCODE_SETTINGS_PATH);
57
- if (options.vscode || existsSync(vscodeSettingsPath)) {
58
- const vscodeManager = configManager.getVscodeManager();
59
- await vscodeManager.update(updates);
60
- }
61
- else {
62
- await configManager.update(updates);
63
- }
64
- }
65
- // Sync
66
- const syncManager = new SyncManager(options.cwd);
67
- const prompt = await syncManager.sync({
68
- packName,
69
- assistants,
70
- environment,
71
- cwd: options.cwd,
72
- stdout: options.stdout
73
- });
74
- if (options.stdout) {
75
- console.log(prompt);
76
- }
77
- else {
78
- console.log(`✓ Successfully synced prompt pack: ${packName}`);
79
- console.log(` Assistants: ${assistants.join(', ')}`);
80
- }
2
+ import { DefaultConfigManager, NodeFileSystem, SyncManager, UserConfigManager } from '@sysprompthub/sdk';
3
+ import { BaseCommand } from "./base-command.js";
4
+ export class SyncCommand extends BaseCommand {
5
+ fs = new NodeFileSystem();
6
+ workspaceConfig = new DefaultConfigManager();
7
+ userConfig = new UserConfigManager();
8
+ async run(_options) {
9
+ // Load user-level config (API key)
10
+ const userCfg = await this.userConfig.load(this.fs);
11
+ if (!userCfg?.apiKey) {
12
+ console.error('Error: API key not configured. Run "sysprompthub init" to configure.');
13
+ process.exit(1);
14
+ return;
15
+ }
16
+ // Load workspace-level config (pack name, assistants, path)
17
+ const workspaceCfg = await this.workspaceConfig.load(this.fs);
18
+ if (!workspaceCfg) {
19
+ console.error('Error: No workspace configuration found. Run "sysprompthub init" first.');
20
+ process.exit(1);
21
+ return;
81
22
  }
82
- catch (error) {
83
- if (error instanceof Error) {
84
- console.error(`Error: ${error.message}`);
85
- }
86
- else {
87
- console.error('An unknown error occurred');
88
- }
23
+ if (!workspaceCfg.packName) {
24
+ console.error('Error: Pack name not configured. Run "sysprompthub init" to configure.');
89
25
  process.exit(1);
26
+ return;
90
27
  }
91
- });
92
- return command;
28
+ // Combine configs
29
+ const config = {
30
+ ...workspaceCfg,
31
+ apiKey: userCfg.apiKey
32
+ };
33
+ const syncManager = new SyncManager();
34
+ await syncManager.sync({ config, fs: this.fs });
35
+ console.log('✓ Sync complete');
36
+ }
37
+ create() {
38
+ const command = new Command('sync');
39
+ command
40
+ .description('Sync system prompts from SysPromptHub')
41
+ .action(async (options) => await this.run(options));
42
+ return command;
43
+ }
93
44
  }
94
- //# sourceMappingURL=sync.js.map
@@ -0,0 +1,134 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { SyncCommand } from './sync.js';
3
+ vi.mock('@sysprompthub/sdk', () => {
4
+ const mockFs = {
5
+ readFile: vi.fn(),
6
+ writeFile: vi.fn(),
7
+ exists: vi.fn()
8
+ };
9
+ const mockWorkspaceConfig = {
10
+ load: vi.fn(),
11
+ update: vi.fn()
12
+ };
13
+ const mockUserConfig = {
14
+ load: vi.fn(),
15
+ save: vi.fn()
16
+ };
17
+ const mockSyncManager = {
18
+ sync: vi.fn()
19
+ };
20
+ return {
21
+ SyncManager: class {
22
+ sync = mockSyncManager.sync;
23
+ },
24
+ NodeFileSystem: class {
25
+ readFile = mockFs.readFile;
26
+ writeFile = mockFs.writeFile;
27
+ exists = mockFs.exists;
28
+ },
29
+ DefaultConfigManager: class {
30
+ load = mockWorkspaceConfig.load;
31
+ update = mockWorkspaceConfig.update;
32
+ },
33
+ UserConfigManager: class {
34
+ load = mockUserConfig.load;
35
+ save = mockUserConfig.save;
36
+ },
37
+ // Export mocks so tests can access them
38
+ __mocks: {
39
+ mockFs,
40
+ mockWorkspaceConfig,
41
+ mockUserConfig,
42
+ mockSyncManager
43
+ }
44
+ };
45
+ });
46
+ describe('SyncCommand', () => {
47
+ let syncCommand;
48
+ let consoleErrorSpy;
49
+ let consoleLogSpy;
50
+ let processExitSpy;
51
+ let mocks;
52
+ beforeEach(async () => {
53
+ const sdk = await import('@sysprompthub/sdk');
54
+ mocks = sdk.__mocks;
55
+ vi.clearAllMocks();
56
+ mocks.mockFs.readFile.mockReset();
57
+ mocks.mockFs.writeFile.mockReset();
58
+ mocks.mockFs.exists.mockReset();
59
+ mocks.mockWorkspaceConfig.load.mockReset().mockResolvedValue({
60
+ packName: 'user/pack/latest',
61
+ assistants: ['copilot']
62
+ });
63
+ mocks.mockWorkspaceConfig.update.mockReset();
64
+ mocks.mockUserConfig.load.mockReset().mockResolvedValue({
65
+ apiKey: 'a'.repeat(40)
66
+ });
67
+ mocks.mockUserConfig.save.mockReset();
68
+ mocks.mockSyncManager.sync.mockReset().mockResolvedValue(undefined);
69
+ consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
70
+ consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
71
+ processExitSpy = vi.spyOn(process, 'exit').mockImplementation(() => undefined);
72
+ syncCommand = new SyncCommand();
73
+ });
74
+ afterEach(() => {
75
+ consoleErrorSpy.mockRestore();
76
+ consoleLogSpy.mockRestore();
77
+ processExitSpy.mockRestore();
78
+ });
79
+ describe('create', () => {
80
+ it('should create a Command with correct configuration', () => {
81
+ const command = syncCommand.create();
82
+ expect(command.name()).toBe('sync');
83
+ expect(command.description()).toBe('Sync system prompts from SysPromptHub');
84
+ });
85
+ });
86
+ describe('run', () => {
87
+ it('should sync with valid configs', async () => {
88
+ await syncCommand.run({});
89
+ expect(mocks.mockUserConfig.load).toHaveBeenCalled();
90
+ expect(mocks.mockWorkspaceConfig.load).toHaveBeenCalled();
91
+ expect(mocks.mockSyncManager.sync).toHaveBeenCalledWith({
92
+ config: expect.objectContaining({
93
+ packName: 'user/pack/latest',
94
+ apiKey: 'a'.repeat(40)
95
+ }),
96
+ fs: expect.any(Object)
97
+ });
98
+ expect(consoleLogSpy).toHaveBeenCalledWith('✓ Sync complete');
99
+ });
100
+ it('should exit with error if API key not configured', async () => {
101
+ mocks.mockUserConfig.load.mockResolvedValue(null);
102
+ await syncCommand.run({});
103
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error: API key not configured. Run "sysprompthub init" to configure.');
104
+ expect(processExitSpy).toHaveBeenCalledWith(1);
105
+ });
106
+ it('should exit with error if no workspace configuration found', async () => {
107
+ mocks.mockWorkspaceConfig.load.mockResolvedValue(null);
108
+ await syncCommand.run({});
109
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error: No workspace configuration found. Run "sysprompthub init" first.');
110
+ expect(processExitSpy).toHaveBeenCalledWith(1);
111
+ });
112
+ it('should exit with error if pack name not configured', async () => {
113
+ mocks.mockWorkspaceConfig.load.mockResolvedValue({
114
+ assistants: ['copilot']
115
+ });
116
+ await syncCommand.run({});
117
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error: Pack name not configured. Run "sysprompthub init" to configure.');
118
+ expect(processExitSpy).toHaveBeenCalledWith(1);
119
+ });
120
+ it('should use workspace environment when option not provided', async () => {
121
+ mocks.mockWorkspaceConfig.load.mockResolvedValue({
122
+ packName: 'user/pack/latest',
123
+ environment: 'staging'
124
+ });
125
+ await syncCommand.run({});
126
+ expect(mocks.mockSyncManager.sync).toHaveBeenCalledWith({
127
+ config: expect.objectContaining({
128
+ environment: 'staging'
129
+ }),
130
+ fs: expect.any(Object)
131
+ });
132
+ });
133
+ });
134
+ });
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import { createSyncCommand } from './commands/sync.js';
4
- import { createInitCommand } from './commands/init.js';
3
+ import { InitCommand } from './commands/init.js';
4
+ import { SyncCommand } from './commands/sync.js';
5
5
  const program = new Command();
6
6
  program
7
7
  .name('sysprompthub')
8
- .description('CLI for syncing system prompts from SysPromptHub')
9
- .version('0.1.0');
10
- program.addCommand(createSyncCommand());
11
- program.addCommand(createInitCommand());
8
+ .description('SysPromptHub CLI - Manage system prompts for AI assistants')
9
+ .version('1.0.0');
10
+ const initCmd = new InitCommand();
11
+ const syncCmd = new SyncCommand();
12
+ program.addCommand(initCmd.create());
13
+ program.addCommand(syncCmd.create());
12
14
  program.parse();
13
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,20 +1,19 @@
1
1
  {
2
2
  "name": "@sysprompthub/cli",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "CLI for syncing system prompts from SysPromptHub",
5
+ "authorEmail": "info@sysprompthub.com",
6
+ "authorName": "SysPromptHub",
5
7
  "type": "module",
8
+ "main": "dist/index.js",
6
9
  "bin": {
7
- "sysprompthub": "./dist/index.js"
10
+ "sysprompthub": "dist/index.js",
11
+ "sysprompthub-cli": "dist/index.js"
8
12
  },
9
13
  "files": [
10
14
  "dist",
11
15
  "README.md"
12
16
  ],
13
- "scripts": {
14
- "build": "tsc",
15
- "dev": "tsx src/index.ts",
16
- "typecheck": "tsc --noEmit"
17
- },
18
17
  "keywords": [
19
18
  "ai",
20
19
  "prompts",
@@ -27,16 +26,32 @@
27
26
  "author": "",
28
27
  "license": "ISC",
29
28
  "engines": {
30
- "node": ">=18.0.0"
29
+ "node": ">=18.0.0",
30
+ "pnpm": ">=10.27.0"
31
31
  },
32
32
  "dependencies": {
33
- "@sysprompthub/sdk": "^0.1.0",
34
- "commander": "^14.0.2"
33
+ "@inquirer/prompts": "^8.1.0",
34
+ "@sysprompthub/sdk": "1.0.0",
35
+ "commander": "^14.0.2",
36
+ "is-valid-path": "^0.1.1",
37
+ "open": "^11.0.0"
35
38
  },
36
39
  "devDependencies": {
40
+ "@types/is-valid-path": "^0.1.2",
37
41
  "@types/node": "^25.0.3",
42
+ "@vitest/coverage-v8": "^4.0.16",
43
+ "@vitest/ui": "^4.0.16",
38
44
  "tsx": "^4.21.0",
39
- "typescript": "^5.9.3"
45
+ "typescript": "^5.9.3",
46
+ "vitest": "^4.0.16"
40
47
  },
41
- "packageManager": "pnpm@9.0.0+sha512.b4106707c7225b1748b61595953ccbebff97b54ad05d002aa3635f633b9c53cd666f7ce9b8bc44704f1fa048b9a49b55371ab2d9e9d667d1efe2ef1514bcd513"
42
- }
48
+ "scripts": {
49
+ "build": "tsc",
50
+ "dev": "tsx src/index.ts",
51
+ "typecheck": "tsc --noEmit",
52
+ "test": "vitest run",
53
+ "test:watch": "vitest",
54
+ "test:ui": "vitest --ui",
55
+ "test:coverage": "vitest run --coverage"
56
+ }
57
+ }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createInitCommand(): Command;
3
- //# sourceMappingURL=init.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,iBAAiB,IAAI,OAAO,CAsD3C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createSyncCommand(): Command;
3
- //# sourceMappingURL=sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,iBAAiB,IAAI,OAAO,CAsG3C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,kDAAkD,CAAC;KAC/D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAExC,OAAO,CAAC,KAAK,EAAE,CAAC"}