takomi 2.1.39 → 2.1.41
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/.agents/plugins/marketplace.json +22 -22
- package/README.md +217 -422
- package/assets/.agent/skills/remotion/rules/assets/charts-bar-chart.tsx +173 -173
- package/assets/.agent/skills/remotion/rules/assets/text-animations-typewriter.tsx +100 -100
- package/assets/.agent/skills/remotion/rules/text-animations.md +20 -20
- package/assets/.agent/skills/remotion/rules/videos.md +171 -171
- package/assets/.agent/skills/remotion-real-ui-video/SKILL.md +264 -0
- package/assets/.agent/skills/remotion-real-ui-video/references/anti-patterns.md +114 -0
- package/assets/.agent/skills/remotion-real-ui-video/references/completion-checklist.md +75 -0
- package/assets/.agent/skills/remotion-real-ui-video/references/real-ui-bridge-example.md +93 -0
- package/assets/.agent/skills/takomi-flow/SKILL.md +244 -235
- package/docs/features/TakomiFlow_Portable_Plugin.md +82 -78
- package/docs/takomi-flow-onboarding.md +86 -76
- package/docs/takomi-flow-public-distribution.md +94 -94
- package/package.json +1 -1
- package/plugins/takomi-flow/.mcp.json +11 -11
- package/plugins/takomi-flow/assets/capabilities.json +203 -171
- package/plugins/takomi-flow/assets/collection.schema.json +29 -29
- package/plugins/takomi-flow/assets/examples.json +94 -94
- package/plugins/takomi-flow/assets/request.schema.json +91 -67
- package/plugins/takomi-flow/assets/result.schema.json +46 -45
- package/plugins/takomi-flow/assets/templates/image-request.json +17 -13
- package/plugins/takomi-flow/assets/templates/video-request.json +19 -15
- package/plugins/takomi-flow/package.json +38 -38
- package/plugins/takomi-flow/pnpm-lock.yaml +813 -813
- package/plugins/takomi-flow/references/flow-provider-contract.md +349 -326
- package/plugins/takomi-flow/scripts/lib/agent-plan.mjs +140 -130
- package/plugins/takomi-flow/scripts/lib/api.mjs +113 -113
- package/plugins/takomi-flow/scripts/lib/args.mjs +66 -57
- package/plugins/takomi-flow/scripts/lib/audit.mjs +65 -65
- package/plugins/takomi-flow/scripts/lib/browser.mjs +78 -39
- package/plugins/takomi-flow/scripts/lib/capabilities.mjs +11 -11
- package/plugins/takomi-flow/scripts/lib/collect.mjs +53 -53
- package/plugins/takomi-flow/scripts/lib/commands.mjs +192 -175
- package/plugins/takomi-flow/scripts/lib/doctor.mjs +77 -77
- package/plugins/takomi-flow/scripts/lib/examples.mjs +17 -17
- package/plugins/takomi-flow/scripts/lib/flow-media.mjs +39 -0
- package/plugins/takomi-flow/scripts/lib/flow-outcome.mjs +115 -90
- package/plugins/takomi-flow/scripts/lib/flow-project-session.mjs +153 -0
- package/plugins/takomi-flow/scripts/lib/flow-ui.mjs +204 -165
- package/plugins/takomi-flow/scripts/lib/generation.mjs +190 -90
- package/plugins/takomi-flow/scripts/lib/inspect.mjs +81 -81
- package/plugins/takomi-flow/scripts/lib/mcp-prompts.mjs +39 -39
- package/plugins/takomi-flow/scripts/lib/mcp-resources.mjs +16 -16
- package/plugins/takomi-flow/scripts/lib/mcp-tools.mjs +165 -150
- package/plugins/takomi-flow/scripts/lib/media.mjs +78 -78
- package/plugins/takomi-flow/scripts/lib/observe.mjs +54 -54
- package/plugins/takomi-flow/scripts/lib/paths.mjs +37 -37
- package/plugins/takomi-flow/scripts/lib/playwright-loader.mjs +23 -23
- package/plugins/takomi-flow/scripts/lib/prompts.mjs +72 -72
- package/plugins/takomi-flow/scripts/lib/report.mjs +141 -141
- package/plugins/takomi-flow/scripts/lib/request-validator.mjs +73 -58
- package/plugins/takomi-flow/scripts/lib/request.mjs +66 -55
- package/plugins/takomi-flow/scripts/lib/resource-files.mjs +69 -69
- package/plugins/takomi-flow/scripts/lib/result.mjs +31 -31
- package/plugins/takomi-flow/scripts/lib/review.mjs +44 -44
- package/plugins/takomi-flow/scripts/lib/selftest.mjs +153 -153
- package/plugins/takomi-flow/scripts/lib/settings-plan.mjs +44 -39
- package/plugins/takomi-flow/scripts/lib/templates.mjs +37 -37
- package/plugins/takomi-flow/scripts/lib/trusted-chrome.mjs +67 -67
- package/plugins/takomi-flow/scripts/lib/workflow.mjs +56 -56
- package/plugins/takomi-flow/scripts/mcp-server.mjs +18 -18
- package/plugins/takomi-flow/scripts/mcp-smoke.mjs +144 -142
- package/plugins/takomi-flow/scripts/takomi-flow.mjs +17 -17
- package/plugins/takomi-flow/skills/takomi-flow/SKILL.md +244 -235
- package/plugins/takomi-flow/skills/takomi-flow/agents/openai.yaml +7 -7
- package/scripts/install-takomi-flow.ps1 +85 -85
- package/src/skills-catalog.js +10 -9
|
@@ -1,130 +1,140 @@
|
|
|
1
|
-
import { loadCapabilities } from './capabilities.mjs';
|
|
2
|
-
import { normalizeRequest } from './request.mjs';
|
|
3
|
-
|
|
4
|
-
export function createAgentPlan(args = {}) {
|
|
5
|
-
const request = normalizeRequest(args);
|
|
6
|
-
const capabilities = loadCapabilities();
|
|
7
|
-
const submit = Boolean(args.submit);
|
|
8
|
-
const collectTarget = args.targetDir || args['target-dir'];
|
|
9
|
-
return {
|
|
10
|
-
schemaVersion: 1,
|
|
11
|
-
status: 'ready',
|
|
12
|
-
provider: capabilities.provider,
|
|
13
|
-
summary: `${request.kind} ${request.mode} Flow job with ${request.variations} variation(s).`,
|
|
14
|
-
request,
|
|
15
|
-
gates: gates(request, submit),
|
|
16
|
-
mcpSequence: mcpSequence(request, { submit, collectTarget }),
|
|
17
|
-
cliSequence: cliSequence(request, { submit, collectTarget }),
|
|
18
|
-
expectedOutputs: expectedOutputs(request, collectTarget),
|
|
19
|
-
nextActions: nextActions(submit, collectTarget),
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function gates(request, submit) {
|
|
24
|
-
const items = [
|
|
25
|
-
{
|
|
26
|
-
name: 'spend',
|
|
27
|
-
required: submit,
|
|
28
|
-
satisfied: request.allowSpend,
|
|
29
|
-
note: 'Generation submission may spend Flow credits and requires allowSpend=true.',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: 'browser',
|
|
33
|
-
required: submit,
|
|
34
|
-
satisfied: false,
|
|
35
|
-
note: 'Browser-opening MCP tools require allowBrowser=true at call time.',
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
return submit ? items : items.map(item => ({ ...item, required: false }));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function mcpSequence(request, options) {
|
|
42
|
-
const workflowArgs = {
|
|
43
|
-
kind: request.kind,
|
|
44
|
-
prompt: request.prompt,
|
|
45
|
-
variations: request.variations,
|
|
46
|
-
aspectRatio: request.aspectRatio,
|
|
47
|
-
durationSeconds: request.durationSeconds,
|
|
48
|
-
mode: request.mode,
|
|
49
|
-
modelHint: request.modelHint,
|
|
50
|
-
outputDir: request.outputDir,
|
|
51
|
-
allowSpend: request.allowSpend,
|
|
52
|
-
extractFrames: request.extractFrames,
|
|
53
|
-
sourceAssets: request.sourceAssets,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (request.
|
|
96
|
-
if (request.
|
|
97
|
-
if (request.
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
1
|
+
import { loadCapabilities } from './capabilities.mjs';
|
|
2
|
+
import { normalizeRequest } from './request.mjs';
|
|
3
|
+
|
|
4
|
+
export function createAgentPlan(args = {}) {
|
|
5
|
+
const request = normalizeRequest(args);
|
|
6
|
+
const capabilities = loadCapabilities();
|
|
7
|
+
const submit = Boolean(args.submit);
|
|
8
|
+
const collectTarget = args.targetDir || args['target-dir'];
|
|
9
|
+
return {
|
|
10
|
+
schemaVersion: 1,
|
|
11
|
+
status: 'ready',
|
|
12
|
+
provider: capabilities.provider,
|
|
13
|
+
summary: `${request.kind} ${request.mode} Flow job with ${request.variations} variation(s).`,
|
|
14
|
+
request,
|
|
15
|
+
gates: gates(request, submit),
|
|
16
|
+
mcpSequence: mcpSequence(request, { submit, collectTarget }),
|
|
17
|
+
cliSequence: cliSequence(request, { submit, collectTarget }),
|
|
18
|
+
expectedOutputs: expectedOutputs(request, collectTarget),
|
|
19
|
+
nextActions: nextActions(submit, collectTarget),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function gates(request, submit) {
|
|
24
|
+
const items = [
|
|
25
|
+
{
|
|
26
|
+
name: 'spend',
|
|
27
|
+
required: submit,
|
|
28
|
+
satisfied: request.allowSpend,
|
|
29
|
+
note: 'Generation submission may spend Flow credits and requires allowSpend=true.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'browser',
|
|
33
|
+
required: submit,
|
|
34
|
+
satisfied: false,
|
|
35
|
+
note: 'Browser-opening MCP tools require allowBrowser=true at call time.',
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
return submit ? items : items.map(item => ({ ...item, required: false }));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function mcpSequence(request, options) {
|
|
42
|
+
const workflowArgs = {
|
|
43
|
+
kind: request.kind,
|
|
44
|
+
prompt: request.prompt,
|
|
45
|
+
variations: request.variations,
|
|
46
|
+
aspectRatio: request.aspectRatio,
|
|
47
|
+
durationSeconds: request.durationSeconds,
|
|
48
|
+
mode: request.mode,
|
|
49
|
+
modelHint: request.modelHint,
|
|
50
|
+
outputDir: request.outputDir,
|
|
51
|
+
allowSpend: request.allowSpend,
|
|
52
|
+
extractFrames: request.extractFrames,
|
|
53
|
+
sourceAssets: request.sourceAssets,
|
|
54
|
+
projectUrl: request.projectUrl,
|
|
55
|
+
reuseCurrentProject: request.reuseCurrentProject,
|
|
56
|
+
allowNewProject: request.allowNewProject,
|
|
57
|
+
freshChatOnFailure: request.freshChatOnFailure,
|
|
58
|
+
editorWaitMs: request.editorWaitMs,
|
|
59
|
+
submit: options.submit,
|
|
60
|
+
allowBrowser: options.submit,
|
|
61
|
+
};
|
|
62
|
+
const steps = [
|
|
63
|
+
{ tool: 'takomi_flow_audit', arguments: { outputDir: request.outputDir } },
|
|
64
|
+
{ tool: 'takomi_flow_workflow', arguments: compact(workflowArgs) },
|
|
65
|
+
{ tool: 'takomi_flow_review', arguments: { run: '<run.json|run-dir>', frames: request.extractFrames || 0 } },
|
|
66
|
+
];
|
|
67
|
+
if (options.collectTarget) {
|
|
68
|
+
steps.push({
|
|
69
|
+
tool: 'takomi_flow_collect',
|
|
70
|
+
arguments: {
|
|
71
|
+
run: '<run.json|run-dir>',
|
|
72
|
+
targetDir: options.collectTarget,
|
|
73
|
+
frames: request.extractFrames || 0,
|
|
74
|
+
includeFrames: true,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return steps;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function cliSequence(request, options) {
|
|
82
|
+
const base = [
|
|
83
|
+
'node scripts/takomi-flow.mjs audit',
|
|
84
|
+
`node scripts/takomi-flow.mjs workflow --kind ${request.kind} --prompt "${escapeArg(request.prompt)}"${optionArgs(request, options.submit)}`,
|
|
85
|
+
`node scripts/takomi-flow.mjs review --run <run.json|run-dir> --frames ${request.extractFrames || 0}`,
|
|
86
|
+
];
|
|
87
|
+
if (options.collectTarget) {
|
|
88
|
+
base.push(`node scripts/takomi-flow.mjs collect --run <run.json|run-dir> --target-dir "${escapeArg(options.collectTarget)}" --frames ${request.extractFrames || 0} --include-frames`);
|
|
89
|
+
}
|
|
90
|
+
return base;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function optionArgs(request, submit) {
|
|
94
|
+
const args = [];
|
|
95
|
+
if (request.variations) args.push(`--variations ${request.variations}`);
|
|
96
|
+
if (request.aspectRatio) args.push(`--aspect-ratio ${request.aspectRatio}`);
|
|
97
|
+
if (request.durationSeconds) args.push(`--duration ${request.durationSeconds}`);
|
|
98
|
+
if (request.mode) args.push(`--mode ${request.mode}`);
|
|
99
|
+
if (request.modelHint) args.push(`--model "${escapeArg(request.modelHint)}"`);
|
|
100
|
+
if (request.outputDir) args.push(`--output-dir "${escapeArg(request.outputDir)}"`);
|
|
101
|
+
if (request.extractFrames) args.push(`--extract-frames ${request.extractFrames}`);
|
|
102
|
+
if (request.sourceAssets.length) args.push(`--assets "${escapeArg(request.sourceAssets.join(','))}"`);
|
|
103
|
+
if (request.projectUrl) args.push(`--project-url "${escapeArg(request.projectUrl)}"`);
|
|
104
|
+
if (request.reuseCurrentProject) args.push('--reuse-current-project');
|
|
105
|
+
if (request.allowNewProject) args.push('--allow-new-project');
|
|
106
|
+
if (request.freshChatOnFailure === false) args.push('--fresh-chat-on-failure=false');
|
|
107
|
+
if (request.editorWaitMs) args.push(`--editor-wait-ms ${request.editorWaitMs}`);
|
|
108
|
+
if (submit) args.push('--submit --allow-browser --allow-spend');
|
|
109
|
+
return args.length ? ` ${args.join(' ')}` : '';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function expectedOutputs(request, collectTarget) {
|
|
113
|
+
const outputs = [
|
|
114
|
+
`${request.outputDir}/requests/<timestamp>-request.json`,
|
|
115
|
+
`${request.outputDir}/<runId>/run.json`,
|
|
116
|
+
`${request.outputDir}/<runId>/downloads/`,
|
|
117
|
+
`${request.outputDir}/<runId>/assets.json`,
|
|
118
|
+
`${request.outputDir}/<runId>/report.md`,
|
|
119
|
+
];
|
|
120
|
+
if (request.extractFrames) outputs.push(`${request.outputDir}/<runId>/frames/`);
|
|
121
|
+
if (collectTarget) outputs.push(`${collectTarget}/takomi-flow-collection.json`);
|
|
122
|
+
return outputs;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function nextActions(submit, collectTarget) {
|
|
126
|
+
const actions = ['Run the audit step first and treat missing profile as a bootstrap/login gate.'];
|
|
127
|
+
if (!submit) actions.push('Use the workflow step without submit to prepare and validate the request without spending credits.');
|
|
128
|
+
if (submit) actions.push('Confirm the user explicitly approved spending Flow credits before running the submit step.');
|
|
129
|
+
actions.push('After generation, review run metadata, errors, screenshots, and downloaded assets.');
|
|
130
|
+
if (collectTarget) actions.push('Collect reviewed outputs into the downstream target folder for pipeline reuse.');
|
|
131
|
+
return actions;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function compact(value) {
|
|
135
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function escapeArg(value) {
|
|
139
|
+
return String(value).replaceAll('"', '\\"');
|
|
140
|
+
}
|
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
import { createPreparedRequest } from './request.mjs';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { validateRequestFile } from './request-validator.mjs';
|
|
5
|
-
import { runDoctor } from './doctor.mjs';
|
|
6
|
-
import { loadCapabilities } from './capabilities.mjs';
|
|
7
|
-
import { listTemplates, loadTemplate, writeTemplate } from './templates.mjs';
|
|
8
|
-
import { runSelfTest } from './selftest.mjs';
|
|
9
|
-
import { inspectRun, latestRun, listRuns, resolveRun } from './inspect.mjs';
|
|
10
|
-
import { catalogAssets } from './media.mjs';
|
|
11
|
-
import { observeFlow } from './observe.mjs';
|
|
12
|
-
import { generateFromRequest } from './generation.mjs';
|
|
13
|
-
import { createReport } from './report.mjs';
|
|
14
|
-
import { runWorkflow } from './workflow.mjs';
|
|
15
|
-
import { reviewRun } from './review.mjs';
|
|
16
|
-
import { runAudit } from './audit.mjs';
|
|
17
|
-
import { collectRun } from './collect.mjs';
|
|
18
|
-
import { loadExamples } from './examples.mjs';
|
|
19
|
-
import { createAgentPlan } from './agent-plan.mjs';
|
|
20
|
-
|
|
21
|
-
export async function doctor(args = {}) {
|
|
22
|
-
return runDoctor({ profileDir: args.profileDir, outputDir: args.outputDir });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function capabilities() {
|
|
26
|
-
return loadCapabilities();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function observe(args = {}) {
|
|
30
|
-
return observeFlow({
|
|
31
|
-
profileDir: args.profileDir,
|
|
32
|
-
outputDir: args.outputDir,
|
|
33
|
-
browserChannel: args.browserChannel,
|
|
34
|
-
cdpUrl: args.cdpUrl,
|
|
35
|
-
headless: Boolean(args.headless),
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function template(args = {}) {
|
|
40
|
-
if (!args.kind) return { templates: listTemplates() };
|
|
41
|
-
if (args.outputDir) return writeTemplate(args.kind, args.outputDir);
|
|
42
|
-
return loadTemplate(args.kind);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function prepare(args = {}) {
|
|
46
|
-
const { request, requestPath } = createPreparedRequest(args);
|
|
47
|
-
return { status: 'prepared', requestPath, request };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function validate(args = {}) {
|
|
51
|
-
return validateRequestFile(args.request);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function selftest(args = {}) {
|
|
55
|
-
return runSelfTest({ outputDir: args.outputDir });
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function inspect(args = {}) {
|
|
59
|
-
return inspectRun(args.run);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function latest(args = {}) {
|
|
63
|
-
return latestRun(args.outputDir);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function runs(args = {}) {
|
|
67
|
-
return listRuns(args.outputDir, args.limit);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export async function assets(args = {}) {
|
|
71
|
-
const run = resolveRun(args.run);
|
|
72
|
-
return catalogAssets(run, assetPathsForRun(run), { frames: args.frames || 0 });
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export async function generate(args = {}) {
|
|
76
|
-
return generateFromRequest(args);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function report(args = {}) {
|
|
80
|
-
return createReport(args);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function workflow(args = {}) {
|
|
84
|
-
return runWorkflow(args);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export async function review(args = {}) {
|
|
88
|
-
return reviewRun(args);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function audit(args = {}) {
|
|
92
|
-
return runAudit(args);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function collect(args = {}) {
|
|
96
|
-
return collectRun(args);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function examples(args = {}) {
|
|
100
|
-
return loadExamples(args.name);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function plan(args = {}) {
|
|
104
|
-
return createAgentPlan(args);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function assetPathsForRun(run) {
|
|
108
|
-
if (run.data.assets?.length) return run.data.assets;
|
|
109
|
-
if (!fs.existsSync(run.downloadsDir)) return [];
|
|
110
|
-
return fs.readdirSync(run.downloadsDir)
|
|
111
|
-
.map(name => path.join(run.downloadsDir, name))
|
|
112
|
-
.filter(filePath => fs.statSync(filePath).isFile());
|
|
113
|
-
}
|
|
1
|
+
import { createPreparedRequest } from './request.mjs';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { validateRequestFile } from './request-validator.mjs';
|
|
5
|
+
import { runDoctor } from './doctor.mjs';
|
|
6
|
+
import { loadCapabilities } from './capabilities.mjs';
|
|
7
|
+
import { listTemplates, loadTemplate, writeTemplate } from './templates.mjs';
|
|
8
|
+
import { runSelfTest } from './selftest.mjs';
|
|
9
|
+
import { inspectRun, latestRun, listRuns, resolveRun } from './inspect.mjs';
|
|
10
|
+
import { catalogAssets } from './media.mjs';
|
|
11
|
+
import { observeFlow } from './observe.mjs';
|
|
12
|
+
import { generateFromRequest } from './generation.mjs';
|
|
13
|
+
import { createReport } from './report.mjs';
|
|
14
|
+
import { runWorkflow } from './workflow.mjs';
|
|
15
|
+
import { reviewRun } from './review.mjs';
|
|
16
|
+
import { runAudit } from './audit.mjs';
|
|
17
|
+
import { collectRun } from './collect.mjs';
|
|
18
|
+
import { loadExamples } from './examples.mjs';
|
|
19
|
+
import { createAgentPlan } from './agent-plan.mjs';
|
|
20
|
+
|
|
21
|
+
export async function doctor(args = {}) {
|
|
22
|
+
return runDoctor({ profileDir: args.profileDir, outputDir: args.outputDir });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function capabilities() {
|
|
26
|
+
return loadCapabilities();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function observe(args = {}) {
|
|
30
|
+
return observeFlow({
|
|
31
|
+
profileDir: args.profileDir,
|
|
32
|
+
outputDir: args.outputDir,
|
|
33
|
+
browserChannel: args.browserChannel,
|
|
34
|
+
cdpUrl: args.cdpUrl,
|
|
35
|
+
headless: Boolean(args.headless),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function template(args = {}) {
|
|
40
|
+
if (!args.kind) return { templates: listTemplates() };
|
|
41
|
+
if (args.outputDir) return writeTemplate(args.kind, args.outputDir);
|
|
42
|
+
return loadTemplate(args.kind);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function prepare(args = {}) {
|
|
46
|
+
const { request, requestPath } = createPreparedRequest(args);
|
|
47
|
+
return { status: 'prepared', requestPath, request };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function validate(args = {}) {
|
|
51
|
+
return validateRequestFile(args.request);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function selftest(args = {}) {
|
|
55
|
+
return runSelfTest({ outputDir: args.outputDir });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function inspect(args = {}) {
|
|
59
|
+
return inspectRun(args.run);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function latest(args = {}) {
|
|
63
|
+
return latestRun(args.outputDir);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function runs(args = {}) {
|
|
67
|
+
return listRuns(args.outputDir, args.limit);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function assets(args = {}) {
|
|
71
|
+
const run = resolveRun(args.run);
|
|
72
|
+
return catalogAssets(run, assetPathsForRun(run), { frames: args.frames || 0 });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function generate(args = {}) {
|
|
76
|
+
return generateFromRequest(args);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function report(args = {}) {
|
|
80
|
+
return createReport(args);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function workflow(args = {}) {
|
|
84
|
+
return runWorkflow(args);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function review(args = {}) {
|
|
88
|
+
return reviewRun(args);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function audit(args = {}) {
|
|
92
|
+
return runAudit(args);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function collect(args = {}) {
|
|
96
|
+
return collectRun(args);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function examples(args = {}) {
|
|
100
|
+
return loadExamples(args.name);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function plan(args = {}) {
|
|
104
|
+
return createAgentPlan(args);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function assetPathsForRun(run) {
|
|
108
|
+
if (run.data.assets?.length) return run.data.assets;
|
|
109
|
+
if (!fs.existsSync(run.downloadsDir)) return [];
|
|
110
|
+
return fs.readdirSync(run.downloadsDir)
|
|
111
|
+
.map(name => path.join(run.downloadsDir, name))
|
|
112
|
+
.filter(filePath => fs.statSync(filePath).isFile());
|
|
113
|
+
}
|
|
@@ -1,57 +1,66 @@
|
|
|
1
|
-
export function parseArgs(argv) {
|
|
2
|
-
const args = { _: [] };
|
|
3
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
4
|
-
const token = argv[i];
|
|
5
|
-
if (!token.startsWith('--')) {
|
|
6
|
-
args._.push(token);
|
|
7
|
-
continue;
|
|
8
|
-
}
|
|
9
|
-
const key = token.slice(2);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
node scripts/takomi-flow.mjs
|
|
31
|
-
node scripts/takomi-flow.mjs
|
|
32
|
-
node scripts/takomi-flow.mjs
|
|
33
|
-
node scripts/takomi-flow.mjs
|
|
34
|
-
node scripts/takomi-flow.mjs
|
|
35
|
-
node scripts/takomi-flow.mjs
|
|
36
|
-
node scripts/takomi-flow.mjs
|
|
37
|
-
node scripts/takomi-flow.mjs
|
|
38
|
-
node scripts/takomi-flow.mjs
|
|
39
|
-
node scripts/takomi-flow.mjs
|
|
40
|
-
node scripts/takomi-flow.mjs
|
|
41
|
-
node scripts/takomi-flow.mjs
|
|
42
|
-
node scripts/takomi-flow.mjs
|
|
43
|
-
node scripts/takomi-flow.mjs
|
|
44
|
-
node scripts/takomi-flow.mjs
|
|
45
|
-
node scripts/takomi-flow.mjs
|
|
46
|
-
node scripts/takomi-flow.mjs
|
|
47
|
-
node scripts/takomi-flow.mjs
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
export function parseArgs(argv) {
|
|
2
|
+
const args = { _: [] };
|
|
3
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
4
|
+
const token = argv[i];
|
|
5
|
+
if (!token.startsWith('--')) {
|
|
6
|
+
args._.push(token);
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
const [key, inlineValue] = token.slice(2).split(/=(.*)/s, 2);
|
|
10
|
+
if (inlineValue !== undefined) {
|
|
11
|
+
args[key] = inlineValue;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const next = argv[i + 1];
|
|
15
|
+
if (!next || next.startsWith('--')) {
|
|
16
|
+
args[key] = true;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
args[key] = next;
|
|
20
|
+
i += 1;
|
|
21
|
+
}
|
|
22
|
+
return args;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function printUsage() {
|
|
26
|
+
console.log(`
|
|
27
|
+
TakomiFlow
|
|
28
|
+
|
|
29
|
+
Usage:
|
|
30
|
+
node scripts/takomi-flow.mjs bootstrap [--profile-dir <path>] [--browser-channel chrome] [--cdp-url <url>] [--headless]
|
|
31
|
+
node scripts/takomi-flow.mjs doctor [--profile-dir <path>] [--output-dir <path>]
|
|
32
|
+
node scripts/takomi-flow.mjs audit [--profile-dir <path>] [--output-dir <path>]
|
|
33
|
+
node scripts/takomi-flow.mjs capabilities
|
|
34
|
+
node scripts/takomi-flow.mjs examples [--name <example-name>]
|
|
35
|
+
node scripts/takomi-flow.mjs trusted-chrome [--port 9222] [--profile-dir <path>] [--chrome-path <path>]
|
|
36
|
+
node scripts/takomi-flow.mjs plan --kind <video|image> --prompt <text> [--submit --target-dir <path>]
|
|
37
|
+
node scripts/takomi-flow.mjs observe [--profile-dir <path>] [--output-dir <path>] [--browser-channel chrome] [--cdp-url <url>] [--headless]
|
|
38
|
+
node scripts/takomi-flow.mjs smoke [--profile-dir <path>] [--output-dir <path>] [--browser-channel chrome] [--cdp-url <url>]
|
|
39
|
+
node scripts/takomi-flow.mjs prepare --kind <video|image> --prompt <text> [--variations 1]
|
|
40
|
+
node scripts/takomi-flow.mjs workflow --kind <video|image> --prompt <text> [--project-url <url>] [--reuse-current-project] [--allow-new-project] [--submit --allow-browser --allow-spend]
|
|
41
|
+
node scripts/takomi-flow.mjs template --kind <video|image> [--output-dir <path>]
|
|
42
|
+
node scripts/takomi-flow.mjs validate --request <path>
|
|
43
|
+
node scripts/takomi-flow.mjs generate --request <path> [--project-url <url>] [--reuse-current-project] [--allow-new-project]
|
|
44
|
+
node scripts/takomi-flow.mjs selftest [--output-dir <path>]
|
|
45
|
+
node scripts/takomi-flow.mjs inspect --run <run.json|run-dir>
|
|
46
|
+
node scripts/takomi-flow.mjs latest [--output-dir <path>]
|
|
47
|
+
node scripts/takomi-flow.mjs runs [--output-dir <path>] [--limit 20]
|
|
48
|
+
node scripts/takomi-flow.mjs assets --run <run.json|run-dir> [--frames 4]
|
|
49
|
+
node scripts/takomi-flow.mjs review --run <run.json|run-dir> [--frames 4]
|
|
50
|
+
node scripts/takomi-flow.mjs collect --run <run.json|run-dir> --target-dir <path> [--frames 4 --include-frames]
|
|
51
|
+
node scripts/takomi-flow.mjs report [--run <run.json|run-dir>] [--output-dir <path>]
|
|
52
|
+
|
|
53
|
+
Spend guard:
|
|
54
|
+
generation submits only when request allowSpend=true or TAKOMI_FLOW_ALLOW_SPEND=true.
|
|
55
|
+
|
|
56
|
+
Google login note:
|
|
57
|
+
If Google says the browser may not be secure, use trusted Chrome attach mode:
|
|
58
|
+
node scripts/takomi-flow.mjs trusted-chrome
|
|
59
|
+
Then log in manually and attach with --cdp-url http://127.0.0.1:9222.
|
|
60
|
+
|
|
61
|
+
Project reuse:
|
|
62
|
+
Pass --project-url or attach Chrome while already on a Flow project. TakomiFlow will not click
|
|
63
|
+
New project unless --allow-new-project is set. Use --fresh-chat-on-failure=false to disable
|
|
64
|
+
same-project chat recovery.
|
|
65
|
+
`);
|
|
66
|
+
}
|