autocrew 0.1.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/HAMLETDEER.md +562 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/README_CN.md +190 -0
- package/adapters/openclaw/index.ts +68 -0
- package/bin/autocrew.mjs +23 -0
- package/bin/autocrew.ts +13 -0
- package/openclaw.plugin.json +36 -0
- package/package.json +74 -0
- package/skills/_writing-style/SKILL.md +68 -0
- package/skills/audience-profiler/SKILL.md +241 -0
- package/skills/content-attribution/SKILL.md +128 -0
- package/skills/content-review/SKILL.md +257 -0
- package/skills/cover-generator/SKILL.md +93 -0
- package/skills/humanizer-zh/SKILL.md +75 -0
- package/skills/intel-digest/SKILL.md +57 -0
- package/skills/intel-pull/SKILL.md +74 -0
- package/skills/manage-pipeline/SKILL.md +63 -0
- package/skills/memory-distill/SKILL.md +89 -0
- package/skills/onboarding/SKILL.md +117 -0
- package/skills/pipeline-status/SKILL.md +51 -0
- package/skills/platform-rewrite/SKILL.md +125 -0
- package/skills/pre-publish/SKILL.md +142 -0
- package/skills/publish-content/SKILL.md +500 -0
- package/skills/remix-content/SKILL.md +77 -0
- package/skills/research/SKILL.md +127 -0
- package/skills/setup/SKILL.md +353 -0
- package/skills/spawn-batch-writer/SKILL.md +66 -0
- package/skills/spawn-planner/SKILL.md +72 -0
- package/skills/spawn-writer/SKILL.md +60 -0
- package/skills/teardown/SKILL.md +144 -0
- package/skills/title-craft/SKILL.md +234 -0
- package/skills/topic-ideas/SKILL.md +105 -0
- package/skills/video-timeline/SKILL.md +117 -0
- package/skills/write-script/SKILL.md +232 -0
- package/skills/xhs-cover-review/SKILL.md +48 -0
- package/src/adapters/browser/browser-cdp.ts +260 -0
- package/src/adapters/browser/browser-relay.ts +236 -0
- package/src/adapters/browser/gateway-client.ts +148 -0
- package/src/adapters/browser/types.ts +36 -0
- package/src/adapters/image/gemini.ts +219 -0
- package/src/adapters/research/tikhub.ts +19 -0
- package/src/cli/banner.ts +18 -0
- package/src/cli/bootstrap.ts +33 -0
- package/src/cli/commands/adapt.ts +28 -0
- package/src/cli/commands/advance.ts +28 -0
- package/src/cli/commands/assets.ts +24 -0
- package/src/cli/commands/audit.ts +18 -0
- package/src/cli/commands/contents.ts +18 -0
- package/src/cli/commands/cover.ts +58 -0
- package/src/cli/commands/events.ts +17 -0
- package/src/cli/commands/humanize.ts +27 -0
- package/src/cli/commands/index.ts +80 -0
- package/src/cli/commands/init.ts +28 -0
- package/src/cli/commands/intel.ts +55 -0
- package/src/cli/commands/learn.ts +34 -0
- package/src/cli/commands/memory.ts +18 -0
- package/src/cli/commands/migrate.ts +24 -0
- package/src/cli/commands/open.ts +21 -0
- package/src/cli/commands/pipelines.ts +18 -0
- package/src/cli/commands/pre-publish.ts +27 -0
- package/src/cli/commands/profile.ts +31 -0
- package/src/cli/commands/research.ts +36 -0
- package/src/cli/commands/restore.ts +28 -0
- package/src/cli/commands/review.ts +61 -0
- package/src/cli/commands/start.ts +28 -0
- package/src/cli/commands/status.ts +14 -0
- package/src/cli/commands/templates.ts +15 -0
- package/src/cli/commands/topics.ts +18 -0
- package/src/cli/commands/trash.ts +28 -0
- package/src/cli/commands/upgrade.ts +48 -0
- package/src/cli/commands/versions.ts +24 -0
- package/src/cli/index.ts +40 -0
- package/src/data/sensitive-words-builtin.json +114 -0
- package/src/data/source-presets.yaml +54 -0
- package/src/e2e.test.ts +596 -0
- package/src/modules/auth/cookie-manager.ts +113 -0
- package/src/modules/cards/template-engine.ts +74 -0
- package/src/modules/cards/templates/comparison-table.ts +71 -0
- package/src/modules/cards/templates/data-chart.ts +76 -0
- package/src/modules/cards/templates/flow-chart.ts +49 -0
- package/src/modules/cards/templates/key-points.ts +59 -0
- package/src/modules/cover/prompt-builder.test.ts +157 -0
- package/src/modules/cover/prompt-builder.ts +212 -0
- package/src/modules/cover/ratio-adapter.test.ts +122 -0
- package/src/modules/cover/ratio-adapter.ts +104 -0
- package/src/modules/filter/sensitive-words.test.ts +72 -0
- package/src/modules/filter/sensitive-words.ts +212 -0
- package/src/modules/humanizer/zh.test.ts +75 -0
- package/src/modules/humanizer/zh.ts +175 -0
- package/src/modules/intel/collector.ts +19 -0
- package/src/modules/intel/collectors/competitor.test.ts +71 -0
- package/src/modules/intel/collectors/competitor.ts +65 -0
- package/src/modules/intel/collectors/rss.test.ts +56 -0
- package/src/modules/intel/collectors/rss.ts +70 -0
- package/src/modules/intel/collectors/trends.test.ts +80 -0
- package/src/modules/intel/collectors/trends.ts +107 -0
- package/src/modules/intel/collectors/web-search.test.ts +85 -0
- package/src/modules/intel/collectors/web-search.ts +81 -0
- package/src/modules/intel/integration.test.ts +203 -0
- package/src/modules/intel/intel-engine.test.ts +103 -0
- package/src/modules/intel/intel-engine.ts +96 -0
- package/src/modules/intel/source-config.test.ts +113 -0
- package/src/modules/intel/source-config.ts +131 -0
- package/src/modules/learnings/diff-tracker.test.ts +144 -0
- package/src/modules/learnings/diff-tracker.ts +189 -0
- package/src/modules/learnings/rule-distiller.ts +141 -0
- package/src/modules/memory/distill.ts +208 -0
- package/src/modules/migrate/legacy-migrate.test.ts +169 -0
- package/src/modules/migrate/legacy-migrate.ts +229 -0
- package/src/modules/pro/api-client.ts +192 -0
- package/src/modules/pro/gate.test.ts +110 -0
- package/src/modules/pro/gate.ts +104 -0
- package/src/modules/profile/creator-profile.test.ts +178 -0
- package/src/modules/profile/creator-profile.ts +248 -0
- package/src/modules/publish/douyin-api.ts +34 -0
- package/src/modules/publish/wechat-mp.ts +320 -0
- package/src/modules/publish/xiaohongshu-api.ts +127 -0
- package/src/modules/research/free-engine.ts +360 -0
- package/src/modules/timeline/markup-generator.ts +63 -0
- package/src/modules/timeline/parser.ts +275 -0
- package/src/modules/workflow/templates.ts +124 -0
- package/src/modules/writing/platform-rewrite.ts +190 -0
- package/src/modules/writing/title-hashtag.ts +385 -0
- package/src/runtime/context.test.ts +97 -0
- package/src/runtime/context.ts +129 -0
- package/src/runtime/events.test.ts +83 -0
- package/src/runtime/events.ts +104 -0
- package/src/runtime/hooks.ts +174 -0
- package/src/runtime/tool-runner.test.ts +204 -0
- package/src/runtime/tool-runner.ts +282 -0
- package/src/runtime/workflow-engine.test.ts +455 -0
- package/src/runtime/workflow-engine.ts +391 -0
- package/src/server/index.ts +409 -0
- package/src/server/start.ts +39 -0
- package/src/storage/local-store.test.ts +304 -0
- package/src/storage/local-store.ts +704 -0
- package/src/storage/pipeline-store.test.ts +363 -0
- package/src/storage/pipeline-store.ts +698 -0
- package/src/tools/asset.ts +96 -0
- package/src/tools/content-save.ts +276 -0
- package/src/tools/cover-review.ts +221 -0
- package/src/tools/humanize.ts +54 -0
- package/src/tools/init.ts +133 -0
- package/src/tools/intel.ts +92 -0
- package/src/tools/memory.ts +76 -0
- package/src/tools/pipeline-ops.ts +109 -0
- package/src/tools/pipeline.ts +168 -0
- package/src/tools/pre-publish.ts +232 -0
- package/src/tools/publish.ts +183 -0
- package/src/tools/registry.ts +198 -0
- package/src/tools/research.ts +304 -0
- package/src/tools/review.ts +305 -0
- package/src/tools/rewrite.ts +165 -0
- package/src/tools/status.ts +30 -0
- package/src/tools/timeline.ts +234 -0
- package/src/tools/topic-create.ts +50 -0
- package/src/types/providers.ts +69 -0
- package/src/types/timeline.test.ts +147 -0
- package/src/types/timeline.ts +83 -0
- package/src/utils/retry.test.ts +97 -0
- package/src/utils/retry.ts +85 -0
- package/templates/AGENTS.md +99 -0
- package/templates/SOUL.md +31 -0
- package/templates/TOOLS.md +76 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared runtime initialization for all entry points (CLI, MCP, HTTP server, OpenClaw adapter).
|
|
3
|
+
* Single source of truth — eliminates duplicated bootstrap code.
|
|
4
|
+
*/
|
|
5
|
+
import { createContext, type PluginConfig } from "../runtime/context.js";
|
|
6
|
+
import { ToolRunner } from "../runtime/tool-runner.js";
|
|
7
|
+
import { EventBus } from "../runtime/events.js";
|
|
8
|
+
import { HookManager } from "../runtime/hooks.js";
|
|
9
|
+
import { WorkflowEngine } from "../runtime/workflow-engine.js";
|
|
10
|
+
import { registerAllTools } from "../tools/registry.js";
|
|
11
|
+
|
|
12
|
+
export interface BootstrapResult {
|
|
13
|
+
ctx: ReturnType<typeof createContext>;
|
|
14
|
+
eventBus: EventBus;
|
|
15
|
+
runner: ToolRunner;
|
|
16
|
+
hookManager: HookManager;
|
|
17
|
+
workflowEngine: WorkflowEngine;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function bootstrap(config?: PluginConfig): BootstrapResult {
|
|
21
|
+
const ctx = createContext(config);
|
|
22
|
+
const eventBus = new EventBus();
|
|
23
|
+
const runner = new ToolRunner({ ctx, eventBus });
|
|
24
|
+
|
|
25
|
+
registerAllTools(runner);
|
|
26
|
+
|
|
27
|
+
const hookManager = new HookManager();
|
|
28
|
+
hookManager.init(eventBus, runner, ctx.dataDir).catch(() => {});
|
|
29
|
+
|
|
30
|
+
const workflowEngine = new WorkflowEngine(runner, ctx.dataDir);
|
|
31
|
+
|
|
32
|
+
return { ctx, eventBus, runner, hookManager, workflowEngine };
|
|
33
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "adapt",
|
|
5
|
+
description: "Create a platform-native rewrite",
|
|
6
|
+
usage: "autocrew adapt <content-id> <platform>",
|
|
7
|
+
action: async (args, runner) => {
|
|
8
|
+
const contentId = args[0];
|
|
9
|
+
const platform = args[1];
|
|
10
|
+
if (!contentId || !platform) {
|
|
11
|
+
console.error("Usage: autocrew adapt <content-id> <platform>");
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const result = await runner.execute("autocrew_rewrite", {
|
|
16
|
+
action: "adapt_platform",
|
|
17
|
+
content_id: contentId,
|
|
18
|
+
target_platform: platform,
|
|
19
|
+
});
|
|
20
|
+
if (!result.ok) {
|
|
21
|
+
console.error(`Adapt failed: ${result.error || "unknown error"}`);
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log(`Platform rewrite complete → ${platform}`);
|
|
26
|
+
console.log(` New content: ${result.newContentId || result.id || "(saved)"}`);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "advance",
|
|
5
|
+
description: "Advance a project to the next pipeline stage",
|
|
6
|
+
usage: "autocrew advance <project>",
|
|
7
|
+
action: async (args, runner) => {
|
|
8
|
+
const project = args[0];
|
|
9
|
+
if (!project) {
|
|
10
|
+
console.error("Usage: autocrew advance <project>");
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const result = await runner.execute("autocrew_pipeline_ops", {
|
|
16
|
+
action: "advance",
|
|
17
|
+
project,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (!result.ok) {
|
|
21
|
+
console.error(`Advance failed: ${result.error || "unknown error"}`);
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`Project advanced to: ${result.newDir}`);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "assets",
|
|
5
|
+
description: "List assets for a content project",
|
|
6
|
+
usage: "autocrew assets <content-id>",
|
|
7
|
+
action: async (args, runner) => {
|
|
8
|
+
const contentId = args[0];
|
|
9
|
+
if (!contentId) {
|
|
10
|
+
console.error("Usage: autocrew assets <content-id>");
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const result = await runner.execute("autocrew_asset", { action: "list", content_id: contentId });
|
|
15
|
+
const assets = (result.assets || []) as any[];
|
|
16
|
+
if (assets.length === 0) {
|
|
17
|
+
console.log(`No assets for ${contentId}.`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (const a of assets) {
|
|
21
|
+
console.log(` [${a.type}] ${a.filename} (${a.role || "general"})`);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "audit",
|
|
5
|
+
description: "Show recent tool execution audit log",
|
|
6
|
+
usage: "autocrew audit",
|
|
7
|
+
action: async (_args, _runner, ctx) => {
|
|
8
|
+
if (ctx.audit.length === 0) {
|
|
9
|
+
console.log("No audit entries yet.");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
for (const entry of ctx.audit.slice(-20)) {
|
|
13
|
+
const status = entry.ok ? "\u2713" : "\u2717";
|
|
14
|
+
console.log(` ${status} ${entry.tool}${entry.action ? `:${entry.action}` : ""} — ${entry.durationMs}ms (${entry.timestamp})`);
|
|
15
|
+
if (entry.error) console.log(` Error: ${entry.error}`);
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "contents",
|
|
5
|
+
description: "List content items",
|
|
6
|
+
usage: "autocrew contents",
|
|
7
|
+
action: async (_args, runner) => {
|
|
8
|
+
const result = await runner.execute("autocrew_content", { action: "list" });
|
|
9
|
+
const items = (result.items || []) as any[];
|
|
10
|
+
if (items.length === 0) {
|
|
11
|
+
console.log("No content yet. Use 'autocrew_content' tool to save drafts.");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
for (const c of items) {
|
|
15
|
+
console.log(`[${c.id}] ${c.title} — ${c.status} (${c.platform || "general"})`);
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "cover",
|
|
5
|
+
description: "Cover operations: review candidates or approve a variant",
|
|
6
|
+
usage: "autocrew cover <content-id> [--approve <label>]",
|
|
7
|
+
action: async (args, runner) => {
|
|
8
|
+
const contentId = args[0];
|
|
9
|
+
if (!contentId) {
|
|
10
|
+
console.error("Usage: autocrew cover <content-id> [--approve <label>]");
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Check for --approve flag → approve-cover flow
|
|
16
|
+
const approveIdx = args.indexOf("--approve");
|
|
17
|
+
if (approveIdx !== -1) {
|
|
18
|
+
const label = args[approveIdx + 1];
|
|
19
|
+
if (!label) {
|
|
20
|
+
console.error("Usage: autocrew cover <content-id> --approve <label>");
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const result = await runner.execute("autocrew_cover_review", {
|
|
25
|
+
action: "approve",
|
|
26
|
+
content_id: contentId,
|
|
27
|
+
label,
|
|
28
|
+
});
|
|
29
|
+
if (!result.ok) {
|
|
30
|
+
console.error(`Approve failed: ${result.error || "unknown error"}`);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
console.log(`Cover ${label.toUpperCase()} approved for ${contentId}.`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Default: cover-review flow
|
|
39
|
+
const result = await runner.execute("autocrew_cover_review", {
|
|
40
|
+
action: "create_candidates",
|
|
41
|
+
content_id: contentId,
|
|
42
|
+
});
|
|
43
|
+
if (!result.ok) {
|
|
44
|
+
console.error(`Cover generation failed: ${result.error || "unknown error"}`);
|
|
45
|
+
if (result.hint) console.log(`Hint: ${result.hint}`);
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log(`Generated ${result.generated || 0} cover candidates.`);
|
|
50
|
+
const review = result.review as any;
|
|
51
|
+
if (review?.variants) {
|
|
52
|
+
for (const v of review.variants) {
|
|
53
|
+
console.log(` [${v.label.toUpperCase()}] ${v.style} — ${v.titleText || ""}`);
|
|
54
|
+
if (v.imagePaths?.["3:4"]) console.log(` → ${v.imagePaths["3:4"]}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "events",
|
|
5
|
+
description: "Show recent event history",
|
|
6
|
+
usage: "autocrew events",
|
|
7
|
+
action: async (_args, _runner, _ctx, eventBus) => {
|
|
8
|
+
const history = eventBus.getHistory(20);
|
|
9
|
+
if (history.length === 0) {
|
|
10
|
+
console.log("No events yet.");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
for (const e of history) {
|
|
14
|
+
console.log(` ${e.type} — ${JSON.stringify(e.data)} (${e.timestamp})`);
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "humanize",
|
|
5
|
+
description: "Run Chinese de-AI pass on a content draft",
|
|
6
|
+
usage: "autocrew humanize <content-id>",
|
|
7
|
+
action: async (args, runner) => {
|
|
8
|
+
const contentId = args[0];
|
|
9
|
+
if (!contentId) {
|
|
10
|
+
console.error("Usage: autocrew humanize <content-id>");
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const result = await runner.execute("autocrew_humanize", { content_id: contentId });
|
|
15
|
+
if (!result.ok) {
|
|
16
|
+
console.error(`Humanize failed: ${result.error || "unknown error"}`);
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.log(`De-AI pass complete. Changes: ${result.changeCount || 0}`);
|
|
21
|
+
if ((result.changes as any[])?.length > 0) {
|
|
22
|
+
for (const c of result.changes as string[]) {
|
|
23
|
+
console.log(` • ${c}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command registry — exports all CLI commands and shared helpers.
|
|
3
|
+
*/
|
|
4
|
+
import type { ToolRunner } from "../../runtime/tool-runner.js";
|
|
5
|
+
import type { ToolContext } from "../../runtime/context.js";
|
|
6
|
+
import type { EventBus } from "../../runtime/events.js";
|
|
7
|
+
|
|
8
|
+
export interface CommandDef {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
usage?: string;
|
|
12
|
+
action: (args: string[], runner: ToolRunner, ctx: ToolContext, eventBus: EventBus) => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Parse a CLI flag value from args array.
|
|
17
|
+
* e.g. getOption(["--keyword", "AI"], "--keyword") → "AI"
|
|
18
|
+
*/
|
|
19
|
+
export function getOption(args: string[], flag: string): string | undefined {
|
|
20
|
+
const idx = args.indexOf(flag);
|
|
21
|
+
return idx !== -1 && args[idx + 1] ? args[idx + 1] : undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
import { cmd as statusCmd } from "./status.js";
|
|
25
|
+
import { cmd as topicsCmd } from "./topics.js";
|
|
26
|
+
import { cmd as contentsCmd } from "./contents.js";
|
|
27
|
+
import { cmd as researchCmd } from "./research.js";
|
|
28
|
+
import { cmd as assetsCmd } from "./assets.js";
|
|
29
|
+
import { cmd as versionsCmd } from "./versions.js";
|
|
30
|
+
import { cmd as openCmd } from "./open.js";
|
|
31
|
+
import { cmd as pipelinesCmd } from "./pipelines.js";
|
|
32
|
+
import { cmd as templatesCmd } from "./templates.js";
|
|
33
|
+
import { cmd as humanizeCmd } from "./humanize.js";
|
|
34
|
+
import { cmd as adaptCmd } from "./adapt.js";
|
|
35
|
+
import { cmd as coverCmd } from "./cover.js";
|
|
36
|
+
import { cmd as reviewCmd } from "./review.js";
|
|
37
|
+
import { cmd as prePublishCmd } from "./pre-publish.js";
|
|
38
|
+
import { cmd as learnCmd } from "./learn.js";
|
|
39
|
+
import { cmd as memoryCmd } from "./memory.js";
|
|
40
|
+
import { cmd as initCmd } from "./init.js";
|
|
41
|
+
import { cmd as upgradeCmd } from "./upgrade.js";
|
|
42
|
+
import { cmd as profileCmd } from "./profile.js";
|
|
43
|
+
import { cmd as auditCmd } from "./audit.js";
|
|
44
|
+
import { cmd as eventsCmd } from "./events.js";
|
|
45
|
+
import { cmd as intelCmd } from "./intel.js";
|
|
46
|
+
import { cmd as startCmd } from "./start.js";
|
|
47
|
+
import { cmd as advanceCmd } from "./advance.js";
|
|
48
|
+
import { cmd as trashCmd } from "./trash.js";
|
|
49
|
+
import { cmd as restoreCmd } from "./restore.js";
|
|
50
|
+
import { cmd as migrateCmd } from "./migrate.js";
|
|
51
|
+
|
|
52
|
+
export const commands: CommandDef[] = [
|
|
53
|
+
statusCmd,
|
|
54
|
+
topicsCmd,
|
|
55
|
+
contentsCmd,
|
|
56
|
+
researchCmd,
|
|
57
|
+
assetsCmd,
|
|
58
|
+
versionsCmd,
|
|
59
|
+
openCmd,
|
|
60
|
+
pipelinesCmd,
|
|
61
|
+
templatesCmd,
|
|
62
|
+
humanizeCmd,
|
|
63
|
+
adaptCmd,
|
|
64
|
+
coverCmd,
|
|
65
|
+
reviewCmd,
|
|
66
|
+
prePublishCmd,
|
|
67
|
+
learnCmd,
|
|
68
|
+
memoryCmd,
|
|
69
|
+
initCmd,
|
|
70
|
+
upgradeCmd,
|
|
71
|
+
profileCmd,
|
|
72
|
+
auditCmd,
|
|
73
|
+
eventsCmd,
|
|
74
|
+
intelCmd,
|
|
75
|
+
startCmd,
|
|
76
|
+
advanceCmd,
|
|
77
|
+
trashCmd,
|
|
78
|
+
restoreCmd,
|
|
79
|
+
migrateCmd,
|
|
80
|
+
];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
import { loadProfile, detectMissingInfo } from "../../modules/profile/creator-profile.js";
|
|
3
|
+
|
|
4
|
+
export const cmd: CommandDef = {
|
|
5
|
+
name: "init",
|
|
6
|
+
description: "Initialize ~/.autocrew/ data directory and creator profile",
|
|
7
|
+
usage: "autocrew init",
|
|
8
|
+
action: async (_args, runner, ctx) => {
|
|
9
|
+
const result = await runner.execute("autocrew_init", {});
|
|
10
|
+
if (result.alreadyExisted) {
|
|
11
|
+
console.log(`AutoCrew already initialized at ${result.dataDir}`);
|
|
12
|
+
} else {
|
|
13
|
+
console.log(`AutoCrew initialized at ${result.dataDir}`);
|
|
14
|
+
}
|
|
15
|
+
console.log(` Created: ${(result.created as any[])?.length ?? 0} items`);
|
|
16
|
+
|
|
17
|
+
const profile = await loadProfile(ctx.dataDir);
|
|
18
|
+
if (profile) {
|
|
19
|
+
const missing = detectMissingInfo(profile);
|
|
20
|
+
if (missing.length > 0) {
|
|
21
|
+
console.log(`\n Profile incomplete — missing: ${missing.join(", ")}`);
|
|
22
|
+
console.log(` Start a conversation with your agent to complete onboarding.`);
|
|
23
|
+
} else {
|
|
24
|
+
console.log(`\n Profile complete. Ready to go!`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
import { getOption } from "./index.js";
|
|
3
|
+
|
|
4
|
+
export const cmd: CommandDef = {
|
|
5
|
+
name: "intel",
|
|
6
|
+
description: "Manage inspiration sources — pull signals, list saved items, clean expired",
|
|
7
|
+
usage: "autocrew intel pull [--source X] | autocrew intel list [--domain X] | autocrew intel clean",
|
|
8
|
+
action: async (args, runner) => {
|
|
9
|
+
const subcommand = args[0];
|
|
10
|
+
if (!subcommand || !["pull", "list", "clean"].includes(subcommand)) {
|
|
11
|
+
console.error("Usage: autocrew intel <pull|list|clean>");
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const result = await runner.execute("autocrew_intel", {
|
|
17
|
+
action: subcommand,
|
|
18
|
+
source: getOption(args, "--source"),
|
|
19
|
+
domain: getOption(args, "--domain"),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!result.ok) {
|
|
23
|
+
console.error(`Intel ${subcommand} failed: ${result.error || "unknown error"}`);
|
|
24
|
+
process.exitCode = 1;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
switch (subcommand) {
|
|
29
|
+
case "pull":
|
|
30
|
+
console.log(`Intel pull complete. Collected: ${result.totalCollected}, Saved: ${result.totalSaved}`);
|
|
31
|
+
if (result.bySource) {
|
|
32
|
+
for (const [src, count] of Object.entries(result.bySource as Record<string, number>)) {
|
|
33
|
+
console.log(` ${src}: ${count}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (result.errors) {
|
|
37
|
+
console.log(` Errors: ${(result.errors as string[]).length}`);
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
|
|
41
|
+
case "list": {
|
|
42
|
+
console.log(`Intel items: ${result.total} total, showing ${result.showing}`);
|
|
43
|
+
const items = (result.items || []) as any[];
|
|
44
|
+
for (const item of items) {
|
|
45
|
+
console.log(` [${item.source}] ${item.title} — relevance: ${item.relevance ?? "?"}`);
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
case "clean":
|
|
51
|
+
console.log(`Intel clean complete. Archived: ${result.archived}`);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
import { getOption } from "./index.js";
|
|
3
|
+
|
|
4
|
+
export const cmd: CommandDef = {
|
|
5
|
+
name: "learn",
|
|
6
|
+
description: "Capture a feedback signal into AutoCrew memory",
|
|
7
|
+
usage: "autocrew learn <content-id> --signal <signal> [--feedback <feedback>] [--modified-text <text>]",
|
|
8
|
+
action: async (args, runner) => {
|
|
9
|
+
const contentId = args[0];
|
|
10
|
+
const signal = getOption(args, "--signal");
|
|
11
|
+
if (!contentId || !signal) {
|
|
12
|
+
console.error("Usage: autocrew learn <content-id> --signal <signal> [--feedback <feedback>]");
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const result = await runner.execute("autocrew_memory", {
|
|
18
|
+
action: "capture_feedback",
|
|
19
|
+
content_id: contentId,
|
|
20
|
+
signal_type: signal,
|
|
21
|
+
feedback: getOption(args, "--feedback"),
|
|
22
|
+
modified_text: getOption(args, "--modified-text"),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (!result.ok) {
|
|
26
|
+
console.error(`Memory capture failed: ${result.error || "unknown error"}`);
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`Saved learning to ${result.section}.`);
|
|
32
|
+
console.log(` ${result.learning}`);
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "memory",
|
|
5
|
+
description: "Show current AutoCrew MEMORY.md",
|
|
6
|
+
usage: "autocrew memory",
|
|
7
|
+
action: async (_args, runner) => {
|
|
8
|
+
const result = await runner.execute("autocrew_memory", { action: "get_memory" });
|
|
9
|
+
|
|
10
|
+
if (!result.ok) {
|
|
11
|
+
console.error(`Read memory failed: ${result.error || "unknown error"}`);
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
console.log(result.content);
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
import { migrateLegacyData } from "../../modules/migrate/legacy-migrate.js";
|
|
3
|
+
|
|
4
|
+
export const cmd: CommandDef = {
|
|
5
|
+
name: "migrate",
|
|
6
|
+
description: "Migrate legacy data to the new pipeline format",
|
|
7
|
+
usage: "autocrew migrate",
|
|
8
|
+
action: async (_args, _runner, ctx) => {
|
|
9
|
+
console.log("Migrating legacy data...");
|
|
10
|
+
const result = await migrateLegacyData(ctx.dataDir);
|
|
11
|
+
|
|
12
|
+
console.log(` Topics migrated: ${result.topicsMigrated}`);
|
|
13
|
+
console.log(` Contents migrated: ${result.contentsMigrated}`);
|
|
14
|
+
|
|
15
|
+
if (result.errors.length > 0) {
|
|
16
|
+
console.log(`\n Errors (${result.errors.length}):`);
|
|
17
|
+
for (const err of result.errors) {
|
|
18
|
+
console.log(` - ${err}`);
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
console.log("\n Migration complete — no errors.");
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "open",
|
|
5
|
+
description: "Show the file path of a content project directory",
|
|
6
|
+
usage: "autocrew open <content-id>",
|
|
7
|
+
action: async (args, _runner, ctx) => {
|
|
8
|
+
const contentId = args[0];
|
|
9
|
+
if (!contentId) {
|
|
10
|
+
console.error("Usage: autocrew open <content-id>");
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const projPath = `${ctx.dataDir}/contents/${contentId}`;
|
|
15
|
+
console.log(`Content project: ${projPath}`);
|
|
16
|
+
console.log(` draft.md — current readable draft`);
|
|
17
|
+
console.log(` meta.json — metadata + asset index`);
|
|
18
|
+
console.log(` assets/ — media files (covers, B-Roll, etc.)`);
|
|
19
|
+
console.log(` versions/ — version history (v1.md, v2.md, ...)`);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "pipelines",
|
|
5
|
+
description: "List configured pipelines",
|
|
6
|
+
usage: "autocrew pipelines",
|
|
7
|
+
action: async (_args, runner) => {
|
|
8
|
+
const result = await runner.execute("autocrew_pipeline", { action: "list" });
|
|
9
|
+
const pipelines = (result.pipelines || []) as any[];
|
|
10
|
+
if (pipelines.length === 0) {
|
|
11
|
+
console.log("No pipelines configured. Use 'autocrew_pipeline' tool to create one.");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
for (const p of pipelines) {
|
|
15
|
+
console.log(` [${p.id}] ${p.name} — ${p.enabled ? "enabled" : "disabled"} (${p.schedule || "manual"})`);
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "pre-publish",
|
|
5
|
+
description: "Run pre-publish checklist: 6 checks before allowing publish",
|
|
6
|
+
usage: "autocrew pre-publish <content-id>",
|
|
7
|
+
action: async (args, runner) => {
|
|
8
|
+
const contentId = args[0];
|
|
9
|
+
if (!contentId) {
|
|
10
|
+
console.error("Usage: autocrew pre-publish <content-id>");
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const result = await runner.execute("autocrew_pre_publish", {
|
|
15
|
+
action: "check",
|
|
16
|
+
content_id: contentId,
|
|
17
|
+
}) as any;
|
|
18
|
+
|
|
19
|
+
if (!result.ok) {
|
|
20
|
+
console.error(`Pre-publish check failed: ${result.error || "unknown error"}`);
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log(result.summary);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
import { loadProfile, detectMissingInfo } from "../../modules/profile/creator-profile.js";
|
|
3
|
+
|
|
4
|
+
export const cmd: CommandDef = {
|
|
5
|
+
name: "profile",
|
|
6
|
+
description: "Show creator profile",
|
|
7
|
+
usage: "autocrew profile",
|
|
8
|
+
action: async (_args, _runner, ctx) => {
|
|
9
|
+
const profile = await loadProfile(ctx.dataDir);
|
|
10
|
+
if (!profile) {
|
|
11
|
+
console.log("No creator profile yet. Run 'autocrew init' first.");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
console.log(`Industry: ${profile.industry || "(not set)"}`);
|
|
15
|
+
console.log(`Platforms: ${profile.platforms.length > 0 ? profile.platforms.join(", ") : "(not set)"}`);
|
|
16
|
+
console.log(`Style calibrated: ${profile.styleCalibrated ? "yes" : "no"}`);
|
|
17
|
+
if (profile.audiencePersona) {
|
|
18
|
+
console.log(`Audience: ${profile.audiencePersona.name} (${profile.audiencePersona.age || "?"}, ${profile.audiencePersona.job || "?"})`);
|
|
19
|
+
} else {
|
|
20
|
+
console.log(`Audience: (not set)`);
|
|
21
|
+
}
|
|
22
|
+
console.log(`Writing rules: ${profile.writingRules.length}`);
|
|
23
|
+
console.log(`Competitors: ${profile.competitorAccounts.length}`);
|
|
24
|
+
console.log(`Performance entries: ${profile.performanceHistory.length}`);
|
|
25
|
+
|
|
26
|
+
const missing = detectMissingInfo(profile);
|
|
27
|
+
if (missing.length > 0) {
|
|
28
|
+
console.log(`\nMissing: ${missing.join(", ")}`);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
import { getOption } from "./index.js";
|
|
3
|
+
|
|
4
|
+
export const cmd: CommandDef = {
|
|
5
|
+
name: "research",
|
|
6
|
+
description: "Discover browser-first topic candidates and save them into AutoCrew",
|
|
7
|
+
usage: "autocrew research --keyword <keyword> [--industry <industry>] [--platform <platform>] [--count <count>]",
|
|
8
|
+
action: async (args, runner) => {
|
|
9
|
+
const keyword = getOption(args, "--keyword");
|
|
10
|
+
if (!keyword) {
|
|
11
|
+
console.error("Missing required option: --keyword <keyword>");
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const result = await runner.execute("autocrew_research", {
|
|
17
|
+
action: "discover",
|
|
18
|
+
keyword,
|
|
19
|
+
industry: getOption(args, "--industry"),
|
|
20
|
+
platform: getOption(args, "--platform") || "xiaohongshu",
|
|
21
|
+
topic_count: Number(getOption(args, "--count") || 3),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (!result.ok) {
|
|
25
|
+
console.error(`Research failed: ${result.error || "unknown error"}`);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(`Research complete. Mode: ${result.mode}`);
|
|
31
|
+
const topics = (result.topics || []) as any[];
|
|
32
|
+
for (const t of topics) {
|
|
33
|
+
console.log(` [${t.id}] ${t.title} — score: ${t.viralScore ?? "?"}`);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CommandDef } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export const cmd: CommandDef = {
|
|
4
|
+
name: "restore",
|
|
5
|
+
description: "Restore a project from the trash stage",
|
|
6
|
+
usage: "autocrew restore <project>",
|
|
7
|
+
action: async (args, runner) => {
|
|
8
|
+
const project = args[0];
|
|
9
|
+
if (!project) {
|
|
10
|
+
console.error("Usage: autocrew restore <project>");
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const result = await runner.execute("autocrew_pipeline_ops", {
|
|
16
|
+
action: "restore",
|
|
17
|
+
project,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (!result.ok) {
|
|
21
|
+
console.error(`Restore failed: ${result.error || "unknown error"}`);
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`Project restored to: ${result.restoredTo}`);
|
|
27
|
+
},
|
|
28
|
+
};
|