@postplus/cli 0.1.19 → 0.1.20
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/doctor.js +30 -5
- package/build/index.js +11 -1
- package/build/skill-catalog.js +16 -1
- package/build/skill-management.js +2 -4
- package/build/status.js +7 -2
- package/build/update-check.js +1 -1
- package/package.json +1 -1
package/build/doctor.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import { resolveFreshRemoteAuth, } from './auth-session.js';
|
|
2
2
|
import { resolveHostedBaseUrl } from './hosted-release.js';
|
|
3
3
|
import { formatLocalDependencyReport, generateLocalDependencyReport, } from './local-dependencies.js';
|
|
4
|
-
function createPass(id, label, detail) {
|
|
4
|
+
function createPass(id, label, detail, severity = 'required') {
|
|
5
5
|
return {
|
|
6
6
|
id,
|
|
7
7
|
label,
|
|
8
8
|
status: 'pass',
|
|
9
|
+
severity,
|
|
9
10
|
detail,
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
|
-
function createFail(id, label, detail, fix) {
|
|
13
|
+
function createFail(id, label, detail, fix, input = {}) {
|
|
13
14
|
return {
|
|
14
15
|
id,
|
|
15
16
|
label,
|
|
16
17
|
status: 'fail',
|
|
18
|
+
severity: input.severity ?? 'required',
|
|
17
19
|
detail,
|
|
18
20
|
fix,
|
|
21
|
+
metadata: input.metadata,
|
|
19
22
|
};
|
|
20
23
|
}
|
|
21
24
|
export async function generateDoctorReport() {
|
|
@@ -50,7 +53,19 @@ async function checkLocalDependencies() {
|
|
|
50
53
|
const report = await generateLocalDependencyReport();
|
|
51
54
|
const detail = formatLocalDependencyReport(report);
|
|
52
55
|
if (!report.ok) {
|
|
53
|
-
return createFail('local_dependencies', '
|
|
56
|
+
return createFail('local_dependencies', 'Task-specific local media dependencies', detail, 'Run the affected PostPlus skill in a local agent. The installed postplus-shared rules tell the agent how to bootstrap approved missing media dependencies.', {
|
|
57
|
+
severity: 'task_specific',
|
|
58
|
+
metadata: {
|
|
59
|
+
bootstrapRule: 'postplus-shared',
|
|
60
|
+
missingDependencies: report.checks
|
|
61
|
+
.filter((check) => !check.ok)
|
|
62
|
+
.map((check) => ({
|
|
63
|
+
dependency: check.dependency,
|
|
64
|
+
detail: check.detail,
|
|
65
|
+
skillIds: check.skillIds,
|
|
66
|
+
})),
|
|
67
|
+
},
|
|
68
|
+
});
|
|
54
69
|
}
|
|
55
70
|
return createPass('local_dependencies', 'Local dependencies', detail);
|
|
56
71
|
}
|
|
@@ -61,9 +76,11 @@ async function checkLocalDependencies() {
|
|
|
61
76
|
}
|
|
62
77
|
}
|
|
63
78
|
function buildDoctorReport(checks) {
|
|
79
|
+
const requiredOk = checks.every((check) => check.severity !== 'required' || check.status === 'pass');
|
|
64
80
|
return {
|
|
65
81
|
schemaVersion: 1,
|
|
66
82
|
ok: checks.every((check) => check.status === 'pass'),
|
|
83
|
+
requiredOk,
|
|
67
84
|
checks,
|
|
68
85
|
};
|
|
69
86
|
}
|
|
@@ -183,12 +200,20 @@ function requestWithAuth(input, path) {
|
|
|
183
200
|
export function formatDoctorReport(report) {
|
|
184
201
|
const lines = ['PostPlus CLI doctor', ''];
|
|
185
202
|
for (const check of report.checks) {
|
|
186
|
-
const marker = check.status === 'pass'
|
|
203
|
+
const marker = check.status === 'pass'
|
|
204
|
+
? '[PASS]'
|
|
205
|
+
: check.severity === 'task_specific'
|
|
206
|
+
? '[WARN]'
|
|
207
|
+
: '[FAIL]';
|
|
187
208
|
lines.push(`${marker} ${check.label}: ${check.detail}`);
|
|
188
209
|
if (check.fix) {
|
|
189
210
|
lines.push(` Fix: ${check.fix}`);
|
|
190
211
|
}
|
|
191
212
|
}
|
|
192
|
-
lines.push('', report.ok
|
|
213
|
+
lines.push('', report.ok
|
|
214
|
+
? 'Doctor passed.'
|
|
215
|
+
: report.requiredOk
|
|
216
|
+
? 'Doctor incomplete: task-specific checks need attention.'
|
|
217
|
+
: 'Doctor failed.');
|
|
193
218
|
return lines.join('\n');
|
|
194
219
|
}
|
package/build/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { assertConfigFilePermissions } from './local-state.js';
|
|
|
8
8
|
import { POSTPLUS_SKILLS_INSTALL_COMMAND, loadPublicSkillCatalog, } from './skill-catalog.js';
|
|
9
9
|
import { runPostPlusSkillUninstall, runPostPlusSkillUpdate, } from './skill-management.js';
|
|
10
10
|
import { formatStatusReport, generateStatusReport } from './status.js';
|
|
11
|
-
import { refreshUpdateCheckCache } from './update-check.js';
|
|
11
|
+
import { readCurrentCliVersion, refreshUpdateCheckCache, } from './update-check.js';
|
|
12
12
|
function printAuthHelp() {
|
|
13
13
|
process.stdout.write(`PostPlus CLI — auth commands
|
|
14
14
|
|
|
@@ -41,6 +41,7 @@ Usage:
|
|
|
41
41
|
postplus uninstall
|
|
42
42
|
postplus list [--json]
|
|
43
43
|
postplus status [--json]
|
|
44
|
+
postplus version
|
|
44
45
|
postplus help
|
|
45
46
|
|
|
46
47
|
Skills:
|
|
@@ -96,6 +97,10 @@ async function runList(json) {
|
|
|
96
97
|
process.stdout.write(`${lines.join('\n')}\n`);
|
|
97
98
|
return 0;
|
|
98
99
|
}
|
|
100
|
+
async function runVersion() {
|
|
101
|
+
process.stdout.write(`${await readCurrentCliVersion()}\n`);
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
99
104
|
async function runSkillUpdateCommand() {
|
|
100
105
|
const exitCode = await runPostPlusSkillUpdate();
|
|
101
106
|
if (exitCode === 0) {
|
|
@@ -172,6 +177,11 @@ async function main() {
|
|
|
172
177
|
printHelp();
|
|
173
178
|
process.exitCode = 0;
|
|
174
179
|
return;
|
|
180
|
+
case '--version':
|
|
181
|
+
case '-v':
|
|
182
|
+
case 'version':
|
|
183
|
+
process.exitCode = await runVersion();
|
|
184
|
+
return;
|
|
175
185
|
case 'help': {
|
|
176
186
|
const [helpTopic] = rest;
|
|
177
187
|
if (helpTopic === 'auth') {
|
package/build/skill-catalog.js
CHANGED
|
@@ -23,7 +23,8 @@ export async function loadPublicSkillCatalog(fetchFn = fetch) {
|
|
|
23
23
|
if (!response.ok) {
|
|
24
24
|
throw new Error(`Failed to load PostPlus skill catalog (${response.status}): ${response.statusText}`);
|
|
25
25
|
}
|
|
26
|
-
const
|
|
26
|
+
const raw = await response.text();
|
|
27
|
+
const payload = parseJsonResponse(raw, POSTPLUS_SKILLS_CATALOG_URL);
|
|
27
28
|
const catalog = parsePublicSkillCatalog(payload);
|
|
28
29
|
return {
|
|
29
30
|
...catalog,
|
|
@@ -33,6 +34,20 @@ export async function loadPublicSkillCatalog(fetchFn = fetch) {
|
|
|
33
34
|
listCommand: POSTPLUS_SKILLS_LIST_COMMAND,
|
|
34
35
|
};
|
|
35
36
|
}
|
|
37
|
+
function parseJsonResponse(raw, url) {
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(raw);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const trimmed = raw.trimStart();
|
|
43
|
+
if (trimmed.startsWith('<')) {
|
|
44
|
+
throw new Error(`PostPlus public skill catalog returned HTML instead of JSON: ${url}`);
|
|
45
|
+
}
|
|
46
|
+
throw new Error(error instanceof Error
|
|
47
|
+
? `PostPlus public skill catalog returned invalid JSON: ${error.message}`
|
|
48
|
+
: 'PostPlus public skill catalog returned invalid JSON.');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
36
51
|
function parsePublicSkillCatalog(payload) {
|
|
37
52
|
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
38
53
|
throw new Error('PostPlus public skill catalog is invalid.');
|
|
@@ -144,10 +144,8 @@ function mergeSkillNames(left, right) {
|
|
|
144
144
|
return [...new Set([...left, ...right])].sort((a, b) => a.localeCompare(b));
|
|
145
145
|
}
|
|
146
146
|
async function listInstalledSkills(dependencies) {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
listInstalledSkillsForScope(dependencies, ['--global']),
|
|
150
|
-
]);
|
|
147
|
+
const project = await listInstalledSkillsForScope(dependencies, []);
|
|
148
|
+
const global = await listInstalledSkillsForScope(dependencies, ['--global']);
|
|
151
149
|
const byKey = new Map();
|
|
152
150
|
for (const skill of [...project, ...global]) {
|
|
153
151
|
byKey.set(`${skill.scope}:${skill.name}:${skill.path}`, skill);
|
package/build/status.js
CHANGED
|
@@ -18,7 +18,7 @@ export async function generateStatusReportWithDependencies(dependencies = {}) {
|
|
|
18
18
|
]);
|
|
19
19
|
return {
|
|
20
20
|
schemaVersion: 1,
|
|
21
|
-
ok: doctor.
|
|
21
|
+
ok: doctor.requiredOk && auth.ok && skills.ok && updates.ok,
|
|
22
22
|
doctor,
|
|
23
23
|
auth,
|
|
24
24
|
skills,
|
|
@@ -26,10 +26,15 @@ export async function generateStatusReportWithDependencies(dependencies = {}) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
export function formatStatusReport(report) {
|
|
29
|
+
const taskSpecificChecksNeedAttention = report.doctor.requiredOk && !report.doctor.ok;
|
|
29
30
|
return [
|
|
30
31
|
'PostPlus CLI status',
|
|
31
32
|
'',
|
|
32
|
-
`Overall: ${report.ok
|
|
33
|
+
`Overall: ${report.ok
|
|
34
|
+
? taskSpecificChecksNeedAttention
|
|
35
|
+
? 'OK (task-specific checks need attention)'
|
|
36
|
+
: 'OK'
|
|
37
|
+
: 'INCOMPLETE'}`,
|
|
33
38
|
'',
|
|
34
39
|
formatDoctorReport(report.doctor),
|
|
35
40
|
'',
|
package/build/update-check.js
CHANGED
|
@@ -125,7 +125,7 @@ function buildUpdateReport(input) {
|
|
|
125
125
|
warning: null,
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
-
async function readCurrentCliVersion() {
|
|
128
|
+
export async function readCurrentCliVersion() {
|
|
129
129
|
const packageJsonPath = new URL('../package.json', import.meta.url);
|
|
130
130
|
const raw = await readFile(packageJsonPath, 'utf8');
|
|
131
131
|
const parsed = JSON.parse(raw);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postplus/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
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.",
|