@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.
Files changed (85) hide show
  1. package/dist/cli.d.ts +19 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +98 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/add.d.ts +13 -0
  6. package/dist/commands/add.d.ts.map +1 -0
  7. package/dist/commands/add.js +91 -0
  8. package/dist/commands/add.js.map +1 -0
  9. package/dist/commands/approve.d.ts +18 -0
  10. package/dist/commands/approve.d.ts.map +1 -0
  11. package/dist/commands/approve.js +179 -0
  12. package/dist/commands/approve.js.map +1 -0
  13. package/dist/commands/customize.d.ts +47 -0
  14. package/dist/commands/customize.d.ts.map +1 -0
  15. package/dist/commands/customize.js +176 -0
  16. package/dist/commands/customize.js.map +1 -0
  17. package/dist/commands/distribute.d.ts +30 -0
  18. package/dist/commands/distribute.d.ts.map +1 -0
  19. package/dist/commands/distribute.js +148 -0
  20. package/dist/commands/distribute.js.map +1 -0
  21. package/dist/commands/doctor.d.ts +35 -0
  22. package/dist/commands/doctor.d.ts.map +1 -0
  23. package/dist/commands/doctor.js +354 -0
  24. package/dist/commands/doctor.js.map +1 -0
  25. package/dist/commands/draft.d.ts +17 -0
  26. package/dist/commands/draft.d.ts.map +1 -0
  27. package/dist/commands/draft.js +77 -0
  28. package/dist/commands/draft.js.map +1 -0
  29. package/dist/commands/ingest.d.ts +43 -0
  30. package/dist/commands/ingest.d.ts.map +1 -0
  31. package/dist/commands/ingest.js +321 -0
  32. package/dist/commands/ingest.js.map +1 -0
  33. package/dist/commands/install-preflight.d.ts +83 -0
  34. package/dist/commands/install-preflight.d.ts.map +1 -0
  35. package/dist/commands/install-preflight.js +300 -0
  36. package/dist/commands/install-preflight.js.map +1 -0
  37. package/dist/commands/install.d.ts +27 -0
  38. package/dist/commands/install.d.ts.map +1 -0
  39. package/dist/commands/install.js +132 -0
  40. package/dist/commands/install.js.map +1 -0
  41. package/dist/commands/iterate.d.ts +33 -0
  42. package/dist/commands/iterate.d.ts.map +1 -0
  43. package/dist/commands/iterate.js +202 -0
  44. package/dist/commands/iterate.js.map +1 -0
  45. package/dist/commands/outline.d.ts +19 -0
  46. package/dist/commands/outline.d.ts.map +1 -0
  47. package/dist/commands/outline.js +102 -0
  48. package/dist/commands/outline.js.map +1 -0
  49. package/dist/commands/pause.d.ts +15 -0
  50. package/dist/commands/pause.d.ts.map +1 -0
  51. package/dist/commands/pause.js +70 -0
  52. package/dist/commands/pause.js.map +1 -0
  53. package/dist/commands/plan.d.ts +12 -0
  54. package/dist/commands/plan.d.ts.map +1 -0
  55. package/dist/commands/plan.js +74 -0
  56. package/dist/commands/plan.js.map +1 -0
  57. package/dist/commands/publish.d.ts +18 -0
  58. package/dist/commands/publish.d.ts.map +1 -0
  59. package/dist/commands/publish.js +105 -0
  60. package/dist/commands/publish.js.map +1 -0
  61. package/dist/commands/resume.d.ts +16 -0
  62. package/dist/commands/resume.d.ts.map +1 -0
  63. package/dist/commands/resume.js +70 -0
  64. package/dist/commands/resume.js.map +1 -0
  65. package/dist/commands/review-cancel.d.ts +15 -0
  66. package/dist/commands/review-cancel.d.ts.map +1 -0
  67. package/dist/commands/review-cancel.js +88 -0
  68. package/dist/commands/review-cancel.js.map +1 -0
  69. package/dist/commands/review-help.d.ts +12 -0
  70. package/dist/commands/review-help.d.ts.map +1 -0
  71. package/dist/commands/review-help.js +52 -0
  72. package/dist/commands/review-help.js.map +1 -0
  73. package/dist/commands/review-report.d.ts +13 -0
  74. package/dist/commands/review-report.d.ts.map +1 -0
  75. package/dist/commands/review-report.js +53 -0
  76. package/dist/commands/review-report.js.map +1 -0
  77. package/dist/commands/review-start.d.ts +17 -0
  78. package/dist/commands/review-start.d.ts.map +1 -0
  79. package/dist/commands/review-start.js +121 -0
  80. package/dist/commands/review-start.js.map +1 -0
  81. package/dist/commands/shortform-start.d.ts +33 -0
  82. package/dist/commands/shortform-start.d.ts.map +1 -0
  83. package/dist/commands/shortform-start.js +127 -0
  84. package/dist/commands/shortform-start.js.map +1 -0
  85. 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
