deepline 0.1.3 → 0.1.4
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/dist/cli/index.js +148 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +148 -8
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/repo/sdk/src/cli/commands/auth.ts +25 -7
- package/dist/repo/sdk/src/cli/index.ts +9 -0
- package/dist/repo/sdk/src/cli/skills-sync.ts +137 -0
- package/dist/repo/sdk/src/version.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -98,6 +98,29 @@ function sleep(ms: number): Promise<void> {
|
|
|
98
98
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
function printDeeplineLogo(): void {
|
|
102
|
+
if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
|
|
103
|
+
console.log(' ██████╗ ███████╗ ███████╗ ██████╗ ██╗ ██╗ ███╗ ██╗ ███████╗');
|
|
104
|
+
console.log(' ██╔══██╗ ██╔════╝ ██╔════╝ ██╔══██╗ ██║ ██║ ████╗ ██║ ██╔════╝');
|
|
105
|
+
console.log(' ██║ ██║ █████╗ █████╗ ██████╔╝ ██║ ██║ ██╔██╗ ██║ █████╗');
|
|
106
|
+
console.log(' ██║ ██║ ██╔══╝ ██╔══╝ ██╔═══╝ ██║ ██║ ██║╚██╗██║ ██╔══╝');
|
|
107
|
+
console.log(' ██████╔╝ ███████╗ ███████╗ ██║ ███████╗ ██║ ██║ ╚████║ ███████╗');
|
|
108
|
+
console.log(' ╚═════╝ ╚══════╝ ╚══════╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚══════╝');
|
|
109
|
+
console.log('');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
console.log('DEEPLINE');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function printClaimSuccessBanner(statusData: Record<string, unknown>): void {
|
|
116
|
+
console.log('');
|
|
117
|
+
printDeeplineLogo();
|
|
118
|
+
console.log('✓ All set! Your CLI is connected.');
|
|
119
|
+
if (statusData.org_name) {
|
|
120
|
+
console.log(` • Signed in with organization: ${statusData.org_name}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
101
124
|
export async function handleRegister(args: string[]): Promise<number> {
|
|
102
125
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, '');
|
|
103
126
|
|
|
@@ -189,12 +212,7 @@ export async function handleRegister(args: string[]): Promise<number> {
|
|
|
189
212
|
DEEPLINE_API_KEY: apiKey,
|
|
190
213
|
DEEPLINE_CLAIM_TOKEN: '',
|
|
191
214
|
}, baseUrl);
|
|
192
|
-
|
|
193
|
-
console.log('DEEPLINE');
|
|
194
|
-
console.log('All set! Your CLI is connected.');
|
|
195
|
-
if (statusData.org_name) {
|
|
196
|
-
console.log(` Signed in with organization: ${statusData.org_name}`);
|
|
197
|
-
}
|
|
215
|
+
printClaimSuccessBanner(statusData);
|
|
198
216
|
return EXIT_OK;
|
|
199
217
|
}
|
|
200
218
|
}
|
|
@@ -262,7 +280,7 @@ export async function handleWait(args: string[]): Promise<number> {
|
|
|
262
280
|
DEEPLINE_API_KEY: apiKey,
|
|
263
281
|
DEEPLINE_CLAIM_TOKEN: '',
|
|
264
282
|
}, baseUrl);
|
|
265
|
-
|
|
283
|
+
printClaimSuccessBanner(data);
|
|
266
284
|
return EXIT_OK;
|
|
267
285
|
}
|
|
268
286
|
}
|
|
@@ -14,6 +14,7 @@ import { registerOrgCommands } from './commands/org.js';
|
|
|
14
14
|
import { registerPlayCommands } from './commands/play.js';
|
|
15
15
|
import { registerToolsCommands } from './commands/tools.js';
|
|
16
16
|
import { createCliProgress } from './progress.js';
|
|
17
|
+
import { syncSdkSkillsIfNeeded } from './skills-sync.js';
|
|
17
18
|
import { recordCliTrace, traceCliSpan } from './trace.js';
|
|
18
19
|
import { printJsonError } from './utils.js';
|
|
19
20
|
|
|
@@ -75,6 +76,14 @@ Output:
|
|
|
75
76
|
{ baseUrl },
|
|
76
77
|
() => enforceSdkCompatibility(baseUrl),
|
|
77
78
|
);
|
|
79
|
+
if (printStartupPhase) {
|
|
80
|
+
progress?.phase('checking sdk skills');
|
|
81
|
+
}
|
|
82
|
+
await traceCliSpan(
|
|
83
|
+
'cli.sdk_skills_sync',
|
|
84
|
+
{ baseUrl },
|
|
85
|
+
() => syncSdkSkillsIfNeeded(baseUrl),
|
|
86
|
+
);
|
|
78
87
|
});
|
|
79
88
|
|
|
80
89
|
registerAuthCommands(program);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { baseUrlSlug } from '../config.js';
|
|
6
|
+
|
|
7
|
+
const CHECK_TIMEOUT_MS = 3_000;
|
|
8
|
+
const SDK_SKILL_NAME = 'deepline-sdk';
|
|
9
|
+
const SKILL_AGENTS = ['codex', 'claude-code', 'cursor'] as const;
|
|
10
|
+
|
|
11
|
+
type UpdateCheckResponse = {
|
|
12
|
+
skills?: {
|
|
13
|
+
needs_update?: unknown;
|
|
14
|
+
remote?: {
|
|
15
|
+
version?: unknown;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
let attemptedSync = false;
|
|
21
|
+
|
|
22
|
+
function shouldSkipSkillsSync(): boolean {
|
|
23
|
+
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
24
|
+
return value === '1' || value === 'true' || value === 'yes' || value === 'on';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function sdkSkillsVersionPath(baseUrl: string): string {
|
|
28
|
+
const home = process.env.HOME?.trim() || homedir();
|
|
29
|
+
return join(home, '.local', 'deepline', baseUrlSlug(baseUrl), 'sdk-skills', '.version');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readLocalSkillsVersion(baseUrl: string): string {
|
|
33
|
+
const path = sdkSkillsVersionPath(baseUrl);
|
|
34
|
+
if (!existsSync(path)) return '';
|
|
35
|
+
try {
|
|
36
|
+
return readFileSync(path, 'utf-8').trim();
|
|
37
|
+
} catch {
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function writeLocalSkillsVersion(baseUrl: string, version: string): void {
|
|
43
|
+
const path = sdkSkillsVersionPath(baseUrl);
|
|
44
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
45
|
+
writeFileSync(path, `${version}\n`, 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function fetchSkillsUpdate(baseUrl: string, localVersion: string): Promise<{
|
|
49
|
+
needsUpdate: boolean;
|
|
50
|
+
remoteVersion: string;
|
|
51
|
+
} | null> {
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS);
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(new URL('/api/v2/cli/update-check', baseUrl), {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: { 'Content-Type': 'application/json' },
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
skills: {
|
|
60
|
+
version: localVersion,
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
signal: controller.signal,
|
|
64
|
+
});
|
|
65
|
+
if (!response.ok) return null;
|
|
66
|
+
const data = (await response.json().catch(() => null)) as UpdateCheckResponse | null;
|
|
67
|
+
const skills = data?.skills;
|
|
68
|
+
if (!skills) return null;
|
|
69
|
+
return {
|
|
70
|
+
needsUpdate: skills.needs_update === true,
|
|
71
|
+
remoteVersion: typeof skills.remote?.version === 'string' ? skills.remote.version.trim() : '',
|
|
72
|
+
};
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
} finally {
|
|
76
|
+
clearTimeout(timeout);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function runSkillsInstall(baseUrl: string): Promise<boolean> {
|
|
81
|
+
const packageUrl = new URL('/.well-known/skills/index.json', baseUrl).toString();
|
|
82
|
+
const args = [
|
|
83
|
+
'skills',
|
|
84
|
+
'add',
|
|
85
|
+
packageUrl,
|
|
86
|
+
'--agents',
|
|
87
|
+
...SKILL_AGENTS,
|
|
88
|
+
'--global',
|
|
89
|
+
'--yes',
|
|
90
|
+
'--skill',
|
|
91
|
+
SDK_SKILL_NAME,
|
|
92
|
+
'--full-depth',
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
const child = spawn('npx', args, {
|
|
97
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
98
|
+
env: process.env,
|
|
99
|
+
});
|
|
100
|
+
let stderr = '';
|
|
101
|
+
child.stderr.on('data', (chunk: Buffer) => {
|
|
102
|
+
stderr += chunk.toString('utf-8');
|
|
103
|
+
});
|
|
104
|
+
child.on('error', (error) => {
|
|
105
|
+
process.stderr.write(`SDK skills sync failed to start: ${error.message}\n`);
|
|
106
|
+
resolve(false);
|
|
107
|
+
});
|
|
108
|
+
child.on('close', (code) => {
|
|
109
|
+
if (code === 0) {
|
|
110
|
+
resolve(true);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const detail = stderr.trim();
|
|
114
|
+
process.stderr.write(
|
|
115
|
+
`SDK skills sync failed${detail ? `: ${detail}` : ''}\n` +
|
|
116
|
+
`Run manually: npx ${args.map((arg) => (arg.includes(' ') ? JSON.stringify(arg) : arg)).join(' ')}\n`,
|
|
117
|
+
);
|
|
118
|
+
resolve(false);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export async function syncSdkSkillsIfNeeded(baseUrl: string): Promise<void> {
|
|
124
|
+
if (attemptedSync || shouldSkipSkillsSync()) return;
|
|
125
|
+
attemptedSync = true;
|
|
126
|
+
|
|
127
|
+
const localVersion = readLocalSkillsVersion(baseUrl);
|
|
128
|
+
const update = await fetchSkillsUpdate(baseUrl, localVersion);
|
|
129
|
+
if (!update?.needsUpdate || !update.remoteVersion) return;
|
|
130
|
+
|
|
131
|
+
process.stderr.write('SDK skills changed; syncing deepline-sdk skill...\n');
|
|
132
|
+
const installed = await runSkillsInstall(baseUrl);
|
|
133
|
+
if (!installed) return;
|
|
134
|
+
|
|
135
|
+
writeLocalSkillsVersion(baseUrl, update.remoteVersion);
|
|
136
|
+
process.stderr.write('SDK skills are up to date.\n');
|
|
137
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const SDK_VERSION = "0.1.
|
|
1
|
+
export const SDK_VERSION = "0.1.4";
|
|
2
2
|
export const SDK_API_CONTRACT = "2026-04-plays-v1";
|