@martini-film/cli 0.1.0 → 0.3.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.
@@ -1,17 +1,3 @@
1
- /**
2
- * `martini files`: the project's memory files as a directory.
3
- *
4
- * ls list_project_files
5
- * cat <path> read_project_file (content to stdout)
6
- * write <path> [@file|-] write_project_file (replace; --append; --create-only)
7
- * pull <dir> every file to disk plus .martini/files.json (path → updatedAt)
8
- * push <dir> changed files back, each guarded by expectedUpdatedAt from the
9
- * manifest: a file edited server-side since the pull is refused
10
- * (PROJECT_FILE_CHANGED) unless --force. Never deletes.
11
- *
12
- * project.md is human-owned and Instructions files are read-only during a run;
13
- * the server refuses them and push reports them as skipped.
14
- */
15
1
  import { createHash } from 'node:crypto';
16
2
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
17
3
  import { dirname, join, relative, resolve, sep } from 'node:path';
@@ -33,8 +19,25 @@ function readContentArgument(raw) {
33
19
  return raw;
34
20
  }
35
21
  async function listFiles(context, projectId) {
36
- const result = await context.client.callTool('list_project_files', { projectId });
37
- return result.files ?? [];
22
+ const files = [];
23
+ let after;
24
+ for (;;) {
25
+ const page = await context.client.callTool('list_project_files', {
26
+ projectId,
27
+ ...(after === undefined ? {} : { after }),
28
+ });
29
+ files.push(...(page.files ?? []));
30
+ if (typeof page.nextAfter !== 'string' || page.nextAfter === '')
31
+ return files;
32
+ if (page.nextAfter === after) {
33
+ throw new CliApiError(`list_project_files answered the same nextAfter twice (${after}); the listing is incomplete.`, {
34
+ code: 'INVALID_RESPONSE',
35
+ status: 0,
36
+ tool: 'list_project_files',
37
+ });
38
+ }
39
+ after = page.nextAfter;
40
+ }
38
41
  }
39
42
  function walk(dir, root = dir) {
40
43
  const out = [];
@@ -49,103 +52,140 @@ function walk(dir, root = dir) {
49
52
  }
50
53
  return out;
51
54
  }
