@martini-film/cli 0.3.0 → 0.4.1
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/README.md +169 -44
- package/dist/api.js +71 -23
- package/dist/api.js.map +1 -1
- package/dist/approve.js +16 -1
- package/dist/approve.js.map +1 -1
- package/dist/cli.js +487 -142
- package/dist/cli.js.map +1 -1
- package/dist/commands/assets.js +165 -29
- package/dist/commands/assets.js.map +1 -1
- package/dist/commands/call.js +131 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/context.js +11 -2
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/files.js +117 -9
- package/dist/commands/files.js.map +1 -1
- package/dist/commands/guide.js +71 -0
- package/dist/commands/guide.js.map +1 -0
- package/dist/commands/init.js +213 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.js +37 -6
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/tools.js +88 -80
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/use.js +148 -0
- package/dist/commands/use.js.map +1 -0
- package/dist/config.js +87 -6
- package/dist/config.js.map +1 -1
- package/dist/generated/guide.json +104 -0
- package/dist/generated/manifest.json +73 -24
- package/dist/guideCache.js +204 -0
- package/dist/guideCache.js.map +1 -0
- package/dist/help.js +391 -34
- package/dist/help.js.map +1 -1
- package/dist/manifest.js +27 -0
- package/dist/manifest.js.map +1 -1
- package/dist/manifestCache.js +196 -0
- package/dist/manifestCache.js.map +1 -0
- package/dist/output.js +289 -30
- package/dist/output.js.map +1 -1
- package/dist/schema.js +281 -16
- package/dist/schema.js.map +1 -1
- package/dist/wait.js +33 -2
- package/dist/wait.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, realpathSync, statSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { basename, dirname, join, resolve, sep } from 'node:path';
|
|
3
|
+
import { flagBoolean, flagString } from '../args.js';
|
|
4
|
+
import { ArgumentError } from '../schema.js';
|
|
5
|
+
export const SKILL_MD = `---
|
|
6
|
+
name: martini
|
|
7
|
+
description: Work on Martini (AI video production) projects from the shell with the martini CLI — read boards, upload and download material, generate and wait for shots, edit project memory files. Use for any Martini task when a shell is available.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Martini CLI
|
|
11
|
+
|
|
12
|
+
## When to use
|
|
13
|
+
|
|
14
|
+
Any Martini task: projects, canvases, shots, the library, generation, timelines, project memory files. If the
|
|
15
|
+
Martini MCP connector is also installed, use the CLI anyway — every MCP tool is a \`martini\` command of the same
|
|
16
|
+
name, with its arguments as flags, and the CLI costs no tool-listing context.
|
|
17
|
+
|
|
18
|
+
## Install and sign in
|
|
19
|
+
|
|
20
|
+
\`\`\`bash
|
|
21
|
+
npm install --global @martini-film/cli # installs the CLI on PATH (or run each command as npx @martini-film/cli <command>)
|
|
22
|
+
martini login # pair this device in the browser (as an agent: --no-wait, relay the code, rerun)
|
|
23
|
+
martini whoami # which organization and key the CLI acts as
|
|
24
|
+
\`\`\`
|
|
25
|
+
|
|
26
|
+
Inside a Martini workflow run the CLI is already signed in through \`.martini/config.json\`; never run
|
|
27
|
+
\`martini login\` there.
|
|
28
|
+
|
|
29
|
+
## Start here
|
|
30
|
+
|
|
31
|
+
\`\`\`bash
|
|
32
|
+
martini guide # the operator rules: read them once per session, again on a GUIDE_CHANGED warning
|
|
33
|
+
martini guide generation # one topic: orientation, library, timeline, generation, storage, support, shell
|
|
34
|
+
martini use "<project name or id>" # this directory now works in that project
|
|
35
|
+
martini get_board_overview # canvases, shots, library, variables
|
|
36
|
+
\`\`\`
|
|
37
|
+
|
|
38
|
+
\`martini use\` writes \`.martini/context.json\`, which every later command here reads: your shell is new on each
|
|
39
|
+
command, so an exported variable would not last. \`--project\` / \`--canvas\` override it. It holds no key.
|
|
40
|
+
|
|
41
|
+
## Finding commands
|
|
42
|
+
|
|
43
|
+
- \`martini --help\` lists every command; \`martini <tool> --help\` shows its flags, an example, and its result
|
|
44
|
+
fields. Read it before a tool's first call.
|
|
45
|
+
- \`martini <tool> --schema <flag> --keys\` lists the keys of a JSON argument (\`--nodes\`, \`--edit\`).
|
|
46
|
+
- \`martini tools\` compares the server's tool list with this build's; \`martini call <tool> --args '{…}'\` sends
|
|
47
|
+
any tool by name.
|
|
48
|
+
|
|
49
|
+
## Compound commands
|
|
50
|
+
|
|
51
|
+
- \`martini upload <path…>\`: local files to canvas assets; reference and frame flags take their ids.
|
|
52
|
+
- \`martini download <asset-id…> --dir <dir>\`: completed assets to files.
|
|
53
|
+
- \`martini wait <asset-id…> --timeout N\`: block until assets (or \`--job\`, \`--run\`, \`--render\`) settle.
|
|
54
|
+
- \`martini files pull <dir>\` / \`martini files push <dir>\`: project memory files as a directory. Push exits 1
|
|
55
|
+
when a file changed on the server since the pull; pull keeps a file you edited.
|
|
56
|
+
- \`martini probe <path|asset-id>…\`: duration, resolution, fps, codecs, sha256 (needs ffprobe).
|
|
57
|
+
|
|
58
|
+
## Looking at results
|
|
59
|
+
|
|
60
|
+
Nothing is shown until you open a file:
|
|
61
|
+
|
|
62
|
+
\`\`\`bash
|
|
63
|
+
martini inspect_video --video-asset-ids <id> <id> --out-dir review # a contact sheet per shot
|
|
64
|
+
martini view_asset --asset-id <id> --raw --out still.webp # one image
|
|
65
|
+
\`\`\`
|
|
66
|
+
|
|
67
|
+
\`--out-dir\` prints \`{ dir, files: [{ path, about }] }\`; \`about\` names each file's asset, shot, and duration.
|
|
68
|
+
|
|
69
|
+
## Output and arguments
|
|
70
|
+
|
|
71
|
+
- Results are JSON on stdout (\`guide\`, \`init\`, \`files cat\`, and \`--help\` print text); errors are one JSON
|
|
72
|
+
object on stderr. Exit 0 means the command did all you asked. Otherwise read \`error.code\`; work that was
|
|
73
|
+
done is still on stdout (a push's \`skipped\`, a wait's \`pending\`).
|
|
74
|
+
- \`--fields a,b.c\` keeps only those paths of the result; \`--out <path>\` writes the result to a file.
|
|
75
|
+
- Object arguments take JSON (\`--placement '{"rightOf": "<id>"}'\`), a list of objects takes \`@file\`
|
|
76
|
+
(\`--nodes @nodes.json\`), and \`--args @args.json\` passes the whole arguments object.
|
|
77
|
+
- An asset id works in either spelling: the bare id, or \`asset-<id>\`.
|
|
78
|
+
|
|
79
|
+
## Waiting and approval
|
|
80
|
+
|
|
81
|
+
- Single-item generation and rendering wait by default (\`--wait\` / \`--no-wait\`). Fan a batch out, then run
|
|
82
|
+
\`martini wait <ids…> --timeout N\` once; a wait that runs out exits 4 and prints the resume command, and a
|
|
83
|
+
failed shot exits 1.
|
|
84
|
+
- Generations cost olives and cannot be undone: agree the plan with the user first. \`generate_nodes\`,
|
|
85
|
+
\`upscale_assets\`, and \`enhance_draft\` quote first; \`--approve --max-olives N\` approves under the cap in one
|
|
86
|
+
command. Over the cap nothing starts (exit 5): ask the user before raising it.
|
|
87
|
+
|
|
88
|
+
## Exit codes
|
|
89
|
+
|
|
90
|
+
0 done, all of it · 1 tool error · 2 usage · 3 auth · 4 not ready or timed out · 5 over budget (olives, or a quote over --max-olives)
|
|
91
|
+
`;
|
|
92
|
+
export const AGENTS_MD_MARKER = '## Martini CLI';
|
|
93
|
+
export const AGENTS_MD_POINTER = `${AGENTS_MD_MARKER}
|
|
94
|
+
|
|
95
|
+
Martini is available as the \`martini\` command; the skill at \`.agents/skills/martini/SKILL.md\` says how to use it. Start with \`martini guide\`.
|
|
96
|
+
`;
|
|
97
|
+
const SKILL_DIRECTORIES = ['.agents/skills', '.claude/skills'];
|
|
98
|
+
export const GITIGNORE_LINES = ['**/.martini/files.json', '**/.martini/conflicts/'];
|
|
99
|
+
function resolveLinks(path, depth = 0) {
|
|
100
|
+
try {
|
|
101
|
+
return realpathSync(path);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
}
|
|
105
|
+
if (depth < 40) {
|
|
106
|
+
try {
|
|
107
|
+
if (lstatSync(path).isSymbolicLink())
|
|
108
|
+
return resolveLinks(resolve(dirname(path), readlinkSync(path)), depth + 1);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const parent = dirname(path);
|
|
114
|
+
return parent === path ? path : join(resolveLinks(parent, depth + 1), basename(path));
|
|
115
|
+
}
|
|
116
|
+
function skillTargets(root) {
|
|
117
|
+
const [shared, claude] = SKILL_DIRECTORIES.map(directory => join(root, directory));
|
|
118
|
+
const sameDirectory = existsOrLinked(claude) && resolveLinks(claude) === resolveLinks(shared);
|
|
119
|
+
return (sameDirectory ? [shared] : [shared, claude]).map(directory => join(directory, 'martini', 'SKILL.md'));
|
|
120
|
+
}
|
|
121
|
+
function existsOrLinked(path) {
|
|
122
|
+
try {
|
|
123
|
+
lstatSync(path);
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function writeSkill(path, force) {
|
|
131
|
+
if (existsSync(path)) {
|
|
132
|
+
if (readFileSync(path, 'utf8') === SKILL_MD)
|
|
133
|
+
return 'unchanged';
|
|
134
|
+
if (!force)
|
|
135
|
+
return 'kept';
|
|
136
|
+
}
|
|
137
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
138
|
+
writeFileSync(path, SKILL_MD);
|
|
139
|
+
return 'written';
|
|
140
|
+
}
|
|
141
|
+
function writeGitignore(path) {
|
|
142
|
+
const existing = existsSync(path) ? readFileSync(path, 'utf8') : '';
|
|
143
|
+
const present = new Set(existing.split(/\r?\n/).map(line => line.trim()));
|
|
144
|
+
const added = GITIGNORE_LINES.filter(line => !present.has(line));
|
|
145
|
+
if (added.length === 0)
|
|
146
|
+
return { path, status: 'unchanged', added: [] };
|
|
147
|
+
const block = ['# martini CLI: local state (martini init)', ...added].join('\n');
|
|
148
|
+
writeFileSync(path, `${existing.trimEnd()}${existing.trim() ? '\n\n' : ''}${block}\n`);
|
|
149
|
+
return { path, status: 'written', added };
|
|
150
|
+
}
|
|
151
|
+
function writePointer(path) {
|
|
152
|
+
const existing = existsSync(path) ? readFileSync(path, 'utf8') : '';
|
|
153
|
+
if (existing.includes(AGENTS_MD_MARKER))
|
|
154
|
+
return 'unchanged';
|
|
155
|
+
writeFileSync(path, `${existing.trimEnd()}${existing.trim() ? '\n\n' : ''}${AGENTS_MD_POINTER}`);
|
|
156
|
+
return 'written';
|
|
157
|
+
}
|
|
158
|
+
export const init = {
|
|
159
|
+
name: 'init',
|
|
160
|
+
summary: 'Install the Martini agent skill and a three-line AGENTS.md pointer in a repository (prints them without --write)',
|
|
161
|
+
usage: 'martini init [--write] [--force] [--dir <repo>]',
|
|
162
|
+
details: 'Without --write, prints the skill file, a line ---, and the AGENTS.md pointer, and writes nothing. With --write, installs the skill at <repo>/.agents/skills/martini/SKILL.md (read by Codex, Cursor, and other agents) and <repo>/.claude/skills/martini/SKILL.md (Claude Code) — only the first when .claude/skills is a link to .agents/skills — appends the pointer to <repo>/AGENTS.md (created if absent) unless it already has a "## Martini CLI" section, and adds the CLI\'s local state (.martini/files.json, .martini/conflicts/) to <repo>/.gitignore (created if absent; .martini/context.json holds no key and is meant to be committed). A skill file with other content is kept unless --force; nothing outside <repo> is written. The skill is short on purpose: it sends the agent to martini guide for the operator rules and to martini <tool> --help for flags. Result: { ok, skills: [{ path, status: written | unchanged | kept }], agentsMd: { path, status: written | unchanged }, gitignore: { path, status: written | unchanged, added } }.',
|
|
163
|
+
flags: [
|
|
164
|
+
{ flag: 'write', kind: 'boolean', description: 'Install the skill and the pointer instead of printing them' },
|
|
165
|
+
{
|
|
166
|
+
flag: 'force',
|
|
167
|
+
kind: 'boolean',
|
|
168
|
+
description: 'With --write: overwrite a skill file whose content differs (an older or edited copy)',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
flag: 'dir',
|
|
172
|
+
kind: 'string',
|
|
173
|
+
value: '<repo>',
|
|
174
|
+
description: 'With --write: the repository to install into (default: the working directory)',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
examples: ['martini init', 'martini init --write', 'martini init --write --force --dir ../my-film'],
|
|
178
|
+
async run(context) {
|
|
179
|
+
if (context.positionals.length > 0) {
|
|
180
|
+
throw new ArgumentError(`Unexpected argument ${JSON.stringify(context.positionals[0])}: martini init installs into a repository directory; name it with --dir <repo>.`);
|
|
181
|
+
}
|
|
182
|
+
const write = flagBoolean(context.flags, 'write') === true;
|
|
183
|
+
const force = flagBoolean(context.flags, 'force') === true;
|
|
184
|
+
const dir = flagString(context.flags, 'dir');
|
|
185
|
+
if (!write) {
|
|
186
|
+
if (force || dir !== undefined)
|
|
187
|
+
throw new ArgumentError('--force and --dir apply only with --write.');
|
|
188
|
+
return `${SKILL_MD}\n---\n\n${AGENTS_MD_POINTER}`;
|
|
189
|
+
}
|
|
190
|
+
const root = resolve(context.cwd, dir ?? '.');
|
|
191
|
+
if (!existsSync(root) || !statSync(root).isDirectory()) {
|
|
192
|
+
throw new ArgumentError(`--dir ${dir ?? root} is not a directory.`);
|
|
193
|
+
}
|
|
194
|
+
const agentsMd = join(root, 'AGENTS.md');
|
|
195
|
+
const gitignore = join(root, '.gitignore');
|
|
196
|
+
const targets = skillTargets(root);
|
|
197
|
+
const realRoot = realpathSync(root);
|
|
198
|
+
for (const path of [...targets, agentsMd, gitignore]) {
|
|
199
|
+
const real = resolveLinks(path);
|
|
200
|
+
if (real !== realRoot && !real.startsWith(`${realRoot}${sep}`)) {
|
|
201
|
+
throw new ArgumentError(`${path} resolves to ${real}, outside ${root} (through a link); martini init writes only inside the repository. Nothing was written.`, { hint: 'Fix the link, or install by hand from what martini init prints.' });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const skills = targets.map(path => ({ path, status: writeSkill(path, force) }));
|
|
205
|
+
return {
|
|
206
|
+
ok: true,
|
|
207
|
+
skills,
|
|
208
|
+
agentsMd: { path: agentsMd, status: writePointer(agentsMd) },
|
|
209
|
+
gitignore: writeGitignore(gitignore),
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/login.js
CHANGED
|
@@ -13,6 +13,11 @@ export function defaultDeviceLabel(env = process.env) {
|
|
|
13
13
|
export function pendingLoginPath(env = process.env) {
|
|
14
14
|
return join(dirname(userConfigPath(env)), 'login-pending.json');
|
|
15
15
|
}
|
|
16
|
+
export const PAIRING_MIN_REMAINING_MS = 120_000;
|
|
17
|
+
const PAIRING_GONE = new Set(['LOGIN_REQUEST_NOT_FOUND', 'LOGIN_REQUEST_EXPIRED']);
|
|
18
|
+
function secondsLeft(expiresAt, now) {
|
|
19
|
+
return Math.max(0, Math.round((new Date(expiresAt).getTime() - now) / 1000));
|
|
20
|
+
}
|
|
16
21
|
function readPendingLogin(env, apiUrl, now) {
|
|
17
22
|
const pending = readJsonFile(pendingLoginPath(env));
|
|
18
23
|
if (!pending || pending.apiUrl !== apiUrl || typeof pending.pollToken !== 'string')
|
|
@@ -61,7 +66,7 @@ export const login = {
|
|
|
61
66
|
name: 'login',
|
|
62
67
|
summary: 'Sign in: pair this device through the browser and save a 90-day key',
|
|
63
68
|
usage: 'martini login [--device <label>] [--profile <name>] [--no-default] [--no-wait] [--timeout <seconds>]',
|
|
64
|
-
details:
|
|
69
|
+
details: "Prints a URL and a code. Open the URL, enter the code, approve as you (every organization you belong to — one login for all your work; saved as the profile \"account\") or for one organization only (saved as a profile named after it); the first profile becomes the default. Tools run as you either way and the project you name decides who is billed; an organization key additionally reaches that organization's REST API and is listed in its Settings. The pairing is remembered until it expires (10 minutes), so running martini login again resumes it instead of starting over — after --no-wait, a --timeout, or a shell step that was killed while the person was still approving; one with under two minutes left that nobody approved is replaced by a fresh code instead. An agent therefore runs martini login --no-wait, tells the person the code and how long it lasts (expiresInSeconds), and runs martini login again once they have approved. Already signed in? martini whoami prints the key's scope and configSource, the file and profile it came from (~/.config/martini/config.json by default). A key is taken from, first to last: --api-key, MARTINI_API_KEY, a .martini/config.json above the directory that holds one (a workflow run's; skipped when a profile is named), then a profile of the config file (MARTINI_CONFIG_FILE, else ~/.config/martini/config.json): --profile, MARTINI_PROFILE, else its default. --api-url (or MARTINI_API_URL) signs in to another API; the profile keeps it.",
|
|
65
70
|
flags: [
|
|
66
71
|
{
|
|
67
72
|
flag: 'device',
|
|
@@ -87,10 +92,25 @@ export const login = {
|
|
|
87
92
|
const apiUrl = context.config.apiUrl;
|
|
88
93
|
const stderr = context.output.stderr ?? (text => process.stderr.write(text));
|
|
89
94
|
let pending = readPendingLogin(env, apiUrl, context.now());
|
|
95
|
+
let collected = null;
|
|
96
|
+
if (pending && new Date(pending.expiresAt).getTime() - context.now() < PAIRING_MIN_REMAINING_MS) {
|
|
97
|
+
const polled = await context.client.pollLogin(pending.pollToken).catch((error) => {
|
|
98
|
+
if (error instanceof CliApiError && PAIRING_GONE.has(error.code))
|
|
99
|
+
return { status: 'expired' };
|
|
100
|
+
throw error;
|
|
101
|
+
});
|
|
102
|
+
if (polled.status === 'pending' || polled.status === 'expired') {
|
|
103
|
+
clearPendingLogin(env);
|
|
104
|
+
pending = null;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
collected = polled;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
90
110
|
if (pending) {
|
|
91
111
|
stderr([
|
|
92
112
|
'',
|
|
93
|
-
` Resuming the pairing started ${pending.startedAt}:`,
|
|
113
|
+
` Resuming the pairing started ${pending.startedAt} (${secondsLeft(pending.expiresAt, context.now())} s left):`,
|
|
94
114
|
` open ${pending.verificationUrl}`,
|
|
95
115
|
` and enter the code ${pending.code}`,
|
|
96
116
|
'',
|
|
@@ -112,12 +132,13 @@ export const login = {
|
|
|
112
132
|
writePendingLogin(env, pending);
|
|
113
133
|
stderr(['', ` Open ${started.verificationUrl}`, ` and enter the code ${started.code}`, ''].join('\n'));
|
|
114
134
|
}
|
|
115
|
-
if (!wantsWait(context, true)) {
|
|
135
|
+
if (!wantsWait(context, true) && !collected) {
|
|
116
136
|
return {
|
|
117
137
|
status: 'pending',
|
|
118
138
|
code: pending.code,
|
|
119
139
|
verificationUrl: pending.verificationUrl,
|
|
120
140
|
expiresAt: pending.expiresAt,
|
|
141
|
+
expiresInSeconds: secondsLeft(pending.expiresAt, context.now()),
|
|
121
142
|
next: 'Approve the code in the browser, then run martini login again to collect the key.',
|
|
122
143
|
};
|
|
123
144
|
}
|
|
@@ -132,8 +153,10 @@ export const login = {
|
|
|
132
153
|
status: 0,
|
|
133
154
|
});
|
|
134
155
|
}
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
if (!collected)
|
|
157
|
+
await context.sleep(intervalMs);
|
|
158
|
+
const polled = collected ?? (await context.client.pollLogin(pending.pollToken));
|
|
159
|
+
collected = null;
|
|
137
160
|
if (polled.status === 'pending') {
|
|
138
161
|
if (context.now() > expiry) {
|
|
139
162
|
clearPendingLogin(env);
|
|
@@ -228,7 +251,8 @@ export const whoami = {
|
|
|
228
251
|
name: 'whoami',
|
|
229
252
|
summary: 'Which key this CLI acts as — its scope, organization, and your memberships — and where the config came from',
|
|
230
253
|
usage: 'martini whoami',
|
|
231
|
-
details: 'Result: { scope, organization, organizations, key, apiVersion, apiUrl, projectId, canvasId, runId, configSource }. scope is "user" for an account key (organization is null; organizations lists every one you belong to) or "organization" for a key bound to one.',
|
|
254
|
+
details: 'Result: { scope, organization, organizations, key, apiVersion, apiUrl, projectId, canvasId, runId, configSource, context }. scope is "user" for an account key (organization is null; organizations lists every one you belong to) or "organization" for a key bound to one. projectId and canvasId are what commands here will use; context names the .martini/context.json they came from (martini use), with the project and canvas names, or is null when a flag, a variable, or the profile supplied them.',
|
|
255
|
+
readOnly: true,
|
|
232
256
|
async run(context) {
|
|
233
257
|
const me = await context.client.me();
|
|
234
258
|
return {
|
|
@@ -244,6 +268,13 @@ export const whoami = {
|
|
|
244
268
|
executionId: context.config.executionId ?? null,
|
|
245
269
|
workerId: context.config.workerId ?? null,
|
|
246
270
|
configSource: context.config.source,
|
|
271
|
+
context: context.config.context
|
|
272
|
+
? {
|
|
273
|
+
file: context.config.context.path,
|
|
274
|
+
projectName: context.config.context.projectName ?? null,
|
|
275
|
+
canvasName: context.config.context.canvasName ?? null,
|
|
276
|
+
}
|
|
277
|
+
: null,
|
|
247
278
|
};
|
|
248
279
|
},
|
|
249
280
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/tools.js
CHANGED
|
@@ -5,46 +5,70 @@ import { tmpdir } from 'node:os';
|
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { CLI_VERSION, CliApiError } from '../api.js';
|
|
7
7
|
import { flagBoolean, flagString } from '../args.js';
|
|
8
|
-
import { userConfigPath } from '../config.js';
|
|
8
|
+
import { cacheDir, userConfigPath } from '../config.js';
|
|
9
9
|
import { SUPERSEDED_BY_COMPOUND } from '../help.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
10
|
+
import { compareManifests } from '../manifest.js';
|
|
11
|
+
import { MANIFEST_REFRESH_ENV, refreshDisabled } from '../manifestCache.js';
|
|
12
|
+
import { ArgumentError, bareAssetId } from '../schema.js';
|
|
13
|
+
import { requireProject, selectedFields } from './context.js';
|
|
13
14
|
export const tools = {
|
|
14
15
|
name: 'tools',
|
|
15
|
-
summary:
|
|
16
|
-
usage: 'martini tools [--remote] [--fields tools.name
|
|
17
|
-
details:
|
|
16
|
+
summary: "How the server's tool list differs from this build's (--list adds every tool commands run with)",
|
|
17
|
+
usage: 'martini tools [--list] [--refresh] [--remote] [--fields serverOnly,changed,tools.name]',
|
|
18
|
+
details: "Asks the server for its tool list first (one conditional request; MARTINI_MANIFEST_REFRESH=0 skips it) and keeps it in the local cache, so a tool or argument the server added since this build works as a command. Result: { source, hash, serverHash, fetchedAt?, upToDate, serverOnly, buildOnly, changed, count, refresh, note? } — a few hundred bytes. --list (or a tools.… path in --fields) adds tools: [{ name, description, readOnly, requiresActions, supersededBy? }], every tool with its description, about 70 KB: ask for it with --fields tools.name when the names are enough, and read one tool with martini <tool> --help. source: cache when commands run with the server's list (fetched at fetchedAt), baked when with this build's. hash: this build's manifest hash; serverHash: the server's for this key. serverOnly: tools the server has that this build lacks; buildOnly: tools this build has that the server does not list for this key (Actions tools without access, or retired ones); changed: tools whose arguments differ. upToDate: true when serverOnly and changed are both empty. Those four and serverHash are null while the server's list is unknown (offline, or MARTINI_MANIFEST_REFRESH=0 with nothing cached). With the list cached, serverOnly and changed already work as commands and flags (note says so when there are any); npx @martini-film/cli@latest updates the build itself. count is how many tools commands run with; refresh is \"on\", or \"off (MARTINI_MANIFEST_REFRESH=0)\" when nothing is fetched; supersededBy names the compound command to prefer (upload, download).",
|
|
19
|
+
readOnly: true,
|
|
18
20
|
flags: [
|
|
21
|
+
{
|
|
22
|
+
flag: 'list',
|
|
23
|
+
kind: 'boolean',
|
|
24
|
+
description: 'Add tools: every tool commands run with, with its description (large; narrow it with --fields)',
|
|
25
|
+
},
|
|
26
|
+
{ flag: 'refresh', kind: 'boolean', description: "Fetch the server's whole tool list, ignoring the cached one" },
|
|
19
27
|
{
|
|
20
28
|
flag: 'remote',
|
|
21
29
|
kind: 'boolean',
|
|
22
|
-
description: "Print the server's manifest (full JSON Schemas) instead of
|
|
30
|
+
description: "Print the server's manifest (full JSON Schemas) instead of the summary",
|
|
23
31
|
},
|
|
24
32
|
],
|
|
25
|
-
examples: ['martini tools --fields
|
|
33
|
+
examples: ['martini tools', 'martini tools --fields tools.name', 'martini tools --refresh --fields source,fetchedAt'],
|
|
26
34
|
async run(context) {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
serverHash = await context.client.serverManifestHash(local.hash);
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
serverHash = null;
|
|
35
|
+
const remote = flagBoolean(context.flags, 'remote') === true;
|
|
36
|
+
await context.manifests.refresh({ force: remote || flagBoolean(context.flags, 'refresh') === true });
|
|
37
|
+
if (remote) {
|
|
38
|
+
const known = context.manifests.state;
|
|
39
|
+
return known.server ?? { ...known.manifest, source: known.source };
|
|
36
40
|
}
|
|
41
|
+
const state = context.manifests.state;
|
|
42
|
+
const diff = state.server ? compareManifests(state.baked, state.server) : null;
|
|
43
|
+
const listed = flagBoolean(context.flags, 'list') === true ||
|
|
44
|
+
selectedFields(context).some(path => path === 'tools' || path.startsWith('tools.'));
|
|
37
45
|
return {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
source: state.source,
|
|
47
|
+
hash: state.baked.hash,
|
|
48
|
+
serverHash: state.server?.hash ?? null,
|
|
49
|
+
...(state.fetchedAt ? { fetchedAt: state.fetchedAt } : {}),
|
|
50
|
+
upToDate: diff ? diff.serverOnly.length === 0 && diff.changed.length === 0 : null,
|
|
51
|
+
serverOnly: diff?.serverOnly ?? null,
|
|
52
|
+
buildOnly: diff?.buildOnly ?? null,
|
|
53
|
+
changed: diff?.changed ?? null,
|
|
54
|
+
count: state.manifest.tools.length,
|
|
55
|
+
refresh: refreshState(context.env),
|
|
56
|
+
...(state.source === 'cache' && diff && diff.serverOnly.length > 0
|
|
57
|
+
? {
|
|
58
|
+
note: `serverOnly tools are on the server but not in this build; commands run with the server's list, so they work as commands (martini ${diff.serverOnly[0]} --help).`,
|
|
59
|
+
}
|
|
60
|
+
: {}),
|
|
61
|
+
...(listed
|
|
62
|
+
? {
|
|
63
|
+
tools: state.manifest.tools.map(tool => ({
|
|
64
|
+
name: tool.name,
|
|
65
|
+
description: tool.description,
|
|
66
|
+
readOnly: tool.annotations.readOnlyHint,
|
|
67
|
+
requiresActions: tool.requiresActions,
|
|
68
|
+
...(SUPERSEDED_BY_COMPOUND[tool.name] ? { supersededBy: SUPERSEDED_BY_COMPOUND[tool.name] } : {}),
|
|
69
|
+
})),
|
|
70
|
+
}
|
|
71
|
+
: {}),
|
|
48
72
|
};
|
|
49
73
|
},
|
|
50
74
|
};
|
|
@@ -54,6 +78,7 @@ export const models = {
|
|
|
54
78
|
summary: 'The model catalog (cached for an hour; --refresh to refetch; --query/--capability to narrow)',
|
|
55
79
|
usage: 'martini models [--query <text>] [--capability <name>] [--detail summary|full] [--refresh]',
|
|
56
80
|
details: 'get_models with a one-hour local cache per argument set (the catalog is ~10 KB and rarely changes).',
|
|
81
|
+
readOnly: true,
|
|
57
82
|
flags: [
|
|
58
83
|
{
|
|
59
84
|
flag: 'query',
|
|
@@ -88,8 +113,8 @@ export const models = {
|
|
|
88
113
|
args.capability = capability;
|
|
89
114
|
if (detail)
|
|
90
115
|
args.detailLevel = detail;
|
|
91
|
-
const
|
|
92
|
-
const cachePath = join(
|
|
116
|
+
const directory = cacheDir(context.env);
|
|
117
|
+
const cachePath = join(directory, `models-${Buffer.from(JSON.stringify(args)).toString('base64url')}.json`);
|
|
93
118
|
if (!flagBoolean(context.flags, 'refresh') && existsSync(cachePath)) {
|
|
94
119
|
try {
|
|
95
120
|
const cached = JSON.parse(readFileSync(cachePath, 'utf8'));
|
|
@@ -100,7 +125,7 @@ export const models = {
|
|
|
100
125
|
}
|
|
101
126
|
}
|
|
102
127
|
const result = await context.client.callTool('get_models', args);
|
|
103
|
-
mkdirSync(
|
|
128
|
+
mkdirSync(directory, { recursive: true });
|
|
104
129
|
writeFileSync(cachePath, JSON.stringify({ fetchedAt: context.now(), result }));
|
|
105
130
|
return result;
|
|
106
131
|
},
|
|
@@ -122,9 +147,13 @@ export function probeFile(path, run = spawnSync) {
|
|
|
122
147
|
});
|
|
123
148
|
}
|
|
124
149
|
const parsed = JSON.parse(String(probe.stdout));
|
|
125
|
-
const video = parsed.streams?.find(stream => stream.codec_type === 'video'
|
|
150
|
+
const video = parsed.streams?.find(stream => stream.codec_type === 'video' &&
|
|
151
|
+
stream.disposition?.attached_pic !== 1);
|
|
126
152
|
const audio = parsed.streams?.find(stream => stream.codec_type === 'audio');
|
|
153
|
+
const kind = video ? (isStill(parsed.format?.format_name, video) ? 'image' : 'video') : audio ? 'audio' : 'unknown';
|
|
127
154
|
const fps = (() => {
|
|
155
|
+
if (kind === 'image')
|
|
156
|
+
return null;
|
|
128
157
|
const rate = video?.avg_frame_rate ?? video?.r_frame_rate;
|
|
129
158
|
if (typeof rate !== 'string')
|
|
130
159
|
return null;
|
|
@@ -134,6 +163,7 @@ export function probeFile(path, run = spawnSync) {
|
|
|
134
163
|
const bytes = readFileSync(path);
|
|
135
164
|
return {
|
|
136
165
|
path,
|
|
166
|
+
kind,
|
|
137
167
|
bytes: bytes.byteLength,
|
|
138
168
|
durationSec: parsed.format?.duration ? Number(parsed.format.duration) : null,
|
|
139
169
|
width: typeof video?.width === 'number' ? video.width : null,
|
|
@@ -146,11 +176,17 @@ export function probeFile(path, run = spawnSync) {
|
|
|
146
176
|
sha256: createHash('sha256').update(bytes).digest('hex'),
|
|
147
177
|
};
|
|
148
178
|
}
|
|
179
|
+
function isStill(formatName, video) {
|
|
180
|
+
if (formatName && /(^|,)(image2|[a-z0-9]+_pipe)(,|$)/.test(formatName))
|
|
181
|
+
return true;
|
|
182
|
+
const codec = typeof video.codec_name === 'string' ? video.codec_name : '';
|
|
183
|
+
return /^(png|mjpeg|webp|bmp|tiff|gif)$/.test(codec) && Number(video.nb_frames ?? 1) <= 1 && !video.duration;
|
|
184
|
+
}
|
|
149
185
|
export const probe = {
|
|
150
186
|
name: 'probe',
|
|
151
187
|
summary: 'Measure local files or assets: duration, resolution, fps, codecs, channels, sha256 (needs ffprobe)',
|
|
152
188
|
usage: 'martini probe <path|asset-id>… [--dir <download-dir>]',
|
|
153
|
-
details: 'Result: { reports: [{ path, assetId?, bytes, durationSec, width, height, fps, videoCodec, audioCodec, audioChannels, sampleRate, sha256 }] }. An argument that is not an existing file is treated as an asset id and downloaded first (needs a project).',
|
|
189
|
+
details: 'Result: { reports: [{ path, assetId?, kind, bytes, durationSec, width, height, fps, videoCodec, audioCodec, audioChannels, sampleRate, sha256 }] }. kind is video, audio, image (a still: fps is null), or unknown. An argument that is not an existing file is treated as an asset id and downloaded first (needs a project).',
|
|
154
190
|
positionals: [
|
|
155
191
|
{
|
|
156
192
|
name: 'path|asset-id',
|
|
@@ -179,71 +215,43 @@ export const probe = {
|
|
|
179
215
|
continue;
|
|
180
216
|
}
|
|
181
217
|
const projectId = requireProject(context);
|
|
218
|
+
const assetId = bareAssetId(target);
|
|
182
219
|
const link = await context.client.callTool('get_asset_download_url', {
|
|
183
220
|
projectId,
|
|
184
|
-
assetId
|
|
221
|
+
assetId,
|
|
185
222
|
});
|
|
186
223
|
const { bytes } = await context.client.fetchBytes(link.downloadUrl);
|
|
187
224
|
mkdirSync(dir, { recursive: true });
|
|
188
|
-
const path = join(dir, link.suggestedFilename ??
|
|
225
|
+
const path = join(dir, link.suggestedFilename ?? assetId);
|
|
189
226
|
writeFileSync(path, bytes);
|
|
190
|
-
reports.push({ ...probeFile(path), assetId
|
|
227
|
+
reports.push({ ...probeFile(path), assetId });
|
|
191
228
|
}
|
|
192
229
|
return { reports };
|
|
193
230
|
},
|
|
194
231
|
};
|
|
195
|
-
const AGENTS_SNIPPET = `## Martini CLI
|
|
196
|
-
|
|
197
|
-
Martini is available as the \`martini\` command (every MCP tool is a subcommand; \`martini --help\` lists them,
|
|
198
|
-
\`martini <tool> --help\` shows a tool's flags). Prefer it over MCP tool calls for bulk, file, and wait work:
|
|
199
|
-
|
|
200
|
-
- \`martini upload <files…> --canvas <id>\` uploads local files as assets in one step.
|
|
201
|
-
- \`martini download <asset-id…> --dir out/\` saves completed assets; \`martini probe <path|id>\` measures them.
|
|
202
|
-
- \`martini <generation tool> … --wait\` blocks until the asset is ready; \`martini wait <ids…>\` resumes a wait.
|
|
203
|
-
- \`martini files pull dir/\` / \`martini files push dir/\` edit project memory files locally with conflict checks.
|
|
204
|
-
- Any argument can be JSON: \`--json @args.json\`. Results are JSON on stdout; \`--fields a,b\` trims them; \`--out f\` writes them.
|
|
205
|
-
- A wait stops at \`--timeout\` (default 50 s) with exit 4 but still prints the result and the pending ids; resume with \`martini wait <ids…> --timeout N\`, sized to your shell step.
|
|
206
|
-
- Tools that quote first (\`generate_nodes\`, \`upscale_assets\`, \`enhance_draft\`): \`--approve --max-olives N\` takes the quote and approves it under the cap in one command; over the cap nothing starts.
|
|
207
|
-
|
|
208
|
-
Exit codes: 0 ok · 1 tool error · 2 usage · 3 auth · 4 not ready or timed out · 5 insufficient olives.
|
|
209
|
-
`;
|
|
210
|
-
export const init = {
|
|
211
|
-
name: 'init',
|
|
212
|
-
summary: 'Print (or append to AGENTS.md with --write) the snippet that teaches agents to use the CLI',
|
|
213
|
-
usage: 'martini init [--write [path]]',
|
|
214
|
-
positionals: [{ name: 'path', description: 'With --write: the file to append to (default ./AGENTS.md)' }],
|
|
215
|
-
flags: [
|
|
216
|
-
{
|
|
217
|
-
flag: 'write',
|
|
218
|
-
kind: 'boolean',
|
|
219
|
-
description: 'Append the snippet to the file instead of printing it (skipped when already present)',
|
|
220
|
-
},
|
|
221
|
-
],
|
|
222
|
-
async run(context) {
|
|
223
|
-
if (flagBoolean(context.flags, 'write')) {
|
|
224
|
-
const target = context.positionals[0] ?? join(context.cwd, 'AGENTS.md');
|
|
225
|
-
const existing = existsSync(target) ? readFileSync(target, 'utf8') : '';
|
|
226
|
-
if (existing.includes('## Martini CLI'))
|
|
227
|
-
return { ok: true, path: target, changed: false };
|
|
228
|
-
writeFileSync(target, `${existing.trimEnd()}${existing ? '\n\n' : ''}${AGENTS_SNIPPET}`);
|
|
229
|
-
return { ok: true, path: target, changed: true };
|
|
230
|
-
}
|
|
231
|
-
return AGENTS_SNIPPET;
|
|
232
|
-
},
|
|
233
|
-
};
|
|
234
232
|
export const version = {
|
|
235
233
|
name: 'version',
|
|
236
|
-
summary: 'The CLI version,
|
|
234
|
+
summary: 'The CLI version, which tool manifest commands run with, and the config file paths',
|
|
237
235
|
usage: 'martini version',
|
|
238
|
-
|
|
236
|
+
readOnly: true,
|
|
237
|
+
details: "Result: { version, manifestSource, runningManifestHash, manifestHash, cachedManifestHash, fetchedAt?, tools, refresh, manifestCache, userConfig }. runningManifestHash is the tool list commands run with: the server's list cached for this credential when manifestSource is cache (fetched at fetchedAt; the same as cachedManifestHash), this build's own when it is baked. manifestHash is always this build's, so the two differ whenever the server's list is in use and has changed since this build. tools counts the list in use; refresh is \"on\", or \"off (MARTINI_MANIFEST_REFRESH=0)\" when no command fetches the server's list; manifestCache is the cache file for this API URL and credential (null for a workflow run key or no key). Reads only local files: martini tools refreshes. martini --version prints the same.",
|
|
239
238
|
async run(context) {
|
|
240
|
-
const
|
|
239
|
+
const state = context.manifests.state;
|
|
241
240
|
return {
|
|
242
241
|
version: CLI_VERSION,
|
|
243
|
-
|
|
244
|
-
|
|
242
|
+
manifestSource: state.source,
|
|
243
|
+
runningManifestHash: state.manifest.hash,
|
|
244
|
+
manifestHash: state.baked.hash,
|
|
245
|
+
cachedManifestHash: state.source === 'cache' ? state.manifest.hash : null,
|
|
246
|
+
...(state.fetchedAt ? { fetchedAt: state.fetchedAt } : {}),
|
|
247
|
+
tools: state.manifest.tools.length,
|
|
248
|
+
refresh: refreshState(context.env),
|
|
249
|
+
manifestCache: state.cachePath,
|
|
245
250
|
userConfig: userConfigPath(context.env),
|
|
246
251
|
};
|
|
247
252
|
},
|
|
248
253
|
};
|
|
254
|
+
function refreshState(env) {
|
|
255
|
+
return refreshDisabled(env) ? `off (${MANIFEST_REFRESH_ENV}=${env[MANIFEST_REFRESH_ENV]})` : 'on';
|
|
256
|
+
}
|
|
249
257
|
//# sourceMappingURL=tools.js.map
|