@deskwork/cli 0.9.5
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.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +98 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +13 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +91 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/approve.d.ts +18 -0
- package/dist/commands/approve.d.ts.map +1 -0
- package/dist/commands/approve.js +179 -0
- package/dist/commands/approve.js.map +1 -0
- package/dist/commands/customize.d.ts +47 -0
- package/dist/commands/customize.d.ts.map +1 -0
- package/dist/commands/customize.js +176 -0
- package/dist/commands/customize.js.map +1 -0
- package/dist/commands/distribute.d.ts +30 -0
- package/dist/commands/distribute.d.ts.map +1 -0
- package/dist/commands/distribute.js +148 -0
- package/dist/commands/distribute.js.map +1 -0
- package/dist/commands/doctor.d.ts +35 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +354 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/draft.d.ts +17 -0
- package/dist/commands/draft.d.ts.map +1 -0
- package/dist/commands/draft.js +77 -0
- package/dist/commands/draft.js.map +1 -0
- package/dist/commands/ingest.d.ts +43 -0
- package/dist/commands/ingest.d.ts.map +1 -0
- package/dist/commands/ingest.js +321 -0
- package/dist/commands/ingest.js.map +1 -0
- package/dist/commands/install-preflight.d.ts +83 -0
- package/dist/commands/install-preflight.d.ts.map +1 -0
- package/dist/commands/install-preflight.js +300 -0
- package/dist/commands/install-preflight.js.map +1 -0
- package/dist/commands/install.d.ts +27 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +132 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/iterate.d.ts +33 -0
- package/dist/commands/iterate.d.ts.map +1 -0
- package/dist/commands/iterate.js +202 -0
- package/dist/commands/iterate.js.map +1 -0
- package/dist/commands/outline.d.ts +19 -0
- package/dist/commands/outline.d.ts.map +1 -0
- package/dist/commands/outline.js +102 -0
- package/dist/commands/outline.js.map +1 -0
- package/dist/commands/pause.d.ts +15 -0
- package/dist/commands/pause.d.ts.map +1 -0
- package/dist/commands/pause.js +70 -0
- package/dist/commands/pause.js.map +1 -0
- package/dist/commands/plan.d.ts +12 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +74 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/publish.d.ts +18 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +105 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/resume.d.ts +16 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +70 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/review-cancel.d.ts +15 -0
- package/dist/commands/review-cancel.d.ts.map +1 -0
- package/dist/commands/review-cancel.js +88 -0
- package/dist/commands/review-cancel.js.map +1 -0
- package/dist/commands/review-help.d.ts +12 -0
- package/dist/commands/review-help.d.ts.map +1 -0
- package/dist/commands/review-help.js +52 -0
- package/dist/commands/review-help.js.map +1 -0
- package/dist/commands/review-report.d.ts +13 -0
- package/dist/commands/review-report.d.ts.map +1 -0
- package/dist/commands/review-report.js +53 -0
- package/dist/commands/review-report.js.map +1 -0
- package/dist/commands/review-start.d.ts +17 -0
- package/dist/commands/review-start.d.ts.map +1 -0
- package/dist/commands/review-start.js +121 -0
- package/dist/commands/review-start.js.map +1 -0
- package/dist/commands/shortform-start.d.ts +33 -0
- package/dist/commands/shortform-start.d.ts.map +1 -0
- package/dist/commands/shortform-start.js +127 -0
- package/dist/commands/shortform-start.js.map +1 -0
- package/package.json +45 -0
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* deskwork — single dispatch entry for the editorial CLI.
|
|
4
|
+
*
|
|
5
|
+
* Each subcommand lives in its own module under ./commands. Subcommands
|
|
6
|
+
* export `run(argv: string[]): Promise<void>`. They emit JSON to stdout
|
|
7
|
+
* for success, write to stderr + `process.exit(N)` (via lib/cli.ts:fail)
|
|
8
|
+
* for failure.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* deskwork <subcommand> [args...]
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* deskwork install <project-root> <config-file>
|
|
15
|
+
* deskwork add "My First Post" --site main
|
|
16
|
+
* deskwork outline draft-me --author "Jane"
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* deskwork — single dispatch entry for the editorial CLI.
|
|
4
|
+
*
|
|
5
|
+
* Each subcommand lives in its own module under ./commands. Subcommands
|
|
6
|
+
* export `run(argv: string[]): Promise<void>`. They emit JSON to stdout
|
|
7
|
+
* for success, write to stderr + `process.exit(N)` (via lib/cli.ts:fail)
|
|
8
|
+
* for failure.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* deskwork <subcommand> [args...]
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* deskwork install <project-root> <config-file>
|
|
15
|
+
* deskwork add "My First Post" --site main
|
|
16
|
+
* deskwork outline draft-me --author "Jane"
|
|
17
|
+
*/
|
|
18
|
+
const SUBCOMMANDS = {
|
|
19
|
+
add: () => import("./commands/add.js"),
|
|
20
|
+
approve: () => import("./commands/approve.js"),
|
|
21
|
+
customize: () => import("./commands/customize.js"),
|
|
22
|
+
distribute: () => import("./commands/distribute.js"),
|
|
23
|
+
doctor: () => import("./commands/doctor.js"),
|
|
24
|
+
draft: () => import("./commands/draft.js"),
|
|
25
|
+
ingest: () => import("./commands/ingest.js"),
|
|
26
|
+
install: () => import("./commands/install.js"),
|
|
27
|
+
iterate: () => import("./commands/iterate.js"),
|
|
28
|
+
outline: () => import("./commands/outline.js"),
|
|
29
|
+
pause: () => import("./commands/pause.js"),
|
|
30
|
+
plan: () => import("./commands/plan.js"),
|
|
31
|
+
publish: () => import("./commands/publish.js"),
|
|
32
|
+
resume: () => import("./commands/resume.js"),
|
|
33
|
+
'review-cancel': () => import("./commands/review-cancel.js"),
|
|
34
|
+
'review-help': () => import("./commands/review-help.js"),
|
|
35
|
+
'review-report': () => import("./commands/review-report.js"),
|
|
36
|
+
'review-start': () => import("./commands/review-start.js"),
|
|
37
|
+
'shortform-start': () => import("./commands/shortform-start.js"),
|
|
38
|
+
};
|
|
39
|
+
const subcommand = process.argv[2];
|
|
40
|
+
const rawArgv = process.argv.slice(3);
|
|
41
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help') {
|
|
42
|
+
printUsage();
|
|
43
|
+
process.exit(subcommand ? 0 : 2);
|
|
44
|
+
}
|
|
45
|
+
// Each command treats the first positional as <project-root>. To keep
|
|
46
|
+
// invocations short ("deskwork add 'My Post'" instead of
|
|
47
|
+
// "deskwork add . 'My Post'"), we inject process.cwd() when the user
|
|
48
|
+
// didn't pass an explicit path. The heuristic: the first non-flag arg
|
|
49
|
+
// is path-like only when it starts with `/`, `./`, `../`, or is exactly `.`.
|
|
50
|
+
// Anything else (a title, a slug, a flag) means "no project-root passed".
|
|
51
|
+
const argv = injectProjectRoot(rawArgv);
|
|
52
|
+
const loader = SUBCOMMANDS[subcommand];
|
|
53
|
+
if (!loader) {
|
|
54
|
+
process.stderr.write(`unknown subcommand: ${subcommand}\n`);
|
|
55
|
+
process.stderr.write(`Available: ${Object.keys(SUBCOMMANDS).sort().join(', ')}\n`);
|
|
56
|
+
process.exit(2);
|
|
57
|
+
}
|
|
58
|
+
const mod = await loader();
|
|
59
|
+
await mod.run(argv);
|
|
60
|
+
function injectProjectRoot(args) {
|
|
61
|
+
const firstPositional = args.find((a) => !a.startsWith('--'));
|
|
62
|
+
if (firstPositional && pathLike(firstPositional))
|
|
63
|
+
return args;
|
|
64
|
+
return [process.cwd(), ...args];
|
|
65
|
+
}
|
|
66
|
+
function pathLike(s) {
|
|
67
|
+
return s === '.' || s.startsWith('/') || s.startsWith('./') || s.startsWith('../');
|
|
68
|
+
}
|
|
69
|
+
function printUsage() {
|
|
70
|
+
const out = subcommand ? process.stdout : process.stderr;
|
|
71
|
+
out.write('Usage: deskwork <subcommand> [args...]\n\n');
|
|
72
|
+
out.write('Lifecycle:\n');
|
|
73
|
+
out.write(' install bootstrap deskwork in a project\n');
|
|
74
|
+
out.write(' ingest backfill existing markdown into the calendar\n');
|
|
75
|
+
out.write(' add append an idea to the calendar\n');
|
|
76
|
+
out.write(' plan move Ideas → Planned with keywords\n');
|
|
77
|
+
out.write(' outline scaffold + move Planned → Outlining\n');
|
|
78
|
+
out.write(' draft move Outlining → Drafting\n');
|
|
79
|
+
out.write(' publish move to Published\n');
|
|
80
|
+
out.write(' pause move a non-terminal entry to Paused\n');
|
|
81
|
+
out.write(' resume restore a Paused entry to its prior stage\n\n');
|
|
82
|
+
out.write('Maintenance:\n');
|
|
83
|
+
out.write(' doctor audit/repair binding metadata\n');
|
|
84
|
+
out.write(' customize copy a plugin default into .deskwork/<category>/<name>.ts\n\n');
|
|
85
|
+
out.write('Review loop:\n');
|
|
86
|
+
out.write(' review-start enqueue a longform draft for review\n');
|
|
87
|
+
out.write(' shortform-start enqueue a shortform draft for review\n');
|
|
88
|
+
out.write(' iterate snapshot agent revision; back to in-review\n');
|
|
89
|
+
out.write(' approve finalize an approved workflow\n');
|
|
90
|
+
out.write(' review-cancel cancel a workflow\n');
|
|
91
|
+
out.write(' review-help list open workflows\n');
|
|
92
|
+
out.write(' review-report voice-drift report\n\n');
|
|
93
|
+
out.write('Distribution:\n');
|
|
94
|
+
out.write(' distribute record a posted shortform URL on the calendar\n\n');
|
|
95
|
+
out.write('Run `deskwork <subcommand>` with no further args to see its usage.\n');
|
|
96
|
+
}
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deskwork-add — append a new idea to the editorial calendar.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* deskwork-add <project-root> [--site <slug>] [--type blog|youtube|tool]
|
|
6
|
+
* [--content-url URL] [--source manual|analytics]
|
|
7
|
+
* <title> [description]
|
|
8
|
+
*
|
|
9
|
+
* Writes the calendar atomically. Emits a JSON result on stdout:
|
|
10
|
+
* { "slug": "...", "stage": "Ideas", "site": "...", "calendarPath": "..." }
|
|
11
|
+
*/
|
|
12
|
+
export declare function run(argv: string[]): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=add.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuFvD"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deskwork-add — append a new idea to the editorial calendar.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* deskwork-add <project-root> [--site <slug>] [--type blog|youtube|tool]
|
|
6
|
+
* [--content-url URL] [--source manual|analytics]
|
|
7
|
+
* <title> [description]
|
|
8
|
+
*
|
|
9
|
+
* Writes the calendar atomically. Emits a JSON result on stdout:
|
|
10
|
+
* { "slug": "...", "stage": "Ideas", "site": "...", "calendarPath": "..." }
|
|
11
|
+
*/
|
|
12
|
+
import { readConfig } from '@deskwork/core/config';
|
|
13
|
+
import { readCalendar, writeCalendar } from '@deskwork/core/calendar';
|
|
14
|
+
import { addEntry } from '@deskwork/core/calendar-mutations';
|
|
15
|
+
import { resolveSite, resolveCalendarPath } from '@deskwork/core/paths';
|
|
16
|
+
import { isContentType } from '@deskwork/core/types';
|
|
17
|
+
import { absolutize, emit, fail, parseArgs } from '@deskwork/core/cli-args';
|
|
18
|
+
export async function run(argv) {
|
|
19
|
+
const KNOWN_FLAGS = ['site', 'type', 'content-url', 'source', 'slug'];
|
|
20
|
+
const SLUG_RE = /^[a-z0-9][a-z0-9-]*(\/[a-z0-9][a-z0-9-]*)*$/;
|
|
21
|
+
const { positional, flags } = parse();
|
|
22
|
+
if (positional.length < 2) {
|
|
23
|
+
fail('Usage: deskwork-add <project-root> [--site <slug>] [--type blog|youtube|tool] ' +
|
|
24
|
+
'[--content-url URL] [--source manual|analytics] [--slug <path>] ' +
|
|
25
|
+
'<title> [description]', 2);
|
|
26
|
+
}
|
|
27
|
+
if (flags.slug !== undefined && !SLUG_RE.test(flags.slug)) {
|
|
28
|
+
fail(`--slug must be one or more /-separated kebab-case segments ` +
|
|
29
|
+
`(got "${flags.slug}")`, 2);
|
|
30
|
+
}
|
|
31
|
+
const [rootArg, title, ...rest] = positional;
|
|
32
|
+
const description = rest.join(' ').trim();
|
|
33
|
+
const projectRoot = absolutize(rootArg);
|
|
34
|
+
let config;
|
|
35
|
+
try {
|
|
36
|
+
config = readConfig(projectRoot);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
40
|
+
}
|
|
41
|
+
const site = resolveSite(config, flags.site);
|
|
42
|
+
const calendarPath = resolveCalendarPath(projectRoot, config, site);
|
|
43
|
+
let contentType;
|
|
44
|
+
if (flags.type !== undefined) {
|
|
45
|
+
if (!isContentType(flags.type)) {
|
|
46
|
+
fail(`Invalid --type "${flags.type}". Must be one of: blog, youtube, tool.`);
|
|
47
|
+
}
|
|
48
|
+
contentType = flags.type;
|
|
49
|
+
}
|
|
50
|
+
let source = 'manual';
|
|
51
|
+
if (flags.source !== undefined) {
|
|
52
|
+
if (flags.source !== 'manual' && flags.source !== 'analytics') {
|
|
53
|
+
fail(`Invalid --source "${flags.source}". Must be "manual" or "analytics".`);
|
|
54
|
+
}
|
|
55
|
+
source = flags.source;
|
|
56
|
+
}
|
|
57
|
+
const calendar = readCalendar(calendarPath);
|
|
58
|
+
let entry;
|
|
59
|
+
try {
|
|
60
|
+
entry = addEntry(calendar, title, {
|
|
61
|
+
description,
|
|
62
|
+
source,
|
|
63
|
+
...(contentType !== undefined ? { contentType } : {}),
|
|
64
|
+
...(flags['content-url'] !== undefined ? { contentUrl: flags['content-url'] } : {}),
|
|
65
|
+
...(flags.slug !== undefined ? { slug: flags.slug } : {}),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
70
|
+
}
|
|
71
|
+
writeCalendar(calendarPath, calendar);
|
|
72
|
+
emit({
|
|
73
|
+
slug: entry.slug,
|
|
74
|
+
title: entry.title,
|
|
75
|
+
stage: entry.stage,
|
|
76
|
+
description: entry.description,
|
|
77
|
+
site,
|
|
78
|
+
calendarPath,
|
|
79
|
+
contentType: entry.contentType,
|
|
80
|
+
contentUrl: entry.contentUrl,
|
|
81
|
+
});
|
|
82
|
+
function parse() {
|
|
83
|
+
try {
|
|
84
|
+
return parseArgs(argv, KNOWN_FLAGS);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
fail(err instanceof Error ? err.message : String(err), 2);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deskwork-approve — terminal write step for the review loop.
|
|
3
|
+
*
|
|
4
|
+
* For **longform**, the SSOT invariant says disk is already the approved
|
|
5
|
+
* content (the studio save handler writes disk first, approve annotation
|
|
6
|
+
* captures the current version). This helper just transitions the
|
|
7
|
+
* workflow to 'applied'. If disk has moved on since the approve click,
|
|
8
|
+
* the helper refuses rather than silently rolling back.
|
|
9
|
+
*
|
|
10
|
+
* For **shortform**, the approved markdown is written into the matching
|
|
11
|
+
* DistributionRecord's `shortform` field in the calendar.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* deskwork-approve <project-root> [--site <slug>] <slug>
|
|
15
|
+
* deskwork-approve <project-root> [--site <slug>] <slug> --platform <p> [--channel <c>]
|
|
16
|
+
*/
|
|
17
|
+
export declare function run(argv: string[]): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=approve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA6BH,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+MvD"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deskwork-approve — terminal write step for the review loop.
|
|
3
|
+
*
|
|
4
|
+
* For **longform**, the SSOT invariant says disk is already the approved
|
|
5
|
+
* content (the studio save handler writes disk first, approve annotation
|
|
6
|
+
* captures the current version). This helper just transitions the
|
|
7
|
+
* workflow to 'applied'. If disk has moved on since the approve click,
|
|
8
|
+
* the helper refuses rather than silently rolling back.
|
|
9
|
+
*
|
|
10
|
+
* For **shortform**, the approved markdown is written into the matching
|
|
11
|
+
* DistributionRecord's `shortform` field in the calendar.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* deskwork-approve <project-root> [--site <slug>] <slug>
|
|
15
|
+
* deskwork-approve <project-root> [--site <slug>] <slug> --platform <p> [--channel <c>]
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
18
|
+
import { readConfig } from '@deskwork/core/config';
|
|
19
|
+
import { resolveSite, resolveCalendarPath, resolveEntryFilePath, resolveShortformFilePath, } from '@deskwork/core/paths';
|
|
20
|
+
import { readCalendar, writeCalendar } from '@deskwork/core/calendar';
|
|
21
|
+
import { parseFrontmatter } from '@deskwork/core/frontmatter';
|
|
22
|
+
import { handleGetWorkflow, } from '@deskwork/core/review/handlers';
|
|
23
|
+
import { readAnnotations, transitionState, } from '@deskwork/core/review/pipeline';
|
|
24
|
+
import { isPlatform } from '@deskwork/core/types';
|
|
25
|
+
import { absolutize, emit, fail, parseArgs } from '@deskwork/core/cli-args';
|
|
26
|
+
export async function run(argv) {
|
|
27
|
+
const KNOWN_FLAGS = ['site', 'platform', 'channel'];
|
|
28
|
+
const SLUG_RE = /^[a-z0-9][a-z0-9-]*(\/[a-z0-9][a-z0-9-]*)*$/;
|
|
29
|
+
const { positional, flags } = parse();
|
|
30
|
+
if (positional.length < 2) {
|
|
31
|
+
fail('Usage: deskwork-approve <project-root> [--site <slug>] <slug> ' +
|
|
32
|
+
'[--platform <p>] [--channel <c>]', 2);
|
|
33
|
+
}
|
|
34
|
+
const [rootArg, slug] = positional;
|
|
35
|
+
const projectRoot = absolutize(rootArg);
|
|
36
|
+
if (!SLUG_RE.test(slug)) {
|
|
37
|
+
fail(`invalid slug: ${slug} (must match ${SLUG_RE})`);
|
|
38
|
+
}
|
|
39
|
+
if (flags.platform !== undefined && !isPlatform(flags.platform)) {
|
|
40
|
+
fail(`Invalid --platform "${flags.platform}".`);
|
|
41
|
+
}
|
|
42
|
+
let config;
|
|
43
|
+
try {
|
|
44
|
+
config = readConfig(projectRoot);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
48
|
+
}
|
|
49
|
+
const site = resolveSite(config, flags.site);
|
|
50
|
+
const contentKind = flags.platform ? 'shortform' : 'longform';
|
|
51
|
+
const fetched = handleGetWorkflow(projectRoot, config, {
|
|
52
|
+
id: null,
|
|
53
|
+
site,
|
|
54
|
+
slug,
|
|
55
|
+
contentKind,
|
|
56
|
+
platform: flags.platform ?? null,
|
|
57
|
+
channel: flags.channel ?? null,
|
|
58
|
+
});
|
|
59
|
+
if (fetched.status !== 200 || !isSuccessBody(fetched.body)) {
|
|
60
|
+
fail(`no ${contentKind} workflow for ${site}/${slug}: ${errorMessage(fetched.body)}`);
|
|
61
|
+
}
|
|
62
|
+
const workflow = fetched.body.workflow;
|
|
63
|
+
const versions = fetched.body.versions;
|
|
64
|
+
if (workflow.state !== 'approved') {
|
|
65
|
+
fail(`Workflow state is '${workflow.state}', not 'approved'. ` +
|
|
66
|
+
`Click Approve in the review UI first (that records which version was approved).`);
|
|
67
|
+
}
|
|
68
|
+
const annotations = readAnnotations(projectRoot, config, workflow.id);
|
|
69
|
+
const approveAnn = latestApprove(annotations);
|
|
70
|
+
const approvedVersion = approveAnn?.version ?? workflow.currentVersion;
|
|
71
|
+
if (contentKind === 'longform') {
|
|
72
|
+
applyLongform(workflow, approvedVersion);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
applyShortform(workflow, versions, approvedVersion);
|
|
76
|
+
}
|
|
77
|
+
function applyLongform(workflow, approvedVersion) {
|
|
78
|
+
if (approvedVersion !== workflow.currentVersion) {
|
|
79
|
+
fail(`Approved v${approvedVersion}, but workflow is at v${workflow.currentVersion}. ` +
|
|
80
|
+
`Disk has moved on since the approve click — re-click Approve on v${workflow.currentVersion} or iterate back.`);
|
|
81
|
+
}
|
|
82
|
+
// The workflow already records the stable entry id; prefer it for
|
|
83
|
+
// path resolution so the UUID-bound file wins over the slug-template
|
|
84
|
+
// (Issue #67).
|
|
85
|
+
const blogFile = resolveEntryFilePath(projectRoot, config, site, slug, workflow.entryId);
|
|
86
|
+
if (!existsSync(blogFile)) {
|
|
87
|
+
fail(`Blog file missing at ${blogFile}. Nothing to approve against.`);
|
|
88
|
+
}
|
|
89
|
+
transitionState(projectRoot, config, workflow.id, 'applied');
|
|
90
|
+
emit({
|
|
91
|
+
workflowId: workflow.id,
|
|
92
|
+
site,
|
|
93
|
+
slug,
|
|
94
|
+
contentKind: 'longform',
|
|
95
|
+
state: 'applied',
|
|
96
|
+
version: approvedVersion,
|
|
97
|
+
filePath: blogFile,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function applyShortform(workflow, _versions, approvedVersion) {
|
|
101
|
+
if (!flags.platform)
|
|
102
|
+
fail('--platform is required for shortform workflows');
|
|
103
|
+
if (!isPlatform(flags.platform))
|
|
104
|
+
fail(`Invalid --platform "${flags.platform}".`);
|
|
105
|
+
// Phase 21a: shortform is now disk-backed. Read the on-disk file as
|
|
106
|
+
// the SSOT — the journal version is just the latest snapshot, but
|
|
107
|
+
// every save writes to disk first. Strip the frontmatter so the
|
|
108
|
+
// calendar's `## Shortform Copy` section captures the body only.
|
|
109
|
+
const filePath = resolveShortformFilePath(projectRoot, config, site, { slug }, flags.platform, flags.channel);
|
|
110
|
+
if (filePath === undefined || !existsSync(filePath)) {
|
|
111
|
+
const shown = filePath ?? '(unresolved)';
|
|
112
|
+
fail(`Shortform file missing at ${shown}. ` +
|
|
113
|
+
`The file is the SSOT — re-run /deskwork:shortform-start if needed.`);
|
|
114
|
+
}
|
|
115
|
+
const fileSrc = readFileSync(filePath, 'utf-8');
|
|
116
|
+
const approvedMarkdown = parseFrontmatter(fileSrc).body.replace(/^\n+/, '');
|
|
117
|
+
const calendarPath = resolveCalendarPath(projectRoot, config, site);
|
|
118
|
+
const cal = readCalendar(calendarPath);
|
|
119
|
+
const channelLower = flags.channel?.toLowerCase();
|
|
120
|
+
const match = cal.distributions.find((d) => {
|
|
121
|
+
if (d.slug !== slug)
|
|
122
|
+
return false;
|
|
123
|
+
if (d.platform !== flags.platform)
|
|
124
|
+
return false;
|
|
125
|
+
if (channelLower !== undefined) {
|
|
126
|
+
return (d.channel?.toLowerCase() ?? '') === channelLower;
|
|
127
|
+
}
|
|
128
|
+
return !d.channel;
|
|
129
|
+
});
|
|
130
|
+
if (!match) {
|
|
131
|
+
const channelBit = flags.channel ? ` · channel=${flags.channel}` : '';
|
|
132
|
+
fail(`No distribution record for (slug=${slug}, platform=${flags.platform}${channelBit}). ` +
|
|
133
|
+
`Create it with /deskwork:distribute first.`);
|
|
134
|
+
}
|
|
135
|
+
match.shortform = approvedMarkdown;
|
|
136
|
+
writeCalendar(calendarPath, cal);
|
|
137
|
+
transitionState(projectRoot, config, workflow.id, 'applied');
|
|
138
|
+
emit({
|
|
139
|
+
workflowId: workflow.id,
|
|
140
|
+
site,
|
|
141
|
+
slug,
|
|
142
|
+
contentKind: 'shortform',
|
|
143
|
+
state: 'applied',
|
|
144
|
+
version: approvedVersion,
|
|
145
|
+
platform: flags.platform,
|
|
146
|
+
channel: flags.channel,
|
|
147
|
+
calendarPath,
|
|
148
|
+
filePath,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function latestApprove(annotations) {
|
|
152
|
+
const approves = annotations.filter((a) => a.type === 'approve');
|
|
153
|
+
if (approves.length === 0)
|
|
154
|
+
return undefined;
|
|
155
|
+
return approves.reduce((a, b) => (a.createdAt > b.createdAt ? a : b));
|
|
156
|
+
}
|
|
157
|
+
function isSuccessBody(body) {
|
|
158
|
+
if (typeof body !== 'object' || body === null)
|
|
159
|
+
return false;
|
|
160
|
+
return 'workflow' in body && 'versions' in body;
|
|
161
|
+
}
|
|
162
|
+
function errorMessage(body) {
|
|
163
|
+
if (typeof body === 'object' && body !== null) {
|
|
164
|
+
const value = Reflect.get(body, 'error');
|
|
165
|
+
if (typeof value === 'string')
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
return 'unknown error';
|
|
169
|
+
}
|
|
170
|
+
function parse() {
|
|
171
|
+
try {
|
|
172
|
+
return parseArgs(argv, KNOWN_FLAGS);
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
fail(err instanceof Error ? err.message : String(err), 2);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=approve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deskwork customize — copy a plugin-default file into the project's
|
|
3
|
+
* `.deskwork/<category>/<name>.ts` so the operator can edit it.
|
|
4
|
+
*
|
|
5
|
+
* Phase 23f. Categories:
|
|
6
|
+
* - templates → copies `packages/studio/src/pages/<name>.ts`
|
|
7
|
+
* - doctor → copies `packages/core/src/doctor/rules/<name>.ts`
|
|
8
|
+
* - prompts → reserved (no default-source mapping yet)
|
|
9
|
+
*
|
|
10
|
+
* Usage (after the dispatcher injects projectRoot):
|
|
11
|
+
* deskwork customize <project-root> <category> <name>
|
|
12
|
+
*
|
|
13
|
+
* The command:
|
|
14
|
+
* 1. Resolves the plugin-default source file via `import.meta.resolve`
|
|
15
|
+
* against the published package paths so it works in both
|
|
16
|
+
* workspace dev and marketplace install.
|
|
17
|
+
* 2. Copies the source verbatim into
|
|
18
|
+
* `<projectRoot>/.deskwork/<category>/<name>.ts`, creating the
|
|
19
|
+
* directory tree as needed.
|
|
20
|
+
* 3. Refuses if the destination file already exists — clobbering an
|
|
21
|
+
* operator's edits would be a bug-factory.
|
|
22
|
+
* 4. Prints the destination path so the operator can edit.
|
|
23
|
+
*
|
|
24
|
+
* Errors:
|
|
25
|
+
* - Unknown category → exit 2 with the list of valid categories.
|
|
26
|
+
* - `prompts` for now → exit 2 with a "reserved for future use" note.
|
|
27
|
+
* - Plugin-default not found → exit 1 with the list of names that DO
|
|
28
|
+
* have defaults (best-effort).
|
|
29
|
+
* - Destination file already exists → exit 1, refuse to overwrite.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Add `@deskwork/studio/server.ts` resolution support. The studio
|
|
33
|
+
* package's `package.json` lists `bin: { "deskwork-studio": "./src/server.ts" }`
|
|
34
|
+
* but no top-level `exports.server.ts`. We work around that by
|
|
35
|
+
* resolving the package root through `package.json#main` if available;
|
|
36
|
+
* here we cheat and use the studio's own `import.meta` from the
|
|
37
|
+
* compiled bundle. To keep this implementation simple, we resolve via
|
|
38
|
+
* the studio package's `package.json` root and then join the source
|
|
39
|
+
* tree path.
|
|
40
|
+
*
|
|
41
|
+
* (This doc-comment reserves the explanation; the actual logic above
|
|
42
|
+
* uses `@deskwork/studio/server.ts`. Studio's package.json must list
|
|
43
|
+
* an exports entry for that subpath. If it doesn't yet, resolveDefaultSource
|
|
44
|
+
* will throw a clear error and the test will catch the omission.)
|
|
45
|
+
*/
|
|
46
|
+
export declare function run(argv: string[]): Promise<void>;
|
|
47
|
+
//# sourceMappingURL=customize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customize.d.ts","sourceRoot":"","sources":["../../src/commands/customize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAiHH;;;;;;;;;;;;;;GAcG;AAEH,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8DvD"}
|