55
+ function shellQuote(value) {
56
+ return /^[A-Za-z0-9._\/-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
57
+ }
52
58
  export const files = {
53
59
  name: 'files',
54
60
  summary: 'Project memory files: ls, cat, write, pull <dir>, push <dir>',
55
61
  usage: 'martini files ls | cat <path> | write <path> <content|@file|-> [--append|--create-only] | pull <dir> | push <dir> [--force]',
62
+ details: "The project's memory files as a directory. pull writes every file plus .martini/files.json (path → updatedAt, sha256); push sends only changed files, each guarded by expectedUpdatedAt, and refuses one edited server-side since the pull (PROJECT_FILE_CHANGED, reported under skipped) unless --force. project.md and Instructions files are read-only during a run and come back as skipped. Nothing is ever deleted. cat prints the raw content, not JSON.",
63
+ positionals: [
64
+ {
65
+ name: 'ls | cat <path> | write <path> <content|@file|-> | pull <dir> | push <dir>',
66
+ description: 'The subcommand',
67
+ required: true,
68
+ },
69
+ ],
70
+ flags: [
71
+ { flag: 'append', kind: 'boolean', description: 'write: append to the file instead of replacing it' },
72
+ { flag: 'create-only', kind: 'boolean', description: 'write: fail when the file already exists' },
73
+ {
74
+ flag: 'force',
75
+ kind: 'boolean',
76
+ description: 'push: overwrite files changed server-side since the pull, and files that appeared meanwhile',
77
+ },
78
+ ],
79
+ examples: [
80
+ 'martini files cat notes.md',
81
+ 'martini files write notes.md @notes.md',
82
+ 'martini files pull ./memory && martini files push ./memory',
83
+ ],
56
84
  async run(context) {
57
85
  const [sub, ...rest] = context.positionals;
58
86
  const projectId = requireProject(context);
59
- switch (sub) {
60
- case 'ls': {
61
- return { projectId, files: await listFiles(context, projectId) };
62
- }
63
- case 'cat': {
64
- const path = rest[0];
65
- if (!path)
66
- throw new ArgumentError('martini files cat <path>');
67
- const file = await context.client.callTool('read_project_file', { projectId, path });
68
- return file.content;
69
- }
70
- case 'write': {
71
- const path = rest[0];
72
- if (!path)
73
- throw new ArgumentError('martini files write <path> <content|@file|->');
74
- const content = readContentArgument(rest[1]);
75
- return context.client.callTool('write_project_file', {
76
- projectId,
77
- path,
78
- content,
79
- ...(flagBoolean(context.flags, 'append') ? { append: true } : {}),
80
- ...(flagBoolean(context.flags, 'create-only') ? { createOnly: true } : {}),
81
- });
82
- }
83
- case 'pull': {
84
- const dir = resolve(context.cwd, rest[0] ?? '.');
85
- const listed = await listFiles(context, projectId);
86
- const manifest = { projectId, pulledAt: new Date(context.now()).toISOString(), files: {} };
87
- for (const entry of listed) {
88
- const file = await context.client.callTool('read_project_file', {
89
- projectId,
90
- path: entry.path,
91
- });
92
- const target = join(dir, ...entry.path.split('/'));
93
- mkdirSync(dirname(target), { recursive: true });
94
- writeFileSync(target, file.content);
95
- manifest.files[entry.path] = { updatedAt: file.updatedAt, sha256: sha256(file.content) };
87
+ try {
88
+ switch (sub) {
89
+ case 'ls': {
90
+ return { projectId, files: await listFiles(context, projectId) };
96
91
  }
97
- mkdirSync(join(dir, '.martini'), { recursive: true });
98
- writeFileSync(join(dir, FILES_MANIFEST), JSON.stringify(manifest, null, 2) + '\n');
99
- return { projectId, dir, pulled: Object.keys(manifest.files).length, manifest: join(dir, FILES_MANIFEST) };
100
- }
101
- case 'push': {
102
- const dir = resolve(context.cwd, rest[0] ?? '.');
103
- const manifestPath = join(dir, FILES_MANIFEST);
104
- if (!existsSync(manifestPath)) {
105
- throw new ArgumentError(`${dir} was not pulled with martini files pull (no ${FILES_MANIFEST}); pull first so pushes can detect concurrent edits.`);
92
+ case 'cat': {
93
+ const path = rest[0];
94
+ if (!path)
95
+ throw new ArgumentError('martini files cat <path>');
96
+ const file = await context.client.callTool('read_project_file', { projectId, path });
97
+ return file.content;
106
98
  }
107
- const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
108
- if (manifest.projectId !== projectId) {
109
- throw new ArgumentError(`${dir} was pulled from project ${manifest.projectId}, not ${projectId}.`);
99
+ case 'write': {
100
+ const path = rest[0];
101
+ if (!path)
102
+ throw new ArgumentError('martini files write <path> <content|@file|->');
103
+ const content = readContentArgument(rest[1]);
104
+ return context.client.callTool('write_project_file', {
105
+ projectId,
106
+ path,
107
+ content,
108
+ ...(flagBoolean(context.flags, 'append') ? { append: true } : {}),
109
+ ...(flagBoolean(context.flags, 'create-only') ? { createOnly: true } : {}),
110
+ });
110
111
  }
111
- const force = flagBoolean(context.flags, 'force') ?? false;
112
- const pushed = [];
113
- const unchanged = [];
114
- const skipped = [];
115
- for (const path of walk(dir)) {
116
- const abs = join(dir, ...path.split('/'));
117
- if (!statSync(abs).isFile())
118
- continue;
119
- const content = readFileSync(abs, 'utf8');
120
- const known = manifest.files[path];
121
- if (known && known.sha256 === sha256(content)) {
122
- unchanged.push(path);
123
- continue;
124
- }
125
- try {
126
- const written = await context.client.callTool('write_project_file', {
112
+ case 'pull': {
113
+ const dir = resolve(context.cwd, rest[0] ?? '.');
114
+ const listed = await listFiles(context, projectId);
115
+ const manifest = { projectId, pulledAt: new Date(context.now()).toISOString(), files: {} };
116
+ for (const entry of listed) {
117
+ const file = await context.client.callTool('read_project_file', {
127
118
  projectId,
128
- path,
129
- content,
130
- ...(known && !force ? { expectedUpdatedAt: known.updatedAt } : {}),
119
+ path: entry.path,
131
120
  });
132
- manifest.files[path] = { updatedAt: written.updatedAt, sha256: sha256(content) };
133
- pushed.push(path);
121
+ const target = join(dir, ...entry.path.split('/'));
122
+ mkdirSync(dirname(target), { recursive: true });
123
+ writeFileSync(target, file.content);
124
+ manifest.files[entry.path] = { updatedAt: file.updatedAt, sha256: sha256(file.content) };
125
+ }
126
+ mkdirSync(join(dir, '.martini'), { recursive: true });
127
+ writeFileSync(join(dir, FILES_MANIFEST), JSON.stringify(manifest, null, 2) + '\n');
128
+ return { projectId, dir, pulled: Object.keys(manifest.files).length, manifest: join(dir, FILES_MANIFEST) };
129
+ }
130
+ case 'push': {
131
+ const dir = resolve(context.cwd, rest[0] ?? '.');
132
+ const manifestPath = join(dir, FILES_MANIFEST);
133
+ if (!existsSync(manifestPath)) {
134
+ throw new ArgumentError(`${dir} was not pulled with martini files pull (no ${FILES_MANIFEST}); pull first so pushes can detect concurrent edits.`);
135
+ }
136
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
137
+ if (manifest.projectId !== projectId) {
138
+ throw new ArgumentError(`${dir} was pulled from project ${manifest.projectId}, not ${projectId}.`);
134
139
  }
135
- catch (error) {
136
- if (error instanceof CliApiError && error.status < 500) {
137
- skipped.push({ path, code: error.code, error: error.message });
140
+ const force = flagBoolean(context.flags, 'force') ?? false;
141
+ const pushed = [];
142
+ const unchanged = [];
143
+ const skipped = [];
144
+ for (const path of walk(dir)) {
145
+ const abs = join(dir, ...path.split('/'));
146
+ if (!statSync(abs).isFile())
138
147
  continue;
148
+ const content = readFileSync(abs, 'utf8');
149
+ const known = manifest.files[path];
150
+ if (known && known.sha256 === sha256(content)) {
151
+ unchanged.push(path);
152
+ continue;
153
+ }
154
+ try {
155
+ const written = await context.client.callTool('write_project_file', {
156
+ projectId,
157
+ path,
158
+ content,
159
+ ...(!force ? (known ? { expectedUpdatedAt: known.updatedAt } : { createOnly: true }) : {}),
160
+ });
161
+ manifest.files[path] = { updatedAt: written.updatedAt, sha256: sha256(content) };
162
+ pushed.push(path);
163
+ }
164
+ catch (error) {
165
+ if (error instanceof CliApiError && error.status < 500) {
166
+ skipped.push({ path, code: error.code, error: error.message });
167
+ continue;
168
+ }
169
+ throw error;
139
170
  }
140
- throw error;
141
171
  }
172
+ manifest.pulledAt = new Date(context.now()).toISOString();
173
+ writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
174
+ return { projectId, dir, pushed, unchanged: unchanged.length, skipped };
142
175
  }
143
- manifest.pulledAt = new Date(context.now()).toISOString();
144
- writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
145
- return { projectId, dir, pushed, unchanged: unchanged.length, skipped };
176
+ default:
177
+ throw new ArgumentError('martini files <ls | cat | write | pull | push>');
178
+ }
179
+ }
180
+ catch (error) {
181
+ if (sub === 'cat' &&
182
+ rest[0]?.startsWith('tools/') &&
183
+ error instanceof CliApiError &&
184
+ (/No project file|(?:file.*not found|not found.*file)|invalid.*path|path.*invalid|^File paths are relative|^The file path (?:is empty|is longer than|has more than)/i.test(error.message) ||
185
+ /^(?:PROJECT_FILE_NOT_FOUND|FILE_NOT_FOUND|NOT_FOUND|INVALID_PATH|INVALID_PROJECT_FILE_PATH)$/.test(error.code))) {
186
+ error.message += `\nKit files are not project files. Read them from the workflow's tools library in two steps: martini get_workflow_authoring --project ${projectId} --workflow-id <workflow-id> --sections workflow (read baseline.toolBundle.sha256), then martini get_workflow_authoring --project ${projectId} --workflow-id <workflow-id> --file-path=${shellQuote(rest[0].replace(/^tools\//, ''))} --expected-bundle-sha256 <that sha> (the workflow id comes from martini list_saved_workflows --project ${projectId}).`;
146
187
  }
147
- default:
148
- throw new ArgumentError('martini files <ls | cat | write | pull | push>');
188
+ throw error;
149
189
  }
150
190
  },
151
191
  };
@@ -1 +1 @@
1
- {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/commands/files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/commands/files.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACnG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,cAAc,EAA6C,MAAM,cAAc,CAAA;AAExF,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;AAc5D,SAAS,MAAM,CAAC,OAAe;IAC7B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC3D,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAuB;IAClD,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,aAAa,CAAC,qDAAqD,CAAC,CAAA;IACrG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IAC/C,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IAClE,OAAO,GAAG,CAAA;AACZ,CAAC;AAMD,KAAK,UAAU,SAAS,CAAC,OAAuB,EAAE,SAAiB;IACjE,MAAM,KAAK,GAAiB,EAAE,CAAA;IAC9B,IAAI,KAAyB,CAAA;IAC7B,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgD,oBAAoB,EAAE;YAC9G,SAAS;YACT,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;SAC1C,CAAC,CAAA;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAA;QACjC,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE;YAAE,OAAO,KAAK,CAAA;QAE7E,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC7B,MAAM,IAAI,WAAW,CACnB,yDAAyD,KAAK,+BAA+B,EAC7F;gBACE,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,CAAC;gBACT,IAAI,EAAE,oBAAoB;aAC3B,CACF,CAAA;QACH,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,SAAS,CAAA;IACxB,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,GAAW,EAAE,IAAI,GAAG,GAAG;IACnC,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QACrE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;aAChD,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAGD,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAA;AACxF,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAoB;IACpC,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,8DAA8D;IACvE,KAAK,EACH,6HAA6H;IAC/H,OAAO,EACL,icAAic;IACnc,WAAW,EAAE;QACX;YACE,IAAI,EAAE,4EAA4E;YAClF,WAAW,EAAE,gBAAgB;YAC7B,QAAQ,EAAE,IAAI;SACf;KACF;IACD,KAAK,EAAE;QACL,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,mDAAmD,EAAE;QACrG,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,0CAA0C,EAAE;QACjG;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,6FAA6F;SAC3G;KACF;IACD,QAAQ,EAAE;QACR,4BAA4B;QAC5B,wCAAwC;QACxC,4DAA4D;KAC7D;IACD,KAAK,CAAC,GAAG,CAAC,OAAuB;QAC/B,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,WAAW,CAAA;QAC1C,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACzC,IAAI,CAAC;YACH,QAAQ,GAAG,EAAE,CAAC;gBACZ,KAAK,IAAI,CAAC,CAAC,CAAC;oBACV,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAA;gBAClE,CAAC;gBACD,KAAK,KAAK,CAAC,CAAC,CAAC;oBACX,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;oBACpB,IAAI,CAAC,IAAI;wBAAE,MAAM,IAAI,aAAa,CAAC,0BAA0B,CAAC,CAAA;oBAC9D,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB,mBAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;oBACzG,OAAO,IAAI,CAAC,OAAO,CAAA;gBACrB,CAAC;gBACD,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;oBACpB,IAAI,CAAC,IAAI;wBAAE,MAAM,IAAI,aAAa,CAAC,8CAA8C,CAAC,CAAA;oBAClF,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;oBAC5C,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE;wBACnD,SAAS;wBACT,IAAI;wBACJ,OAAO;wBACP,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjE,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAC3E,CAAC,CAAA;gBACJ,CAAC;gBACD,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAA;oBAChD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;oBAClD,MAAM,QAAQ,GAAiB,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;oBACxG,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBAC3B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAyC,mBAAmB,EAAE;4BACtG,SAAS;4BACT,IAAI,EAAE,KAAK,CAAC,IAAI;yBACjB,CAAC,CAAA;wBACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;wBAClD,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;wBAC/C,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;wBACnC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;oBAC1F,CAAC;oBACD,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;oBACrD,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;oBAClF,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,CAAA;gBAC5G,CAAC;gBACD,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAA;oBAChD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;oBAC9C,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;wBAC9B,MAAM,IAAI,aAAa,CACrB,GAAG,GAAG,+CAA+C,cAAc,sDAAsD,CAC1H,CAAA;oBACH,CAAC;oBACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAiB,CAAA;oBAC/E,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;wBACrC,MAAM,IAAI,aAAa,CAAC,GAAG,GAAG,4BAA4B,QAAQ,CAAC,SAAS,SAAS,SAAS,GAAG,CAAC,CAAA;oBACpG,CAAC;oBACD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,KAAK,CAAA;oBAC1D,MAAM,MAAM,GAAa,EAAE,CAAA;oBAC3B,MAAM,SAAS,GAAa,EAAE,CAAA;oBAC9B,MAAM,OAAO,GAAyD,EAAE,CAAA;oBACxE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;wBACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE;4BAAE,SAAQ;wBACrC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;wBACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;wBAClC,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;4BAC9C,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;4BACpB,SAAQ;wBACV,CAAC;wBACD,IAAI,CAAC;4BACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAwB,oBAAoB,EAAE;gCACzF,SAAS;gCACT,IAAI;gCACJ,OAAO;gCACP,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;6BAC3F,CAAC,CAAA;4BACF,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAA;4BAChF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;wBACnB,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,IAAI,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gCACvD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gCAC9D,SAAQ;4BACV,CAAC;4BACD,MAAM,KAAK,CAAA;wBACb,CAAC;oBACH,CAAC;oBACD,QAAQ,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;oBACzD,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;oBACrE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAA;gBACzE,CAAC;gBACD;oBACE,MAAM,IAAI,aAAa,CAAC,gDAAgD,CAAC,CAAA;YAC7E,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IACE,GAAG,KAAK,KAAK;gBACb,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC;gBAC7B,KAAK,YAAY,WAAW;gBAI5B,CAAC,oKAAoK,CAAC,IAAI,CACxK,KAAK,CAAC,OAAO,CACd;oBACC,8FAA8F,CAAC,IAAI,CACjG,KAAK,CAAC,IAAI,CACX,CAAC,EACJ,CAAC;gBACD,KAAK,CAAC,OAAO,IAAI,yIAAyI,SAAS,qIAAqI,SAAS,4CAA4C,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,2GAA2G,SAAS,IAAI,CAAA;YAClgB,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;CACF,CAAA"}
@@ -1,70 +1,198 @@
1
+ import { existsSync, mkdirSync, unlinkSync, writeFileSync } from 'node:fs';
1
2
  import { hostname } from 'node:os';
3
+ import { dirname, join } from 'node:path';
2
4
  import { CliApiError } from '../api.js';
3
5
  import { flagBoolean, flagString } from '../args.js';
4
- import { removeProfile, saveProfile } from '../config.js';
6
+ import { readJsonFile, removeProfile, saveProfile, userConfigPath } from '../config.js';
5
7
  import { detectHostAgent } from '../host.js';
8
+ import { timeoutMs, wantsWait } from './context.js';
6
9
  export function defaultDeviceLabel(env = process.env) {
7
10
  const host = detectHostAgent(env);
8
11
  return `${hostname()}${host ? ` (${host})` : ''}`;
9
12
  }
10
- /**
11
- * `martini login`: device-code pairing. Prints a code and a URL; the person
12
- * types the code in the signed-in app; the poll collects the minted key and
13
- * saves it as a profile named after the organization.
14
- */
13
+ export function pendingLoginPath(env = process.env) {
14
+ return join(dirname(userConfigPath(env)), 'login-pending.json');
15
+ }
16
+ function readPendingLogin(env, apiUrl, now) {
17
+ const pending = readJsonFile(pendingLoginPath(env));
18
+ if (!pending || pending.apiUrl !== apiUrl || typeof pending.pollToken !== 'string')
19
+ return null;
20
+ if (new Date(pending.expiresAt).getTime() <= now) {
21
+ clearPendingLogin(env);
22
+ return null;
23
+ }
24
+ return pending;
25
+ }
26
+ function writePendingLogin(env, pending) {
27
+ const path = pendingLoginPath(env);
28
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
29
+ writeFileSync(path, JSON.stringify(pending, null, 2) + '\n', { mode: 0o600 });
30
+ }
31
+ function clearPendingLogin(env) {
32
+ const path = pendingLoginPath(env);
33
+ if (existsSync(path))
34
+ unlinkSync(path);
35
+ }
36
+ export const ACCOUNT_PROFILE_NAME = 'account';
37
+ export function profileNameFor(organizationName, organizationId, existing) {
38
+ if (organizationId === null) {
39
+ const profiles = existing?.profiles ?? {};
40
+ const reusable = (name) => !profiles[name] || profiles[name]?.scope === 'user';
41
+ if (reusable(ACCOUNT_PROFILE_NAME))
42
+ return ACCOUNT_PROFILE_NAME;
43
+ for (let n = 2;; n += 1) {
44
+ const candidate = `${ACCOUNT_PROFILE_NAME}-${n}`;
45
+ if (reusable(candidate))
46
+ return candidate;
47
+ }
48
+ }
49
+ const slug = (organizationName ?? '')
50
+ .toLowerCase()
51
+ .replace(/[^a-z0-9]+/g, '-')
52
+ .replace(/^-+|-+$/g, '');
53
+ if (!slug)
54
+ return organizationId;
55
+ const taken = existing?.profiles?.[slug];
56
+ if (taken?.organizationId && taken.organizationId !== organizationId)
57
+ return `${slug}-${organizationId.slice(0, 8)}`;
58
+ return slug;
59
+ }
15
60
  export const login = {
16
61
  name: 'login',
17
62
  summary: 'Sign in: pair this device through the browser and save a 90-day key',
18
- usage: 'martini login [--device <label>] [--profile <name>] [--no-default]',
63
+ usage: 'martini login [--device <label>] [--profile <name>] [--no-default] [--no-wait] [--timeout <seconds>]',
64
+ 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. An agent therefore runs martini login --no-wait, tells the person the code, and runs martini login again once they have approved.',
65
+ flags: [
66
+ {
67
+ flag: 'device',
68
+ kind: 'string',
69
+ value: '<label>',
70
+ description: 'How this device is listed under Settings → Martini API (default: the hostname, plus the host agent when known)',
71
+ },
72
+ {
73
+ flag: 'profile',
74
+ kind: 'string',
75
+ value: '<name>',
76
+ description: "Save the key under this name instead of the organization's",
77
+ },
78
+ { flag: 'default', kind: 'boolean', description: '--no-default keeps the current default profile' },
79
+ ],
80
+ examples: [
81
+ 'martini login',
82
+ 'martini login --no-wait # print the code and return; run martini login again after approval',
83
+ 'martini login --profile studio --no-default',
84
+ ],
19
85
  async run(context) {
20
- const deviceLabel = flagString(context.flags, 'device') ?? defaultDeviceLabel(context.env);
21
- const started = await context.client.startLogin(deviceLabel);
86
+ const env = context.env;
87
+ const apiUrl = context.config.apiUrl;
22
88
  const stderr = context.output.stderr ?? (text => process.stderr.write(text));
23
- stderr([
24
- '',
25
- ` Open ${started.verificationUrl}`,
26
- ` and enter the code ${started.code}`,
27
- '',
28
- ` Waiting for approval (expires ${started.expiresAt})…`,
29
- '',
30
- ].join('\n'));
31
- const deadline = new Date(started.expiresAt).getTime();
89
+ let pending = readPendingLogin(env, apiUrl, context.now());
90
+ if (pending) {
91
+ stderr([
92
+ '',
93
+ ` Resuming the pairing started ${pending.startedAt}:`,
94
+ ` open ${pending.verificationUrl}`,
95
+ ` and enter the code ${pending.code}`,
96
+ '',
97
+ ].join('\n'));
98
+ }
99
+ else {
100
+ const deviceLabel = flagString(context.flags, 'device') ?? defaultDeviceLabel(env);
101
+ const started = await context.client.startLogin(deviceLabel);
102
+ pending = {
103
+ apiUrl,
104
+ code: started.code,
105
+ pollToken: started.pollToken,
106
+ verificationUrl: started.verificationUrl,
107
+ expiresAt: started.expiresAt,
108
+ intervalSec: started.interval,
109
+ deviceLabel,
110
+ startedAt: new Date(context.now()).toISOString(),
111
+ };
112
+ writePendingLogin(env, pending);
113
+ stderr(['', ` Open ${started.verificationUrl}`, ` and enter the code ${started.code}`, ''].join('\n'));
114
+ }
115
+ if (!wantsWait(context, true)) {
116
+ return {
117
+ status: 'pending',
118
+ code: pending.code,
119
+ verificationUrl: pending.verificationUrl,
120
+ expiresAt: pending.expiresAt,
121
+ next: 'Approve the code in the browser, then run martini login again to collect the key.',
122
+ };
123
+ }
124
+ stderr(` Waiting for approval (until ${pending.expiresAt}; if this is interrupted, martini login resumes it)…\n\n`);
125
+ const expiry = new Date(pending.expiresAt).getTime();
126
+ const budget = flagString(context.flags, 'timeout') === undefined ? Infinity : context.now() + timeoutMs(context);
127
+ const intervalMs = Math.max(1000, (pending.intervalSec || 3) * 1000);
32
128
  for (;;) {
33
- await context.sleep(Math.max(1000, started.interval * 1000));
34
- const polled = await context.client.pollLogin(started.pollToken);
129
+ if (context.now() >= budget) {
130
+ throw new CliApiError('Still waiting for the login to be approved in the browser.', {
131
+ code: 'LOGIN_PENDING',
132
+ status: 0,
133
+ });
134
+ }
135
+ await context.sleep(intervalMs);
136
+ const polled = await context.client.pollLogin(pending.pollToken);
35
137
  if (polled.status === 'pending') {
36
- if (context.now() > deadline)
138
+ if (context.now() > expiry) {
139
+ clearPendingLogin(env);
37
140
  throw new CliApiError('The login request expired before it was approved.', {
38
141
  code: 'LOGIN_EXPIRED',
39
142
  status: 0,
40
143
  });
144
+ }
41
145
  continue;
42
146
  }
43
- if (polled.status === 'denied')
147
+ if (polled.status === 'denied') {
148
+ clearPendingLogin(env);
44
149
  throw new CliApiError('The login was denied in the browser.', { code: 'LOGIN_DENIED', status: 0 });
45
- if (polled.status === 'expired')
150
+ }
151
+ if (polled.status === 'expired') {
152
+ clearPendingLogin(env);
46
153
  throw new CliApiError('The login request expired. Run martini login again.', {
47
154
  code: 'LOGIN_EXPIRED',
48
155
  status: 0,
49
156
  });
50
- if (polled.status === 'claimed')
157
+ }
158
+ if (polled.status === 'claimed') {
159
+ clearPendingLogin(env);
51
160
  throw new CliApiError('This login was already collected elsewhere. Run martini login again.', {
52
161
  code: 'LOGIN_CLAIMED',
53
162
  status: 0,
54
163
  });
164
+ }
55
165
  if (polled.status !== 'approved')
56
166
  continue;
57
- const profileName = flagString(context.flags, 'profile') ?? polled.organizationId;
167
+ const scope = polled.scope ?? (polled.organizationId === null ? 'user' : 'organization');
168
+ const organizationId = scope === 'user' ? null : polled.organizationId;
169
+ const me = scope === 'organization'
170
+ ? await context
171
+ .clientFor({ ...context.config, apiKey: polled.key })
172
+ .me()
173
+ .catch(() => null)
174
+ : null;
175
+ const organizationName = me?.organization?.name ?? null;
176
+ const profileName = flagString(context.flags, 'profile') ??
177
+ profileNameFor(organizationName, organizationId, readJsonFile(userConfigPath(env)));
58
178
  const path = saveProfile(profileName, {
59
179
  apiKey: polled.key,
60
- apiUrl: context.config.apiUrl,
61
- organizationId: polled.organizationId,
180
+ apiUrl,
181
+ scope,
182
+ ...(organizationId ? { organizationId } : {}),
183
+ ...(organizationName ? { organizationName } : {}),
62
184
  ...(polled.expiresAt ? { expiresAt: polled.expiresAt } : {}),
63
- }, { env: context.env, makeDefault: flagBoolean(context.flags, 'default') ?? true });
185
+ }, { env, makeDefault: flagBoolean(context.flags, 'default') ?? true });
186
+ clearPendingLogin(env);
187
+ if (scope === 'user') {
188
+ stderr(' This key acts in every organization you belong to. --project decides where work lands and who is billed; create_project makes a personal project unless --team-id is given.\n\n');
189
+ }
64
190
  return {
65
191
  ok: true,
66
192
  profile: profileName,
67
- organizationId: polled.organizationId,
193
+ scope,
194
+ organizationId,
195
+ organizationName,
68
196
  keyId: polled.keyId,
69
197
  expiresAt: polled.expiresAt,
70
198
  savedTo: path,
@@ -76,6 +204,14 @@ export const logout = {
76
204
  name: 'logout',
77
205
  summary: 'Forget a saved profile (the key itself is revoked from Settings → Martini API)',
78
206
  usage: 'martini logout [--profile <name>]',
207
+ flags: [
208
+ {
209
+ flag: 'profile',
210
+ kind: 'string',
211
+ value: '<name>',
212
+ description: 'The profile to forget (default: the active one)',
213
+ },
214
+ ],
79
215
  async run(context) {
80
216
  const name = flagString(context.flags, 'profile');
81
217
  if (!name) {
@@ -90,18 +226,23 @@ export const logout = {
90
226
  };
91
227
  export const whoami = {
92
228
  name: 'whoami',
93
- summary: 'Which organization and key this CLI acts as, and where the config came from',
229
+ summary: 'Which key this CLI acts as — its scope, organization, and your memberships — and where the config came from',
94
230
  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.',
95
232
  async run(context) {
96
233
  const me = await context.client.me();
97
234
  return {
235
+ scope: me.scope,
98
236
  organization: me.organization,
237
+ organizations: me.organizations,
99
238
  key: me.key,
100
239
  apiVersion: me.apiVersion,
101
240
  apiUrl: context.config.apiUrl,
102
241
  projectId: context.config.projectId ?? null,
103
242
  canvasId: context.config.canvasId ?? null,
104
243
  runId: context.config.runId ?? null,
244
+ executionId: context.config.executionId ?? null,
245
+ workerId: context.config.workerId ?? null,
105
246
  configSource: context.config.source,
106
247
  };
107
248
  },
@@ -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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"}