@postplus/cli 0.1.32 → 0.1.34
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/build/account-binding-display.js +21 -0
- package/build/auth-lifecycle.js +5 -1
- package/build/auth-login.js +23 -0
- package/build/auth-session.js +8 -0
- package/build/auth-validate.js +15 -1
- package/build/auth.js +16 -1
- package/build/client-compatibility.js +1 -1
- package/build/doctor.js +11 -4
- package/build/index.js +4 -3
- package/build/local-state.js +6 -0
- package/build/skill-management.js +39 -5
- package/build/status.js +6 -3
- package/build/update-check.js +6 -1
- package/package.json +2 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function formatAccountBindingLines(input) {
|
|
2
|
+
if (input.accountType === 'team') {
|
|
3
|
+
return [
|
|
4
|
+
`Workspace: ${formatAccountBindingName(input)}`,
|
|
5
|
+
...(input.accountSlug ? [`Workspace slug: ${input.accountSlug}`] : []),
|
|
6
|
+
`Account ID: ${input.accountId ?? 'not bound'}`,
|
|
7
|
+
];
|
|
8
|
+
}
|
|
9
|
+
return [
|
|
10
|
+
`Account: ${input.accountName ?? 'not bound'}`,
|
|
11
|
+
`Account ID: ${input.accountId ?? 'not bound'}`,
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
export function formatAccountBindingName(input) {
|
|
15
|
+
if (!input.accountName) {
|
|
16
|
+
return input.accountId ? `Account ${input.accountId}` : 'not bound';
|
|
17
|
+
}
|
|
18
|
+
return input.accountType === 'team'
|
|
19
|
+
? `${input.accountName} (team)`
|
|
20
|
+
: input.accountName;
|
|
21
|
+
}
|
package/build/auth-lifecycle.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatAccountBindingLines } from './account-binding-display.js';
|
|
1
2
|
import { refreshRemoteAuthSession } from './auth-session.js';
|
|
2
3
|
import { clearAuthState, generateAuthStatusReport } from './auth.js';
|
|
3
4
|
import { buildPostPlusClientCompatibilityHeaders, formatPostPlusCompatibilityError, } from './client-compatibility.js';
|
|
@@ -8,6 +9,9 @@ export async function refreshRemoteAuth() {
|
|
|
8
9
|
const refreshed = await refreshRemoteAuthSession();
|
|
9
10
|
return {
|
|
10
11
|
accountId: refreshed.accountId,
|
|
12
|
+
accountName: refreshed.accountName,
|
|
13
|
+
accountSlug: refreshed.accountSlug,
|
|
14
|
+
accountType: refreshed.accountType,
|
|
11
15
|
apiBaseUrl: refreshed.apiBaseUrl,
|
|
12
16
|
ok: true,
|
|
13
17
|
subscriptionStatus: refreshed.subscriptionStatus,
|
|
@@ -21,7 +25,7 @@ export function formatAuthRefreshReport(report) {
|
|
|
21
25
|
'',
|
|
22
26
|
`Remote auth: ${report.ok ? 'OK' : 'FAILED'}`,
|
|
23
27
|
`PostPlus Cloud: ${report.apiBaseUrl}`,
|
|
24
|
-
|
|
28
|
+
...formatAccountBindingLines(report),
|
|
25
29
|
`User: ${report.userEmail ?? report.userId}`,
|
|
26
30
|
`Subscription: ${readSubscriptionStatusField(report).label}`,
|
|
27
31
|
].join('\n');
|
package/build/auth-login.js
CHANGED
|
@@ -34,6 +34,9 @@ export async function loginWithCloudHandoff() {
|
|
|
34
34
|
});
|
|
35
35
|
await setLocalSession({
|
|
36
36
|
accountId: validated.accountId,
|
|
37
|
+
accountName: validated.accountName,
|
|
38
|
+
accountSlug: validated.accountSlug,
|
|
39
|
+
accountType: validated.accountType,
|
|
37
40
|
apiBaseUrl: baseUrl,
|
|
38
41
|
cliSessionToken: handoffPayload.cliSessionToken,
|
|
39
42
|
sessionExpiresAt: validated.sessionExpiresAt ?? handoffPayload.sessionExpiresAt ?? null,
|
|
@@ -43,6 +46,9 @@ export async function loginWithCloudHandoff() {
|
|
|
43
46
|
await writeCurrentCliVersionToLocalConfig();
|
|
44
47
|
return {
|
|
45
48
|
accountId: validated.accountId,
|
|
49
|
+
accountName: validated.accountName,
|
|
50
|
+
accountSlug: validated.accountSlug,
|
|
51
|
+
accountType: validated.accountType,
|
|
46
52
|
apiBaseUrl: baseUrl,
|
|
47
53
|
ok: true,
|
|
48
54
|
userEmail: validated.userEmail,
|
|
@@ -135,6 +141,9 @@ export async function validateCliSession(input) {
|
|
|
135
141
|
if (!response.ok) {
|
|
136
142
|
throw new Error(formatCliSessionAuthError(payload));
|
|
137
143
|
}
|
|
144
|
+
if (!isValidatedCliSessionPayload(payload)) {
|
|
145
|
+
throw new Error('PostPlus CLI auth validation returned incomplete data.');
|
|
146
|
+
}
|
|
138
147
|
return payload;
|
|
139
148
|
}
|
|
140
149
|
export function formatCliSessionAuthError(payload) {
|
|
@@ -168,11 +177,25 @@ function isCliAuthLoginCompletedPayload(payload) {
|
|
|
168
177
|
payload.status === 'completed' &&
|
|
169
178
|
typeof payload.cliSessionToken === 'string' &&
|
|
170
179
|
typeof payload.accountId === 'string' &&
|
|
180
|
+
typeof payload.accountName === 'string' &&
|
|
181
|
+
(payload.accountSlug === null || typeof payload.accountSlug === 'string') &&
|
|
182
|
+
(payload.accountType === 'personal' || payload.accountType === 'team') &&
|
|
171
183
|
typeof payload.userId === 'string');
|
|
172
184
|
}
|
|
173
185
|
function isCliAuthLoginPendingPayload(payload) {
|
|
174
186
|
return 'status' in payload && payload.status === 'pending';
|
|
175
187
|
}
|
|
188
|
+
function isValidatedCliSessionPayload(payload) {
|
|
189
|
+
return (typeof payload === 'object' &&
|
|
190
|
+
payload !== null &&
|
|
191
|
+
typeof payload.accountId === 'string' &&
|
|
192
|
+
typeof payload.accountName === 'string' &&
|
|
193
|
+
(payload.accountSlug === null ||
|
|
194
|
+
typeof payload.accountSlug === 'string') &&
|
|
195
|
+
(payload.accountType === 'personal' ||
|
|
196
|
+
payload.accountType === 'team') &&
|
|
197
|
+
typeof payload.userId === 'string');
|
|
198
|
+
}
|
|
176
199
|
function formatRemoteAuthLoginError(payload) {
|
|
177
200
|
const compatibilityError = formatPostPlusCompatibilityError(payload);
|
|
178
201
|
if (compatibilityError) {
|
package/build/auth-session.js
CHANGED
|
@@ -66,6 +66,9 @@ export async function refreshRemoteAuthSession(input) {
|
|
|
66
66
|
}
|
|
67
67
|
await setLocalSession({
|
|
68
68
|
accountId: payload.accountId,
|
|
69
|
+
accountName: payload.accountName,
|
|
70
|
+
accountSlug: payload.accountSlug,
|
|
71
|
+
accountType: payload.accountType,
|
|
69
72
|
apiBaseUrl,
|
|
70
73
|
cliSessionToken: payload.cliSessionToken,
|
|
71
74
|
sessionExpiresAt: payload.sessionExpiresAt,
|
|
@@ -86,5 +89,10 @@ function isRemoteAuthRefreshSuccessPayload(payload) {
|
|
|
86
89
|
payload.cliSessionToken.trim().length >
|
|
87
90
|
0 &&
|
|
88
91
|
typeof payload.accountId === 'string' &&
|
|
92
|
+
typeof payload.accountName === 'string' &&
|
|
93
|
+
(payload.accountSlug === null ||
|
|
94
|
+
typeof payload.accountSlug === 'string') &&
|
|
95
|
+
(payload.accountType === 'personal' ||
|
|
96
|
+
payload.accountType === 'team') &&
|
|
89
97
|
typeof payload.userId === 'string');
|
|
90
98
|
}
|
package/build/auth-validate.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatAccountBindingLines } from './account-binding-display.js';
|
|
1
2
|
import { resolveFreshRemoteAuth } from './auth-session.js';
|
|
2
3
|
import { buildPostPlusClientCompatibilityHeaders, formatPostPlusCompatibilityError, } from './client-compatibility.js';
|
|
3
4
|
import { readSubscriptionStatusField } from './subscription-status.js';
|
|
@@ -22,10 +23,16 @@ export async function validateRemoteAuth() {
|
|
|
22
23
|
}
|
|
23
24
|
const hasSubscriptionStatus = Object.prototype.hasOwnProperty.call(payload, 'subscriptionStatus');
|
|
24
25
|
const accountId = readRequiredString(payload, 'accountId');
|
|
26
|
+
const accountName = readRequiredString(payload, 'accountName');
|
|
27
|
+
const accountSlug = readNullableString(payload, 'accountSlug');
|
|
28
|
+
const accountType = readAccountType(payload);
|
|
25
29
|
const userId = readRequiredString(payload, 'userId');
|
|
26
30
|
const userEmail = readNullableString(payload, 'userEmail');
|
|
27
31
|
return {
|
|
28
32
|
accountId,
|
|
33
|
+
accountName,
|
|
34
|
+
accountSlug,
|
|
35
|
+
accountType,
|
|
29
36
|
apiBaseUrl: auth.apiBaseUrl,
|
|
30
37
|
ok: true,
|
|
31
38
|
source: auth.source,
|
|
@@ -42,11 +49,18 @@ export function formatAuthValidateReport(report) {
|
|
|
42
49
|
'',
|
|
43
50
|
`Remote auth: ${report.ok ? 'OK' : 'FAILED'}`,
|
|
44
51
|
`PostPlus Cloud: ${report.apiBaseUrl}`,
|
|
45
|
-
|
|
52
|
+
...formatAccountBindingLines(report),
|
|
46
53
|
`User: ${report.userEmail ?? report.userId}`,
|
|
47
54
|
`Subscription: ${readSubscriptionStatusField(report).label}`,
|
|
48
55
|
].join('\n');
|
|
49
56
|
}
|
|
57
|
+
function readAccountType(payload) {
|
|
58
|
+
const value = payload.accountType;
|
|
59
|
+
if (value !== 'personal' && value !== 'team') {
|
|
60
|
+
throw new Error('Invalid PostPlus auth response: accountType must be personal or team.');
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
50
64
|
async function fetchWhoami(input) {
|
|
51
65
|
const compatibilityHeaders = await buildPostPlusClientCompatibilityHeaders();
|
|
52
66
|
return fetch(`${input.apiBaseUrl}/api/postplus-cli/auth/whoami`, {
|
package/build/auth.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatAccountBindingLines } from './account-binding-display.js';
|
|
1
2
|
import { clearLocalAuthState, getPostPlusConfigPath, hasLocalConfigFile, maskSecret, readLocalConfig, resolveApiBaseUrlState, resolveLocalSessionState, setLocalApiBaseUrl, } from './local-state.js';
|
|
2
3
|
export async function generateAuthStatusReport() {
|
|
3
4
|
const [sessionState, apiBaseUrlState, configExists, config] = await Promise.all([
|
|
@@ -22,6 +23,15 @@ export async function generateAuthStatusReport() {
|
|
|
22
23
|
path: getPostPlusConfigPath(),
|
|
23
24
|
exists: configExists,
|
|
24
25
|
accountId: config?.accountId?.trim() || null,
|
|
26
|
+
accountName: typeof config?.accountName === 'string'
|
|
27
|
+
? config.accountName.trim() || null
|
|
28
|
+
: null,
|
|
29
|
+
accountSlug: typeof config?.accountSlug === 'string'
|
|
30
|
+
? config.accountSlug.trim() || null
|
|
31
|
+
: null,
|
|
32
|
+
accountType: config?.accountType === 'personal' || config?.accountType === 'team'
|
|
33
|
+
? config.accountType
|
|
34
|
+
: null,
|
|
25
35
|
sessionExpiresAt: typeof config?.sessionExpiresAt === 'number'
|
|
26
36
|
? config.sessionExpiresAt
|
|
27
37
|
: null,
|
|
@@ -47,7 +57,12 @@ export function formatAuthStatusReport(report) {
|
|
|
47
57
|
lines.push(report.config.exists
|
|
48
58
|
? `[PASS] local config: ${report.config.path}`
|
|
49
59
|
: `[PASS] local config path: ${report.config.path}`);
|
|
50
|
-
lines.push(
|
|
60
|
+
lines.push(...formatAccountBindingLines({
|
|
61
|
+
accountId: report.config.accountId,
|
|
62
|
+
accountName: report.config.accountName,
|
|
63
|
+
accountSlug: report.config.accountSlug,
|
|
64
|
+
accountType: report.config.accountType,
|
|
65
|
+
}).map((line) => ` ${line}`));
|
|
51
66
|
lines.push(` User: ${report.config.userEmail ?? report.config.userId ?? 'not bound'}`);
|
|
52
67
|
lines.push(` Expires: ${report.config.sessionExpiresAt
|
|
53
68
|
? new Date(report.config.sessionExpiresAt * 1000).toISOString()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { readLocalConfig, updateLocalConfig } from './local-state.js';
|
|
3
|
-
export const POSTPLUS_CLIENT_CONTRACT_VERSION =
|
|
3
|
+
export const POSTPLUS_CLIENT_CONTRACT_VERSION = 2;
|
|
4
4
|
export const POSTPLUS_CLIENT_RUNTIME = 'postplus-cli';
|
|
5
5
|
export const POSTPLUS_CLIENT_COMPATIBILITY_HEADERS = {
|
|
6
6
|
cliVersion: 'x-postplus-cli-version',
|
package/build/doctor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatAccountBindingName } from './account-binding-display.js';
|
|
1
2
|
import { resolveFreshRemoteAuth, } from './auth-session.js';
|
|
2
3
|
import { buildPostPlusClientCompatibilityHeaders, formatPostPlusCompatibilityError, } from './client-compatibility.js';
|
|
3
4
|
import { resolveHostedBaseUrl } from './hosted-release.js';
|
|
@@ -131,13 +132,21 @@ async function checkRemoteAuth(input) {
|
|
|
131
132
|
return createFail('remote_auth', 'Remote auth', readErrorMessage(payload, 'PostPlus Cloud rejected the CLI session.'), 'Run `postplus auth login`.');
|
|
132
133
|
}
|
|
133
134
|
const accountId = typeof payload.accountId === 'string' ? payload.accountId : 'unknown';
|
|
135
|
+
const accountName = typeof payload.accountName === 'string' ? payload.accountName : null;
|
|
136
|
+
const accountType = payload.accountType === 'personal' || payload.accountType === 'team'
|
|
137
|
+
? payload.accountType
|
|
138
|
+
: null;
|
|
134
139
|
const user = typeof payload.userEmail === 'string'
|
|
135
140
|
? payload.userEmail
|
|
136
141
|
: typeof payload.userId === 'string'
|
|
137
142
|
? payload.userId
|
|
138
143
|
: 'unknown';
|
|
139
144
|
const subscription = readSubscriptionStatusField(payload).label;
|
|
140
|
-
return createPass('remote_auth', 'Remote auth',
|
|
145
|
+
return createPass('remote_auth', 'Remote auth', `${formatAccountBindingName({
|
|
146
|
+
accountId,
|
|
147
|
+
accountName,
|
|
148
|
+
accountType,
|
|
149
|
+
})}; account ${accountId}; user ${user}; subscription ${subscription}`);
|
|
141
150
|
}
|
|
142
151
|
catch (error) {
|
|
143
152
|
return createFail('remote_auth', 'Remote auth', error instanceof Error
|
|
@@ -216,9 +225,7 @@ function readCapabilityFailureLabel(value, skillScope) {
|
|
|
216
225
|
.map(readReadinessCheckFailureLabel)
|
|
217
226
|
.filter((check) => check !== null)
|
|
218
227
|
: [];
|
|
219
|
-
const labelWithFailures = failedChecks.length > 0
|
|
220
|
-
? `${label} (${failedChecks.join(', ')})`
|
|
221
|
-
: label;
|
|
228
|
+
const labelWithFailures = failedChecks.length > 0 ? `${label} (${failedChecks.join(', ')})` : label;
|
|
222
229
|
return skillScope
|
|
223
230
|
? `${labelWithFailures} for ${skillScope.skill.skillId}`
|
|
224
231
|
: labelWithFailures;
|
package/build/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { formatAccountBindingLines } from './account-binding-display.js';
|
|
3
4
|
import { formatAuthRefreshReport, refreshRemoteAuth, revokeRemoteAuthAndReport, } from './auth-lifecycle.js';
|
|
4
5
|
import { loginWithCloudHandoff } from './auth-login.js';
|
|
5
6
|
import { formatAuthValidateReport, validateRemoteAuth, } from './auth-validate.js';
|
|
@@ -8,11 +9,11 @@ import { readCurrentCliVersion } from './client-compatibility.js';
|
|
|
8
9
|
import { formatDoctorReport, generateDoctorReport } from './doctor.js';
|
|
9
10
|
import { assertConfigFilePermissions } from './local-state.js';
|
|
10
11
|
import { readLargeCreditQuoteConfirmationChallenge, resolveLargeCreditQuoteConfirmation, } from './quote-confirmation.js';
|
|
11
|
-
import { POSTPLUS_SKILLS_CURRENT_DIRECTORY_INSTALL_COMMAND, POSTPLUS_SKILLS_INSTALL_COMMAND,
|
|
12
|
+
import { POSTPLUS_SKILLS_CURRENT_DIRECTORY_INSTALL_COMMAND, POSTPLUS_SKILLS_INSTALL_COMMAND, formatPostPlusSkillsInstallCommand, loadPublicSkillCatalog, } from './skill-catalog.js';
|
|
12
13
|
import { formatSkillBaselineVerifyReport, runPostPlusSkillUninstall, runPostPlusSkillUpdate, runPostPlusSkillVerify, } from './skill-management.js';
|
|
13
14
|
import { formatStatusReport, generateStatusReport } from './status.js';
|
|
14
|
-
import { refreshUpdateCheckCache, runCliSelfUpdateIfOutdated, } from './update-check.js';
|
|
15
15
|
import { runStudioCommand } from './studio.js';
|
|
16
|
+
import { refreshUpdateCheckCache, runCliSelfUpdateIfOutdated, } from './update-check.js';
|
|
16
17
|
function printAuthHelp() {
|
|
17
18
|
process.stdout.write(`PostPlus CLI — auth commands
|
|
18
19
|
|
|
@@ -297,7 +298,7 @@ async function runAuthLogin() {
|
|
|
297
298
|
process.stdout.write([
|
|
298
299
|
'',
|
|
299
300
|
'PostPlus CLI login complete.',
|
|
300
|
-
|
|
301
|
+
...formatAccountBindingLines(report),
|
|
301
302
|
`PostPlus Cloud: ${report.apiBaseUrl}`,
|
|
302
303
|
`User: ${report.userEmail ?? 'unknown'}`,
|
|
303
304
|
'',
|
package/build/local-state.js
CHANGED
|
@@ -94,6 +94,9 @@ export async function clearLocalAuthState() {
|
|
|
94
94
|
};
|
|
95
95
|
delete next.accessToken;
|
|
96
96
|
delete next.accountId;
|
|
97
|
+
delete next.accountName;
|
|
98
|
+
delete next.accountSlug;
|
|
99
|
+
delete next.accountType;
|
|
97
100
|
delete next.apiKey;
|
|
98
101
|
delete next.cliSessionToken;
|
|
99
102
|
delete next.machineId;
|
|
@@ -162,6 +165,9 @@ export async function setLocalSession(input) {
|
|
|
162
165
|
return updateLocalConfig((current) => ({
|
|
163
166
|
...omitLegacyAuthFields(current),
|
|
164
167
|
accountId: input.accountId,
|
|
168
|
+
accountName: input.accountName ?? null,
|
|
169
|
+
accountSlug: input.accountSlug ?? null,
|
|
170
|
+
accountType: input.accountType ?? null,
|
|
165
171
|
apiBaseUrl,
|
|
166
172
|
cliSessionToken,
|
|
167
173
|
sessionExpiresAt: input.sessionExpiresAt,
|
|
@@ -2,6 +2,7 @@ import { writeCurrentCliVersionToLocalConfig } from './client-compatibility.js';
|
|
|
2
2
|
import { runCommand, runInteractiveCommand } from './command-runner.js';
|
|
3
3
|
import { clearManagedSkillBaseline, readManagedSkillBaseline, writeManagedSkillBaseline, } from './local-state.js';
|
|
4
4
|
import { POSTPLUS_SKILLS_AGENT_TARGETS, formatPostPlusSkillsInstallCommand, resolvePostPlusSkillsSource, loadPublicSkillCatalog, } from './skill-catalog.js';
|
|
5
|
+
import { clearUpdateCheckCache } from './update-check.js';
|
|
5
6
|
const NPX_SKILLS = ['-y', 'skills'];
|
|
6
7
|
const DEFAULT_SKILL_MUTATION_OPTIONS = {
|
|
7
8
|
scope: 'global',
|
|
@@ -31,6 +32,7 @@ export async function runPostPlusSkillUpdate(dependencies = {
|
|
|
31
32
|
skillNames,
|
|
32
33
|
});
|
|
33
34
|
await writeCurrentCliVersionToLocalConfig();
|
|
35
|
+
await clearUpdateCheckCache();
|
|
34
36
|
return 0;
|
|
35
37
|
}
|
|
36
38
|
export async function runPostPlusSkillUninstall(dependencies = {
|
|
@@ -46,13 +48,14 @@ export async function runPostPlusSkillUninstall(dependencies = {
|
|
|
46
48
|
const exitCode = await dependencies.runInteractiveCommand('npx', buildPostPlusSkillUninstallArgs(allKnownSkillNames, options.scope));
|
|
47
49
|
if (exitCode === 0) {
|
|
48
50
|
await clearManagedSkillBaseline();
|
|
51
|
+
await clearUpdateCheckCache();
|
|
49
52
|
}
|
|
50
53
|
return exitCode;
|
|
51
54
|
}
|
|
52
55
|
export async function generateSkillInstallStatusReport(dependencies = {
|
|
53
56
|
runCommand,
|
|
54
|
-
}) {
|
|
55
|
-
return (await inspectPostPlusSkillInstall(dependencies)).report;
|
|
57
|
+
}, options = {}) {
|
|
58
|
+
return (await inspectPostPlusSkillInstall(dependencies, options)).report;
|
|
56
59
|
}
|
|
57
60
|
export async function runPostPlusSkillVerify(dependencies = {
|
|
58
61
|
runCommand,
|
|
@@ -72,6 +75,7 @@ export async function runPostPlusSkillVerify(dependencies = {
|
|
|
72
75
|
skillNames: inspection.requiredSkillNames,
|
|
73
76
|
});
|
|
74
77
|
await writeCurrentCliVersionToLocalConfig();
|
|
78
|
+
await clearUpdateCheckCache();
|
|
75
79
|
return {
|
|
76
80
|
...inspection.report,
|
|
77
81
|
baselineUpdated: true,
|
|
@@ -80,7 +84,7 @@ export async function runPostPlusSkillVerify(dependencies = {
|
|
|
80
84
|
verifiedSkillsReleaseId: inspection.catalog.releaseId,
|
|
81
85
|
};
|
|
82
86
|
}
|
|
83
|
-
async function inspectPostPlusSkillInstall(dependencies) {
|
|
87
|
+
async function inspectPostPlusSkillInstall(dependencies, options = {}) {
|
|
84
88
|
const catalog = await loadPublicSkillCatalog();
|
|
85
89
|
const requiredSkillNames = catalog.skills.map((skill) => skill.skillId);
|
|
86
90
|
const requiredSkills = new Set(requiredSkillNames);
|
|
@@ -91,6 +95,24 @@ async function inspectPostPlusSkillInstall(dependencies) {
|
|
|
91
95
|
const postPlusInstalled = installed.filter((skill) => requiredSkills.has(skill.name));
|
|
92
96
|
const installedNames = new Set(postPlusInstalled.map((skill) => skill.name));
|
|
93
97
|
const missingSkills = [...requiredSkills].filter((skill) => !installedNames.has(skill));
|
|
98
|
+
let managedSkillsReleaseId = baseline.releaseId;
|
|
99
|
+
let currentRetiredManagedSkills = retiredManagedSkills;
|
|
100
|
+
if (options.repairManagedBaseline === true &&
|
|
101
|
+
missingSkills.length === 0 &&
|
|
102
|
+
shouldRepairManagedBaseline({
|
|
103
|
+
baseline,
|
|
104
|
+
releaseId: catalog.releaseId,
|
|
105
|
+
skillNames: requiredSkillNames,
|
|
106
|
+
})) {
|
|
107
|
+
await writeManagedSkillBaseline({
|
|
108
|
+
releaseId: catalog.releaseId,
|
|
109
|
+
skillNames: requiredSkillNames,
|
|
110
|
+
});
|
|
111
|
+
await writeCurrentCliVersionToLocalConfig();
|
|
112
|
+
await clearUpdateCheckCache();
|
|
113
|
+
managedSkillsReleaseId = catalog.releaseId;
|
|
114
|
+
currentRetiredManagedSkills = [];
|
|
115
|
+
}
|
|
94
116
|
const scopes = [
|
|
95
117
|
...new Set(postPlusInstalled
|
|
96
118
|
.map((skill) => skill.scope)
|
|
@@ -103,10 +125,10 @@ async function inspectPostPlusSkillInstall(dependencies) {
|
|
|
103
125
|
error: null,
|
|
104
126
|
installCommand: formatPostPlusSkillsInstallCommand(catalog.source),
|
|
105
127
|
installedCount: installedNames.size,
|
|
106
|
-
managedSkillsReleaseId
|
|
128
|
+
managedSkillsReleaseId,
|
|
107
129
|
missingSkills,
|
|
108
130
|
requiredCount: requiredSkills.size,
|
|
109
|
-
retiredManagedSkills,
|
|
131
|
+
retiredManagedSkills: currentRetiredManagedSkills,
|
|
110
132
|
scopes,
|
|
111
133
|
source: catalog.source,
|
|
112
134
|
updateCommand: formatPostPlusSkillUpdateCommand(),
|
|
@@ -233,6 +255,18 @@ function buildSkillScopeArgs(scope) {
|
|
|
233
255
|
function mergeSkillNames(left, right) {
|
|
234
256
|
return [...new Set([...left, ...right])].sort((a, b) => a.localeCompare(b));
|
|
235
257
|
}
|
|
258
|
+
function shouldRepairManagedBaseline(input) {
|
|
259
|
+
if (input.baseline.releaseId !== input.releaseId) {
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
return !haveSameSkillNames(input.baseline.skillNames, input.skillNames);
|
|
263
|
+
}
|
|
264
|
+
function haveSameSkillNames(left, right) {
|
|
265
|
+
const normalizedLeft = mergeSkillNames(left, []);
|
|
266
|
+
const normalizedRight = mergeSkillNames(right, []);
|
|
267
|
+
return (normalizedLeft.length === normalizedRight.length &&
|
|
268
|
+
normalizedLeft.every((value, index) => value === normalizedRight[index]));
|
|
269
|
+
}
|
|
236
270
|
async function listInstalledSkills(dependencies) {
|
|
237
271
|
const project = await listInstalledSkillsForScope(dependencies, []);
|
|
238
272
|
const global = await listInstalledSkillsForScope(dependencies, ['--global']);
|
package/build/status.js
CHANGED
|
@@ -10,12 +10,15 @@ export async function generateStatusReportWithDependencies(dependencies = {}, op
|
|
|
10
10
|
await writeCurrentCliVersionToLocalConfig();
|
|
11
11
|
const generateAuthStatus = dependencies.generateAuthStatus ?? generateAuthStatusReport;
|
|
12
12
|
const generateDoctor = dependencies.generateDoctor ?? generateDoctorReport;
|
|
13
|
-
const generateSkillStatus = dependencies.generateSkillStatus ??
|
|
13
|
+
const generateSkillStatus = dependencies.generateSkillStatus ??
|
|
14
|
+
(() => generateSkillInstallStatusReport(undefined, {
|
|
15
|
+
repairManagedBaseline: true,
|
|
16
|
+
}));
|
|
14
17
|
const generateUpdateStatus = dependencies.generateUpdateStatus ?? generateUpdateStatusReport;
|
|
15
|
-
const
|
|
18
|
+
const skills = await generateSkillStatus();
|
|
19
|
+
const [doctor, auth, updates] = await Promise.all([
|
|
16
20
|
generateDoctor({ skillId: options.skillId }),
|
|
17
21
|
generateAuthStatus(),
|
|
18
|
-
generateSkillStatus(),
|
|
19
22
|
generateUpdateStatus(),
|
|
20
23
|
]);
|
|
21
24
|
return {
|
package/build/update-check.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
1
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { readCurrentCliVersion } from './client-compatibility.js';
|
|
4
4
|
import { runInteractiveCommand as runDefaultInteractiveCommand, } from './command-runner.js';
|
|
@@ -88,6 +88,11 @@ export async function refreshUpdateCheckCache() {
|
|
|
88
88
|
force: true,
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
|
+
export async function clearUpdateCheckCache() {
|
|
92
|
+
await rm(getUpdateCheckCachePath(), {
|
|
93
|
+
force: true,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
91
96
|
export async function runCliSelfUpdateIfOutdated(dependencies = {}) {
|
|
92
97
|
const fetchFn = dependencies.fetchFn ?? fetch;
|
|
93
98
|
const runInteractiveCommand = dependencies.runInteractiveCommand ?? runDefaultInteractiveCommand;
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postplus/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"packageManager": "pnpm@10.30.3+sha512.c961d1e0a2d8e354ecaa5166b822516668b7f44cb5bd95122d590dd81922f606f5473b6d23ec4a5be05e7fcd18e8488d47d978bbe981872f1145d06e9a740017",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "PostPlus CLI for PostPlus Cloud auth, status, and diagnostics.",
|
|
7
7
|
"license": "SEE LICENSE IN LICENSE",
|
|
8
8
|
"files": [
|
|
9
|
+
"build/account-binding-display.js",
|
|
9
10
|
"build/auth-lifecycle.js",
|
|
10
11
|
"build/auth-login.js",
|
|
11
12
|
"build/auth-session.js",
|