careervivid 1.5.0 → 1.7.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/dist/api.d.ts +1 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +4 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +103 -4
- package/dist/commands/update.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export interface ApiError {
|
|
|
39
39
|
}[];
|
|
40
40
|
}
|
|
41
41
|
export declare function publishPost(payload: PublishPayload, dryRun?: boolean): Promise<PublishResult | ApiError>;
|
|
42
|
+
export declare function updatePost(postId: string, payload: Partial<PublishPayload>): Promise<PublishResult | ApiError>;
|
|
42
43
|
/**
|
|
43
44
|
* Verify an API key against the /verifyAuth endpoint.
|
|
44
45
|
* Optionally accepts a specific key (for set-key validation).
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;AAChD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACrB,OAAO,EAAE,IAAI,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjD;AAmED,wBAAsB,WAAW,CAC7B,OAAO,EAAE,cAAc,EACvB,MAAM,UAAQ,GACf,OAAO,CAAC,aAAa,GAAG,QAAQ,CAAC,CAgBnC;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,QAAQ,CAAC,CAwC9E;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAMzE;AAED,wBAAsB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAAC,CAEnJ;AAED,wBAAsB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAAC,CAEnK;AAED,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAAC,CAEpK;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAAC,CAEvJ;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,QAAQ,CAEpD"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { getApiKey, getApiUrl } from "./config.js";
|
|
8
8
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
9
|
-
const CLI_VERSION = "1.
|
|
9
|
+
const CLI_VERSION = "1.7.0";
|
|
10
10
|
function requireApiKey() {
|
|
11
11
|
const key = getApiKey();
|
|
12
12
|
if (!key) {
|
|
@@ -73,6 +73,9 @@ export async function publishPost(payload, dryRun = false) {
|
|
|
73
73
|
}
|
|
74
74
|
return apiRequest("POST", "publish", payload);
|
|
75
75
|
}
|
|
76
|
+
export async function updatePost(postId, payload) {
|
|
77
|
+
return apiRequest("PATCH", "publish", { ...payload, postId });
|
|
78
|
+
}
|
|
76
79
|
/**
|
|
77
80
|
* Verify an API key against the /verifyAuth endpoint.
|
|
78
81
|
* Optionally accepts a specific key (for set-key validation).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8KpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6J7D"}
|
package/dist/commands/publish.js
CHANGED
|
@@ -53,12 +53,31 @@ function getFiles(dir, recursive) {
|
|
|
53
53
|
}
|
|
54
54
|
async function publishSingleFile(filePath, content, opts, jsonMode) {
|
|
55
55
|
const dryRun = !!opts.dryRun;
|
|
56
|
+
// ── Parse Frontmatter ───────────────────────────────────────────
|
|
57
|
+
let postId = undefined;
|
|
58
|
+
let cleanContent = content;
|
|
59
|
+
// Robust frontmatter extraction (multiline, flexible spacing)
|
|
60
|
+
const frontmatterMatch = content.match(/^---\s*[\r\n]+([\s\S]*?)[\r\n]+---\s*[\r\n]+/);
|
|
61
|
+
if (frontmatterMatch) {
|
|
62
|
+
const fm = frontmatterMatch[1];
|
|
63
|
+
// Match postId with potential leading/trailing whitespace or quotes
|
|
64
|
+
const idMatch = fm.match(/postId:\s*["']?([a-zA-Z0-9_-]+)["']?/i);
|
|
65
|
+
postId = idMatch?.[1];
|
|
66
|
+
cleanContent = content.slice(frontmatterMatch[0].length);
|
|
67
|
+
}
|
|
68
|
+
// Fail if onlyUpdate is set but no postId is found
|
|
69
|
+
if (opts.onlyUpdate && !postId) {
|
|
70
|
+
if (!jsonMode) {
|
|
71
|
+
console.error(chalk.red(`\n ✖ Missing postId frontmatter in ${filePath}. Use 'cv publish' to create a new post.`));
|
|
72
|
+
}
|
|
73
|
+
return { success: false };
|
|
74
|
+
}
|
|
56
75
|
const format = opts.format ||
|
|
57
76
|
(filePath !== "stdin" ? inferFormat(filePath) : "markdown");
|
|
58
77
|
const type = opts.type || inferType(format);
|
|
59
78
|
let title = opts.title || "";
|
|
60
79
|
if (!title && format === "markdown") {
|
|
61
|
-
const firstHeading =
|
|
80
|
+
const firstHeading = cleanContent.match(/^#\s+(.+)$/m);
|
|
62
81
|
if (firstHeading) {
|
|
63
82
|
title = firstHeading[1].trim();
|
|
64
83
|
}
|
|
@@ -86,21 +105,43 @@ async function publishSingleFile(filePath, content, opts, jsonMode) {
|
|
|
86
105
|
type,
|
|
87
106
|
dataFormat: format,
|
|
88
107
|
title,
|
|
89
|
-
content,
|
|
108
|
+
content: cleanContent,
|
|
90
109
|
tags,
|
|
91
110
|
...(opts.cover ? { coverImage: opts.cover } : {}),
|
|
92
111
|
...(opts.official ? { isOfficialPost: true } : {}),
|
|
93
112
|
};
|
|
94
|
-
|
|
113
|
+
let result;
|
|
114
|
+
if (postId && !dryRun) {
|
|
115
|
+
const { updatePost } = await import("../api.js");
|
|
116
|
+
result = await updatePost(postId, payload);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
result = await publishPost(payload, dryRun);
|
|
120
|
+
}
|
|
95
121
|
if (isApiError(result)) {
|
|
96
122
|
if (jsonMode) {
|
|
97
123
|
handleApiError(result, true);
|
|
98
124
|
}
|
|
99
125
|
else {
|
|
100
|
-
console.error(chalk.red(`\n ✖ Failed to publish ${filePath}: ${result.message}`));
|
|
126
|
+
console.error(chalk.red(`\n ✖ Failed to ${postId ? "update" : "publish"} ${filePath}: ${result.message}`));
|
|
101
127
|
}
|
|
102
128
|
return { success: false };
|
|
103
129
|
}
|
|
130
|
+
// ── Write back postId if it's new ────────────────────────────────
|
|
131
|
+
if (!postId && !dryRun && filePath !== "stdin" && result.postId) {
|
|
132
|
+
const newFm = `---\npostId: ${result.postId}\n---\n\n`;
|
|
133
|
+
const updatedFileContent = newFm + content;
|
|
134
|
+
try {
|
|
135
|
+
const { writeFileSync } = await import("fs");
|
|
136
|
+
writeFileSync(filePath, updatedFileContent, "utf-8");
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
// Non-fatal error
|
|
140
|
+
if (!jsonMode) {
|
|
141
|
+
console.warn(chalk.yellow(` ⚠ Could not write postId to ${filePath}`));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
104
145
|
return {
|
|
105
146
|
success: true,
|
|
106
147
|
url: result.url,
|
|
@@ -198,4 +239,62 @@ export function registerPublishCommand(program) {
|
|
|
198
239
|
console.log(`\n ${chalk.yellow("Dry run complete.")} Validated ${chalk.bold(fileList.length)} files.\n`);
|
|
199
240
|
}
|
|
200
241
|
});
|
|
242
|
+
program
|
|
243
|
+
.command("update [files...]")
|
|
244
|
+
.description("Update existing content on CareerVivid (requires postId in frontmatter)")
|
|
245
|
+
.option("-t, --title <title>", "Override post title")
|
|
246
|
+
.option("--tags <tags>", "Comma-separated tags")
|
|
247
|
+
.option("--dry-run", "Validate without updating")
|
|
248
|
+
.option("--json", "Machine-readable output")
|
|
249
|
+
.option("-r, --recursive", "Recursively scan directories")
|
|
250
|
+
.action(async (files, opts) => {
|
|
251
|
+
const extendedOpts = { ...opts, onlyUpdate: true };
|
|
252
|
+
const jsonMode = !!opts.json;
|
|
253
|
+
const dryRun = !!opts.dryRun;
|
|
254
|
+
let fileList = [];
|
|
255
|
+
if (files.length === 0) {
|
|
256
|
+
printError("No files specified to update.", undefined, jsonMode);
|
|
257
|
+
process.exit(1);
|
|
258
|
+
}
|
|
259
|
+
for (const arg of files) {
|
|
260
|
+
try {
|
|
261
|
+
const stat = lstatSync(arg);
|
|
262
|
+
if (stat.isDirectory()) {
|
|
263
|
+
fileList = fileList.concat(getFiles(arg, !!opts.recursive));
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
fileList.push(arg);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
printError(`Cannot find path: ${arg}`, undefined, jsonMode);
|
|
271
|
+
process.exit(1);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (!jsonMode && !dryRun) {
|
|
275
|
+
console.log(`\n ${chalk.bold("Preparing to update")} ${chalk.cyan(fileList.length)} ${fileList.length === 1 ? "file" : "files"}...`);
|
|
276
|
+
}
|
|
277
|
+
const results = [];
|
|
278
|
+
let successCount = 0;
|
|
279
|
+
for (const filePath of fileList) {
|
|
280
|
+
const content = readFileSync(filePath, "utf-8");
|
|
281
|
+
const spinner = (!jsonMode && !dryRun) ? ora(`Updating ${chalk.cyan(filePath)}...`).start() : null;
|
|
282
|
+
const res = await publishSingleFile(filePath, content, extendedOpts, jsonMode);
|
|
283
|
+
spinner?.stop();
|
|
284
|
+
if (res.success) {
|
|
285
|
+
successCount++;
|
|
286
|
+
results.push({ file: filePath, ...res });
|
|
287
|
+
if (!jsonMode && !dryRun) {
|
|
288
|
+
console.log(` ${chalk.green("✔")} Updated: ${chalk.bold(res.title)}`);
|
|
289
|
+
console.log(` ${chalk.dim(res.url)}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (jsonMode) {
|
|
294
|
+
console.log(JSON.stringify(results, null, 2));
|
|
295
|
+
}
|
|
296
|
+
else if (!dryRun) {
|
|
297
|
+
console.log(`\n ${chalk.green("Done!")} Successfully updated ${chalk.bold(successCount)} of ${chalk.bold(fileList.length)} files.\n`);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
201
300
|
}
|
package/dist/commands/update.js
CHANGED
|
@@ -10,7 +10,7 @@ import { spawn } from "child_process";
|
|
|
10
10
|
import { getHelpHeader } from "../branding.js";
|
|
11
11
|
export function registerUpdateCommand(program) {
|
|
12
12
|
program
|
|
13
|
-
.command("
|
|
13
|
+
.command("upgrade")
|
|
14
14
|
.description("Upgrade the CareerVivid CLI to the latest version")
|
|
15
15
|
.action(async () => {
|
|
16
16
|
console.log(getHelpHeader());
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* cv config show Print current configuration
|
|
16
16
|
* cv config set <key> <value> Update a config value
|
|
17
17
|
* cv config get <key> Print a config value
|
|
18
|
-
* cv
|
|
18
|
+
* cv upgrade Upgrade the CLI to the latest version
|
|
19
|
+
* cv update [files...] Update existing content on CareerVivid
|
|
19
20
|
* cv --help / cv --version
|
|
20
21
|
*/
|
|
21
22
|
export {};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
package/dist/index.js
CHANGED
|
@@ -15,12 +15,15 @@
|
|
|
15
15
|
* cv config show Print current configuration
|
|
16
16
|
* cv config set <key> <value> Update a config value
|
|
17
17
|
* cv config get <key> Print a config value
|
|
18
|
-
* cv
|
|
18
|
+
* cv upgrade Upgrade the CLI to the latest version
|
|
19
|
+
* cv update [files...] Update existing content on CareerVivid
|
|
19
20
|
* cv --help / cv --version
|
|
20
21
|
*/
|
|
21
22
|
import { Command } from "commander";
|
|
23
|
+
import { readFileSync, existsSync } from "fs";
|
|
22
24
|
import chalk from "chalk";
|
|
23
|
-
import {
|
|
25
|
+
import { join, dirname } from "path";
|
|
26
|
+
import { fileURLToPath } from "url";
|
|
24
27
|
import { CONFIG_FILE } from "./config.js";
|
|
25
28
|
import { getHelpHeader, printWelcome } from "./branding.js";
|
|
26
29
|
import { registerAuthCommand } from "./commands/auth.js";
|
|
@@ -34,11 +37,13 @@ import { registerPortfolioCommand } from "./commands/portfolio.js";
|
|
|
34
37
|
import { registerWorkspaceCommand } from "./commands/workspace.js";
|
|
35
38
|
import { registerProfileCommand } from "./commands/profile.js";
|
|
36
39
|
import { registerJobsCommand } from "./commands/jobs.js";
|
|
40
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
41
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
|
|
37
42
|
const program = new Command();
|
|
38
43
|
program
|
|
39
44
|
.name("cv")
|
|
40
45
|
.description("CareerVivid CLI — publish articles, diagrams, and portfolio updates from your terminal or AI agent")
|
|
41
|
-
.version(
|
|
46
|
+
.version(pkg.version, "-v, --version", "Print CLI version")
|
|
42
47
|
.addHelpText("before", getHelpHeader())
|
|
43
48
|
.helpOption("-h, --help", "Show help");
|
|
44
49
|
registerAuthCommand(program);
|