@@ -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":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EACL,iBAAiB,GAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,eAAe,EACf,eAAe,GAChB,MAAM,gCAAgC,CAAC;AAOxC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAU,CAAC;IAC7D,MAAM,OAAO,GAAG,6CAA6C,CAAC;IAE9D,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;IAEtC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,IAAI,CACF,gEAAgE;YAC9D,kCAAkC,EACpC,CAAC,CACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,UAAU,CAAC;IACnC,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,OAAO,GAAG,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,uBAAuB,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,WAAW,GAA6B,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC;IAExF,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE;QACrD,EAAE,EAAE,IAAI;QACR,IAAI;QACJ,IAAI;QACJ,WAAW;QACX,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;KAC/B,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,IAAI,CACF,MAAM,WAAW,iBAAiB,IAAI,IAAI,IAAI,KAAK,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAChF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;IAEvC,IAAI,QAAQ,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAClC,IAAI,CACF,sBAAsB,QAAQ,CAAC,KAAK,qBAAqB;YACvD,iFAAiF,CACpF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,UAAU,EAAE,OAAO,IAAI,QAAQ,CAAC,cAAc,CAAC;IAEvE,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC/B,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IACtD,CAAC;IAED,SAAS,aAAa,CAAC,QAA2B,EAAE,eAAuB;QACzE,IAAI,eAAe,KAAK,QAAQ,CAAC,cAAc,EAAE,CAAC;YAChD,IAAI,CACF,aAAa,eAAe,yBAAyB,QAAQ,CAAC,cAAc,IAAI;gBAC9E,oEAAoE,QAAQ,CAAC,cAAc,mBAAmB,CACjH,CAAC;QACJ,CAAC;QAED,kEAAkE;QAClE,qEAAqE;QACrE,eAAe;QACf,MAAM,QAAQ,GAAG,oBAAoB,CACnC,WAAW,EACX,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,QAAQ,CAAC,OAAO,CACjB,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,wBAAwB,QAAQ,+BAA+B,CAAC,CAAC;QACxE,CAAC;QAED,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAE7D,IAAI,CAAC;YACH,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,IAAI;YACJ,IAAI;YACJ,WAAW,EAAE,UAAU;YACvB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,eAAe;YACxB,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED,SAAS,cAAc,CACrB,QAA2B,EAC3B,SAAyB,EACzB,eAAuB;QAEvB,IAAI,CAAC,KAAK,CAAC,QAAQ;YAAE,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAC5E,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,uBAAuB,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;QAEjF,oEAAoE;QACpE,kEAAkE;QAClE,gEAAgE;QAChE,iEAAiE;QACjE,MAAM,QAAQ,GAAG,wBAAwB,CACvC,WAAW,EACX,MAAM,EACN,IAAI,EACJ,EAAE,IAAI,EAAE,EACR,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,OAAO,CACd,CAAC;QACF,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,QAAQ,IAAI,cAAc,CAAC;YACzC,IAAI,CACF,6BAA6B,KAAK,IAAI;gBACpC,oEAAoE,CACvE,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAE5E,MAAM,YAAY,GAAG,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAEvC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YACzC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YAClC,IAAI,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ;gBAAE,OAAO,KAAK,CAAC;YAChD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,KAAK,YAAY,CAAC;YAC3D,CAAC;YACD,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,IAAI,CACF,oCAAoC,IAAI,cAAc,KAAK,CAAC,QAAQ,GAAG,UAAU,KAAK;gBACpF,4CAA4C,CAC/C,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;QACnC,aAAa,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjC,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAE7D,IAAI,CAAC;YACH,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,IAAI;YACJ,IAAI;YACJ,WAAW,EAAE,WAAW;YACxB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,eAAe;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,YAAY;YACZ,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAED,SAAS,aAAa,CACpB,WAAuC;QAEvC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CACjC,CAAC,CAAC,EAA0B,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CACpD,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,SAAS,aAAa,CACpB,IAAa;QAEb,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5D,OAAO,UAAU,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,CAAC;IAClD,CAAC;IAED,SAAS,YAAY,CAAC,IAAa;QACjC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC;QAC9C,CAAC;QACD,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,SAAS,KAAK;QACZ,IAAI,CAAC;YACH,OAAO,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -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"}