@telelabsai/ship 1.1.6 → 1.1.8
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/cli/commands/auth.js +3 -1
- package/cli/commands/sync.js +35 -35
- package/package.json +4 -1
package/cli/commands/auth.js
CHANGED
|
@@ -64,7 +64,9 @@ function login() {
|
|
|
64
64
|
|
|
65
65
|
server.listen(0, () => {
|
|
66
66
|
const port = server.address().port;
|
|
67
|
-
const
|
|
67
|
+
const hostname = os.hostname();
|
|
68
|
+
const platform = process.platform === 'darwin' ? 'macOS' : process.platform === 'win32' ? 'Windows' : 'Linux';
|
|
69
|
+
const authUrl = `${DASHBOARD_URL}/authorize-cli?port=${port}&device=${encodeURIComponent(hostname)}&platform=${encodeURIComponent(platform)}`;
|
|
68
70
|
|
|
69
71
|
console.log(` Auth URL: ${authUrl}\n`);
|
|
70
72
|
console.log(' Waiting for authorization...\n');
|
package/cli/commands/sync.js
CHANGED
|
@@ -2,13 +2,13 @@ const https = require('https');
|
|
|
2
2
|
const http = require('http');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const
|
|
5
|
+
const prompts = require('prompts');
|
|
6
6
|
const { loadCredentials, DASHBOARD_URL } = require('./auth.js');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* ship sync [--workspace <slug>] [--org <slug>] [--key <key>] [--dir <path>]
|
|
10
10
|
*
|
|
11
|
-
* Interactive mode (no flags): picks
|
|
11
|
+
* Interactive mode (no flags): picks workspace with arrow keys
|
|
12
12
|
* CI mode (with flags): uses provided org + workspace directly
|
|
13
13
|
*/
|
|
14
14
|
function sync(args) {
|
|
@@ -36,7 +36,7 @@ function sync(args) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
// Interactive mode
|
|
39
|
+
// Interactive mode
|
|
40
40
|
if (!process.stdin.isTTY) {
|
|
41
41
|
console.error(' Error: --org and --workspace required in non-interactive mode.');
|
|
42
42
|
console.error(' Usage: ship sync --org <slug> --workspace <slug>\n');
|
|
@@ -45,7 +45,7 @@ function sync(args) {
|
|
|
45
45
|
|
|
46
46
|
console.log(' Fetching your workspaces...\n');
|
|
47
47
|
|
|
48
|
-
fetchJson(`${DASHBOARD_URL}/api/cli/workspaces`, token, (err, data) => {
|
|
48
|
+
fetchJson(`${DASHBOARD_URL}/api/cli/workspaces`, token, async (err, data) => {
|
|
49
49
|
if (err) {
|
|
50
50
|
console.error(` Error: ${err.message}\n`);
|
|
51
51
|
process.exit(1);
|
|
@@ -61,7 +61,7 @@ function sync(args) {
|
|
|
61
61
|
process.exit(0);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// Flatten all workspaces
|
|
64
|
+
// Flatten all workspaces
|
|
65
65
|
const allWorkspaces = [];
|
|
66
66
|
for (const o of orgs) {
|
|
67
67
|
for (const w of o.workspaces) {
|
|
@@ -80,42 +80,43 @@ function sync(args) {
|
|
|
80
80
|
process.exit(0);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
// Arrow-key workspace picker
|
|
84
|
+
const { selected } = await prompts({
|
|
85
|
+
type: 'select',
|
|
86
|
+
name: 'selected',
|
|
87
|
+
message: 'Select workspace',
|
|
88
|
+
choices: allWorkspaces.map((w) => ({
|
|
89
|
+
title: `${w.wsName} (${w.orgName})`,
|
|
90
|
+
description: `${w.files} files`,
|
|
91
|
+
value: w,
|
|
92
|
+
})),
|
|
87
93
|
});
|
|
88
|
-
console.log('');
|
|
89
|
-
|
|
90
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
rl.close();
|
|
97
|
-
process.exit(1);
|
|
98
|
-
}
|
|
95
|
+
if (!selected) {
|
|
96
|
+
console.log(' Cancelled.\n');
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (c !== 'y' && c !== 'yes' && c !== '') {
|
|
107
|
-
console.log(' Cancelled.\n');
|
|
108
|
-
process.exit(0);
|
|
109
|
-
}
|
|
110
|
-
console.log('');
|
|
111
|
-
doSync(selected.orgSlug, selected.wsSlug, token, dir);
|
|
112
|
-
});
|
|
100
|
+
// Confirmation
|
|
101
|
+
const { confirmed } = await prompts({
|
|
102
|
+
type: 'confirm',
|
|
103
|
+
name: 'confirmed',
|
|
104
|
+
message: `Sync "${selected.wsName}" (${selected.files} files) to ${path.join(dir, '.claude')}?`,
|
|
105
|
+
initial: true,
|
|
113
106
|
});
|
|
107
|
+
|
|
108
|
+
if (!confirmed) {
|
|
109
|
+
console.log(' Cancelled.\n');
|
|
110
|
+
process.exit(0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
console.log('');
|
|
114
|
+
doSync(selected.orgSlug, selected.wsSlug, token, dir);
|
|
114
115
|
});
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
function doSync(orgSlug, workspaceSlug, token, dir) {
|
|
118
|
-
console.log(` Syncing workspace "${workspaceSlug}"
|
|
119
|
+
console.log(` Syncing workspace "${workspaceSlug}"...\n`);
|
|
119
120
|
|
|
120
121
|
const url = `${DASHBOARD_URL}/api/sync/${orgSlug}?workspace=${workspaceSlug}`;
|
|
121
122
|
|
|
@@ -147,9 +148,8 @@ function doSync(orgSlug, workspaceSlug, token, dir) {
|
|
|
147
148
|
console.log(` + .claude/${file.path}`);
|
|
148
149
|
}
|
|
149
150
|
|
|
150
|
-
console.log(`\n Synced ${written} files to ${claudeDir}\n`);
|
|
151
|
+
console.log(`\n ✓ Synced ${written} files to ${claudeDir}\n`);
|
|
151
152
|
|
|
152
|
-
// Save config for future syncs
|
|
153
153
|
saveSyncConfig(dir, orgSlug, workspaceSlug);
|
|
154
154
|
});
|
|
155
155
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telelabsai/ship",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "Ship code faster with pre-configured agents, skills, rules, and hooks for Claude Code.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ship": "cli/bin.js"
|
|
@@ -37,5 +37,8 @@
|
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"prompts": "^2.4.2"
|
|
40
43
|
}
|
|
41
44
|
}
|