@somewhere-tech/cli 0.27.7 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/commands/advisor.js +2 -67
- package/dist/commands/advisor.js.map +1 -1
- package/dist/commands/call.js +62 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/feedback.js +75 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/git.js +265 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/grep.js +55 -0
- package/dist/commands/grep.js.map +1 -0
- package/dist/commands/mcp.js +10 -41
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/status.js +36 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tasks.js +195 -0
- package/dist/commands/tasks.js.map +1 -0
- package/dist/commands/usage.js +46 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/platform-command.js +32 -0
- package/dist/lib/platform-command.js.map +1 -0
- package/dist/lib/platform-tools.js +163 -0
- package/dist/lib/platform-tools.js.map +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,6 +48,9 @@ After `somewhere init`, Claude Code and Codex auto-connect via the `.mcp.json` i
|
|
|
48
48
|
| `somewhere deploy --dry-run` | Preview the deploy diff without shipping |
|
|
49
49
|
| `somewhere deploy --scope functions` | Deploy backend only (leave the site untouched) |
|
|
50
50
|
| `somewhere deploy --force` | Intentionally overwrite remote changes made since this machine last deployed |
|
|
51
|
+
| `somewhere git connect [owner/repo]` | Install/authorize the GitHub App if needed, deploy repository HEAD, then deploy every push |
|
|
52
|
+
| `somewhere git status` | Show connected repo, commit, deploy status, logs link, and live URL |
|
|
53
|
+
| `somewhere git disconnect` | Stop push-to-deploy; the currently deployed site stays live |
|
|
51
54
|
| `somewhere pull` | Download a project's live deployed source + scaffold tsconfig/package.json for local typechecking |
|
|
52
55
|
| `somewhere typecheck` | Loads the pulled `tsconfig.json` explicitly (equivalent to project-wide `tsc --noEmit`) — catches a dropped import (TS2304) with file:line; do not append source-file args, which bypass the project config |
|
|
53
56
|
| `somewhere logs` | Show recent logs |
|
|
@@ -159,6 +162,23 @@ To exclude local-only files from deploy, add gitignore-style patterns to `.somew
|
|
|
159
162
|
|
|
160
163
|
After each successful linked deploy or pull, the CLI records the current deployed version in `.somewhere.json`. If the project changed elsewhere since that version, the next deploy refuses before overwriting anything and names the changed files. Run `somewhere pull` to bring remote source back locally, or `somewhere deploy --force --yes` to overwrite intentionally.
|
|
161
164
|
|
|
165
|
+
## GitHub push-to-deploy
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
somewhere git connect owner/repo
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The CLI uses the GitHub App, not a pasted personal access token. It opens
|
|
172
|
+
GitHub only when the account or repository still needs authorization, resumes
|
|
173
|
+
automatically, deploys the repository's default-branch HEAD immediately, and
|
|
174
|
+
waits for that exact commit before printing its status, logs link, and live
|
|
175
|
+
URL. Later pushes to the connected branch deploy automatically.
|
|
176
|
+
|
|
177
|
+
Use `--project <id-or-slug>` outside a linked directory, `--branch <name>` for
|
|
178
|
+
a non-default branch, and `--root <directory>` for a monorepo app. `connect`,
|
|
179
|
+
`status`, and `disconnect` support `--json`. Disconnecting stops future GitHub
|
|
180
|
+
deploys but does not undeploy the current site.
|
|
181
|
+
|
|
162
182
|
### Deploy options
|
|
163
183
|
|
|
164
184
|
| Flag | What it does |
|
package/dist/commands/advisor.js
CHANGED
|
@@ -1,71 +1,6 @@
|
|
|
1
|
-
import { ApiClient } from '../lib/client.js';
|
|
2
|
-
import { getToken } from '../lib/config.js';
|
|
3
1
|
import { error, printJson } from '../lib/output.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
const parsed = JSON.parse(text);
|
|
8
|
-
const message = typeof parsed.message === 'string' ? parsed.message : text;
|
|
9
|
-
return typeof parsed.error === 'string' ? `${parsed.error}: ${message}` : message;
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return text;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
async function callPlatformHelpToolWithToken(name, args, token) {
|
|
16
|
-
const [{ Client }, { StreamableHTTPClientTransport }] = await Promise.all([
|
|
17
|
-
import('@modelcontextprotocol/sdk/client/index.js'),
|
|
18
|
-
import('@modelcontextprotocol/sdk/client/streamableHttp.js'),
|
|
19
|
-
]);
|
|
20
|
-
const client = new Client({ name: 'somewhere-cli', version: 'unknown' });
|
|
21
|
-
const transport = new StreamableHTTPClientTransport(new URL(MCP_URL), {
|
|
22
|
-
requestInit: {
|
|
23
|
-
headers: {
|
|
24
|
-
Authorization: `Bearer ${token}`,
|
|
25
|
-
'User-Agent': 'somewhere-cli',
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
try {
|
|
30
|
-
await client.connect(transport);
|
|
31
|
-
const result = await client.callTool({ name, arguments: args });
|
|
32
|
-
if (!('content' in result) || !Array.isArray(result.content)) {
|
|
33
|
-
throw new Error(`${name} returned an unexpected response.`);
|
|
34
|
-
}
|
|
35
|
-
const text = result.content
|
|
36
|
-
.filter((block) => block.type === 'text')
|
|
37
|
-
.map((block) => block.text)
|
|
38
|
-
.join('\n');
|
|
39
|
-
if (result.isError)
|
|
40
|
-
throw new Error(toolErrorMessage(text));
|
|
41
|
-
if (!text)
|
|
42
|
-
throw new Error(`${name} returned an empty response.`);
|
|
43
|
-
return text;
|
|
44
|
-
}
|
|
45
|
-
finally {
|
|
46
|
-
await client.close().catch(() => { });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
/** Call the authoritative MCP-native help surface. Catalog and docs are built
|
|
50
|
-
* inside mcp.somewhere.tech (they do not have /v1 REST mirrors), and advisor
|
|
51
|
-
* is executed there after the caller's stored developer key is verified. */
|
|
52
|
-
export async function callPlatformHelpTool(name, args) {
|
|
53
|
-
const token = getToken();
|
|
54
|
-
try {
|
|
55
|
-
return await callPlatformHelpToolWithToken(name, args, token);
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
const { StreamableHTTPError } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
59
|
-
if (!(err instanceof StreamableHTTPError) || err.code !== 401)
|
|
60
|
-
throw err;
|
|
61
|
-
// MCP uses the same developer key as the REST API, but it is not routed
|
|
62
|
-
// through ApiClient. Probe the normal authenticated path so ApiClient can
|
|
63
|
-
// perform its existing refresh-on-API_KEY_EXPIRED flow and persist the
|
|
64
|
-
// rotated pair, then retry this MCP call exactly once with the fresh key.
|
|
65
|
-
await new ApiClient(token).call('GET', '/auth/whoami');
|
|
66
|
-
return await callPlatformHelpToolWithToken(name, args, getToken());
|
|
67
|
-
}
|
|
68
|
-
}
|
|
2
|
+
import { callPlatformHelpTool } from '../lib/platform-tools.js';
|
|
3
|
+
export { callPlatformHelpTool };
|
|
69
4
|
export function registerAdvisor(program) {
|
|
70
5
|
program
|
|
71
6
|
.command('advisor <question>')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advisor.js","sourceRoot":"","sources":["../../src/commands/advisor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"advisor.js","sourceRoot":"","sources":["../../src/commands/advisor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,QAAQ,EAAE,+CAA+C,CAAC;SACjE,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,IAAwB,EAAE,EAAE;QAC3D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YACnE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACxD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { callPlatformTool, listPlatformTools } from '../lib/platform-tools.js';
|
|
2
|
+
import { error, printJson } from '../lib/output.js';
|
|
3
|
+
import { isRecord } from '../lib/platform-command.js';
|
|
4
|
+
function parseArguments(value) {
|
|
5
|
+
if (value === undefined)
|
|
6
|
+
return {};
|
|
7
|
+
let parsed;
|
|
8
|
+
try {
|
|
9
|
+
parsed = JSON.parse(value);
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
throw new Error(`Arguments must be valid JSON. ${err instanceof Error ? err.message : String(err)}`);
|
|
13
|
+
}
|
|
14
|
+
if (!isRecord(parsed)) {
|
|
15
|
+
throw new Error('Arguments must be a JSON object, for example: \'{"project_id":"default"}\'.');
|
|
16
|
+
}
|
|
17
|
+
return parsed;
|
|
18
|
+
}
|
|
19
|
+
export function registerCall(program) {
|
|
20
|
+
program
|
|
21
|
+
.command('call [tool] [json]')
|
|
22
|
+
.description('Invoke any platform tool by name with JSON arguments')
|
|
23
|
+
.option('--list', 'List every available platform tool and its input schema')
|
|
24
|
+
.option('--json', 'Print stable JSON output')
|
|
25
|
+
.action(async (tool, jsonArgs, opts) => {
|
|
26
|
+
try {
|
|
27
|
+
if (opts.list) {
|
|
28
|
+
if (tool || jsonArgs)
|
|
29
|
+
throw new Error('Do not pass a tool name with --list.');
|
|
30
|
+
const tools = await listPlatformTools({ allTools: true });
|
|
31
|
+
if (opts.json) {
|
|
32
|
+
printJson({ tools, count: tools.length });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const entry of tools) {
|
|
36
|
+
const summary = entry.description?.split('\n')[0] ?? '';
|
|
37
|
+
process.stdout.write(`${entry.name}\t${summary}\n`);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!tool) {
|
|
42
|
+
throw new Error('Missing tool name. Run `somewhere call --list` to discover tools.');
|
|
43
|
+
}
|
|
44
|
+
const value = await callPlatformTool(tool, parseArguments(jsonArgs), { allTools: true });
|
|
45
|
+
if (opts.json || typeof value !== 'string') {
|
|
46
|
+
printJson(value);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
process.stdout.write(value.endsWith('\n') ? value : `${value}\n`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
54
|
+
const next = /unknown tool|not found/i.test(message)
|
|
55
|
+
? ' Run `somewhere call --list` to see exact tool names.'
|
|
56
|
+
: '';
|
|
57
|
+
error(`${message}${next}`);
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/commands/call.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { callPlatformTool } from '../lib/platform-tools.js';
|
|
2
|
+
import { isRecord, resolveProjectRef, truncateText, unwrapPlatformData, } from '../lib/platform-command.js';
|
|
3
|
+
import { dim, error, printJson, table, timeAgo } from '../lib/output.js';
|
|
4
|
+
async function feedbackCall(args, json, printer) {
|
|
5
|
+
try {
|
|
6
|
+
const value = await callPlatformTool('feedback', args, { allTools: true });
|
|
7
|
+
if (json)
|
|
8
|
+
printJson(value);
|
|
9
|
+
else
|
|
10
|
+
printer(value);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
error(err instanceof Error ? err.message : String(err));
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function printFeedbackList(value) {
|
|
18
|
+
const data = unwrapPlatformData(value);
|
|
19
|
+
const rowsValue = isRecord(data) ? data.feedback : undefined;
|
|
20
|
+
if (!Array.isArray(rowsValue)) {
|
|
21
|
+
printJson(data);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (rowsValue.length === 0) {
|
|
25
|
+
console.log(dim('No project feedback.'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const rows = rowsValue.map((row) => {
|
|
29
|
+
if (!isRecord(row))
|
|
30
|
+
return ['—', '—', '—', '—'];
|
|
31
|
+
const created = typeof row.created_at === 'number'
|
|
32
|
+
? timeAgo(new Date(row.created_at).toISOString())
|
|
33
|
+
: typeof row.created_at === 'string'
|
|
34
|
+
? timeAgo(row.created_at)
|
|
35
|
+
: '—';
|
|
36
|
+
return [
|
|
37
|
+
typeof row.id === 'string' ? row.id : '—',
|
|
38
|
+
truncateText(row.message, 72),
|
|
39
|
+
typeof row.status === 'string' ? row.status : row.resolved === true ? 'resolved' : 'open',
|
|
40
|
+
created,
|
|
41
|
+
];
|
|
42
|
+
});
|
|
43
|
+
table(['ID', 'Message', 'Status', 'When'], rows);
|
|
44
|
+
}
|
|
45
|
+
export function registerFeedback(program) {
|
|
46
|
+
const feedback = program
|
|
47
|
+
.command('feedback')
|
|
48
|
+
.description('List or submit feedback for a project-owned application');
|
|
49
|
+
feedback
|
|
50
|
+
.command('list')
|
|
51
|
+
.description('List feedback sent to the project owner inbox')
|
|
52
|
+
.option('-p, --project <project>', 'Project slug or ID; defaults to the linked project')
|
|
53
|
+
.option('--json', 'Print the complete response as JSON')
|
|
54
|
+
.action(async (opts) => {
|
|
55
|
+
await feedbackCall({ project_id: resolveProjectRef(opts.project) }, opts.json, printFeedbackList);
|
|
56
|
+
});
|
|
57
|
+
feedback
|
|
58
|
+
.command('submit <message>')
|
|
59
|
+
.description('Submit app feedback to the project owner inbox')
|
|
60
|
+
.option('-p, --project <project>', 'Project slug or ID; defaults to the linked project')
|
|
61
|
+
.option('--page-url <url>', 'Page URL the feedback concerns')
|
|
62
|
+
.option('--json', 'Print the complete response as JSON')
|
|
63
|
+
.action(async (message, opts) => {
|
|
64
|
+
await feedbackCall({
|
|
65
|
+
project_id: resolveProjectRef(opts.project),
|
|
66
|
+
message,
|
|
67
|
+
...(opts.pageUrl ? { page_url: opts.pageUrl } : {}),
|
|
68
|
+
}, opts.json, (value) => {
|
|
69
|
+
const data = unwrapPlatformData(value);
|
|
70
|
+
printJson(data);
|
|
71
|
+
console.log(dim('Destination: project owner inbox. For a platform bug, use `somewhere call support_ticket`.'));
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/commands/feedback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import prompts from 'prompts';
|
|
3
|
+
import { ApiClient, LONG_CALL_TIMEOUT_MS } from '../lib/client.js';
|
|
4
|
+
import { getToken, loadProjectConfig } from '../lib/config.js';
|
|
5
|
+
import open from '../lib/open.js';
|
|
6
|
+
import { dim, error, info, printJson, success, teal } from '../lib/output.js';
|
|
7
|
+
const DASHBOARD = 'https://somewhere.tech/dashboard';
|
|
8
|
+
const INSTALL_TIMEOUT_MS = 5 * 60_000;
|
|
9
|
+
const DEPLOY_POLL_MS = 1500;
|
|
10
|
+
function sleep(ms) {
|
|
11
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
+
}
|
|
13
|
+
function projectRef(explicit) {
|
|
14
|
+
if (explicit)
|
|
15
|
+
return explicit;
|
|
16
|
+
const config = loadProjectConfig();
|
|
17
|
+
if (config)
|
|
18
|
+
return config.project_id;
|
|
19
|
+
throw new Error('No project specified and no .somewhere.json found. Pass --project <id-or-slug>.');
|
|
20
|
+
}
|
|
21
|
+
function inferGitHubRepo() {
|
|
22
|
+
try {
|
|
23
|
+
const remote = execFileSync('git', ['remote', 'get-url', 'origin'], {
|
|
24
|
+
encoding: 'utf8',
|
|
25
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
26
|
+
}).trim();
|
|
27
|
+
const match = remote.match(/github\.com[/:]([^/]+)\/([^/]+?)(?:\.git)?$/i);
|
|
28
|
+
return match ? `${match[1]}/${match[2]}` : null;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function listInstallations(client) {
|
|
35
|
+
return client.call('GET', '/github/app/installations');
|
|
36
|
+
}
|
|
37
|
+
async function listChoices(client, installations) {
|
|
38
|
+
const batches = await Promise.all(installations.map(async (installation) => {
|
|
39
|
+
const repos = await client.call('GET', '/github/app/repos', undefined, { installation_id: installation.installation_id });
|
|
40
|
+
return repos.map((repo) => ({ installation, repo }));
|
|
41
|
+
}));
|
|
42
|
+
return batches.flat();
|
|
43
|
+
}
|
|
44
|
+
async function openInstaller(client, quiet) {
|
|
45
|
+
const start = await client.call('GET', '/github/app/install', undefined, { format: 'json', return_to: `${DASHBOARD}?github_cli=connected` });
|
|
46
|
+
if (!quiet)
|
|
47
|
+
info(`Opening GitHub to choose an account and repositories…`);
|
|
48
|
+
try {
|
|
49
|
+
await open(start.install_url);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
if (!quiet)
|
|
53
|
+
info(`Open this link: ${start.install_url}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function waitForChoices(client, repoName, quiet) {
|
|
57
|
+
const deadline = Date.now() + INSTALL_TIMEOUT_MS;
|
|
58
|
+
if (!quiet)
|
|
59
|
+
info('Waiting for GitHub authorization…');
|
|
60
|
+
while (Date.now() < deadline) {
|
|
61
|
+
const state = await listInstallations(client);
|
|
62
|
+
const choices = await listChoices(client, state.installations);
|
|
63
|
+
if (repoName) {
|
|
64
|
+
if (choices.some((choice) => choice.repo.name.toLowerCase() === repoName.toLowerCase()))
|
|
65
|
+
return choices;
|
|
66
|
+
}
|
|
67
|
+
else if (choices.length > 0) {
|
|
68
|
+
return choices;
|
|
69
|
+
}
|
|
70
|
+
await sleep(2000);
|
|
71
|
+
}
|
|
72
|
+
throw new Error('GitHub authorization was not completed within 5 minutes. Run `somewhere git connect` again.');
|
|
73
|
+
}
|
|
74
|
+
async function chooseRepo(client, requestedRepo, quiet) {
|
|
75
|
+
const app = await listInstallations(client);
|
|
76
|
+
if (!app.app_configured) {
|
|
77
|
+
throw new Error('GitHub App connect is not configured on this somewhere.tech environment.');
|
|
78
|
+
}
|
|
79
|
+
const inferredRepo = requestedRepo || inferGitHubRepo();
|
|
80
|
+
let choices = await listChoices(client, app.installations);
|
|
81
|
+
let match = inferredRepo
|
|
82
|
+
? choices.find((choice) => choice.repo.name.toLowerCase() === inferredRepo.toLowerCase())
|
|
83
|
+
: undefined;
|
|
84
|
+
if (app.installations.length === 0 || (inferredRepo && !match) || choices.length === 0) {
|
|
85
|
+
await openInstaller(client, quiet);
|
|
86
|
+
choices = await waitForChoices(client, inferredRepo, quiet);
|
|
87
|
+
match = inferredRepo
|
|
88
|
+
? choices.find((choice) => choice.repo.name.toLowerCase() === inferredRepo.toLowerCase())
|
|
89
|
+
: undefined;
|
|
90
|
+
}
|
|
91
|
+
if (match)
|
|
92
|
+
return match;
|
|
93
|
+
if (requestedRepo) {
|
|
94
|
+
throw new Error(`GitHub did not grant access to ${requestedRepo}. Rerun the command and select that repository.`);
|
|
95
|
+
}
|
|
96
|
+
if (!process.stdin.isTTY) {
|
|
97
|
+
throw new Error('No GitHub repository was specified. Pass owner/repo in a non-interactive shell.');
|
|
98
|
+
}
|
|
99
|
+
const answer = await prompts({
|
|
100
|
+
type: 'select',
|
|
101
|
+
name: 'choice',
|
|
102
|
+
message: 'Repository to deploy',
|
|
103
|
+
choices: choices.map((choice) => ({
|
|
104
|
+
title: `${choice.repo.name}${choice.repo.private ? ' (private)' : ''}`,
|
|
105
|
+
value: choice,
|
|
106
|
+
})),
|
|
107
|
+
});
|
|
108
|
+
if (!answer.choice)
|
|
109
|
+
throw new Error('GitHub connection cancelled.');
|
|
110
|
+
return answer.choice;
|
|
111
|
+
}
|
|
112
|
+
async function waitForDeploy(client, projectId, commitSha) {
|
|
113
|
+
const deadline = Date.now() + LONG_CALL_TIMEOUT_MS;
|
|
114
|
+
while (Date.now() < deadline) {
|
|
115
|
+
const connection = await client.call('GET', '/github/connection', undefined, { project_id: projectId });
|
|
116
|
+
if (connection.last_commit_sha === commitSha) {
|
|
117
|
+
if (connection.last_status === 'deployed')
|
|
118
|
+
return connection;
|
|
119
|
+
if (connection.last_status === 'failed') {
|
|
120
|
+
throw new Error(connection.last_error || `Deploy of ${commitSha.slice(0, 7)} failed.`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
await sleep(DEPLOY_POLL_MS);
|
|
124
|
+
}
|
|
125
|
+
throw new Error(`Deploy of ${commitSha.slice(0, 7)} is still running after 10 minutes. Check the project logs.`);
|
|
126
|
+
}
|
|
127
|
+
function urls(projectId, subdomain) {
|
|
128
|
+
return {
|
|
129
|
+
live_url: `https://${subdomain}.somewhere.tech`,
|
|
130
|
+
logs_url: `${DASHBOARD}/projects/${encodeURIComponent(projectId)}?tab=logs`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export function registerGit(program) {
|
|
134
|
+
const git = program
|
|
135
|
+
.command('git')
|
|
136
|
+
.description('Connect a GitHub repository for push-to-deploy');
|
|
137
|
+
git
|
|
138
|
+
.command('connect [repo]')
|
|
139
|
+
.description('Connect a repository, deploy HEAD now, and deploy future pushes')
|
|
140
|
+
.option('-p, --project <id-or-slug>', 'Project ID or slug (defaults to .somewhere.json)')
|
|
141
|
+
.option('-b, --branch <branch>', 'Branch to deploy (defaults to the repository default branch)')
|
|
142
|
+
.option('--root <directory>', 'Repository subdirectory to deploy')
|
|
143
|
+
.option('--json', 'Print structured JSON')
|
|
144
|
+
.action(async (repo, opts) => {
|
|
145
|
+
try {
|
|
146
|
+
const client = new ApiClient(getToken());
|
|
147
|
+
const ref = projectRef(opts.project);
|
|
148
|
+
const project = await client.call('GET', `/projects/${encodeURIComponent(ref)}`);
|
|
149
|
+
const resolvedProjectId = project.id || ref;
|
|
150
|
+
const choice = await chooseRepo(client, repo, !!opts.json);
|
|
151
|
+
const branch = opts.branch || choice.repo.default_branch || 'main';
|
|
152
|
+
if (!opts.json)
|
|
153
|
+
info(`Deploying ${teal(choice.repo.name)}@${branch} to ${teal(project.name)}…`);
|
|
154
|
+
const started = await client.call('POST', '/github/connect', {
|
|
155
|
+
project_id: ref,
|
|
156
|
+
repo: choice.repo.name,
|
|
157
|
+
branch,
|
|
158
|
+
...(opts.root ? { root_dir: opts.root } : {}),
|
|
159
|
+
installation_id: choice.installation.installation_id,
|
|
160
|
+
deploy_head: true,
|
|
161
|
+
});
|
|
162
|
+
const commitSha = started.initial_deploy?.commit_sha;
|
|
163
|
+
if (!commitSha)
|
|
164
|
+
throw new Error('GitHub connected, but the repository deploy did not start.');
|
|
165
|
+
const connection = await waitForDeploy(client, started.project_id || resolvedProjectId, commitSha);
|
|
166
|
+
const connectedProjectId = started.project_id || resolvedProjectId;
|
|
167
|
+
const links = urls(connectedProjectId, project.subdomain);
|
|
168
|
+
const result = {
|
|
169
|
+
connected: true,
|
|
170
|
+
project_id: connectedProjectId,
|
|
171
|
+
repo: connection.repo,
|
|
172
|
+
branch: connection.branch,
|
|
173
|
+
commit_sha: commitSha,
|
|
174
|
+
commit_message: connection.last_commit_message,
|
|
175
|
+
status: connection.last_status,
|
|
176
|
+
...links,
|
|
177
|
+
};
|
|
178
|
+
if (opts.json) {
|
|
179
|
+
printJson(result);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
success(`Deployed ${connection.repo}@${commitSha.slice(0, 7)}`);
|
|
183
|
+
info(`Status: ${connection.last_status}`);
|
|
184
|
+
info(`Logs: ${dim(links.logs_url)}`);
|
|
185
|
+
info(`Live: ${teal(links.live_url)}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
error(err instanceof Error ? err.message : String(err));
|
|
190
|
+
process.exitCode = 1;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
git
|
|
194
|
+
.command('status [project]')
|
|
195
|
+
.description('Show the repository, commit, deploy status, logs, and live URL')
|
|
196
|
+
.option('-p, --project <id-or-slug>', 'Project ID or slug (defaults to the positional project or .somewhere.json)')
|
|
197
|
+
.option('--json', 'Print structured JSON')
|
|
198
|
+
.action(async (project, opts) => {
|
|
199
|
+
try {
|
|
200
|
+
const client = new ApiClient(getToken());
|
|
201
|
+
const ref = projectRef(opts.project || project);
|
|
202
|
+
const [connection, summary] = await Promise.all([
|
|
203
|
+
client.call('GET', '/github/connection', undefined, { project_id: ref }),
|
|
204
|
+
client.call('GET', `/projects/${encodeURIComponent(ref)}`),
|
|
205
|
+
]);
|
|
206
|
+
const links = urls(summary.id || connection.project_id || ref, summary.subdomain);
|
|
207
|
+
const result = { ...connection, ...links };
|
|
208
|
+
if (opts.json) {
|
|
209
|
+
printJson(result);
|
|
210
|
+
}
|
|
211
|
+
else if (!connection.connected) {
|
|
212
|
+
info('No GitHub repository is connected. Run `somewhere git connect`.');
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
console.log(`\n Repository: ${teal(connection.repo || '')}`);
|
|
216
|
+
info(`Branch: ${connection.branch}`);
|
|
217
|
+
info(`Commit: ${connection.last_commit_sha ? `${connection.last_commit_sha.slice(0, 7)}${connection.last_commit_message ? ` · ${connection.last_commit_message}` : ''}` : 'none yet'}`);
|
|
218
|
+
info(`Status: ${connection.last_status || 'waiting for first deploy'}`);
|
|
219
|
+
if (connection.last_error)
|
|
220
|
+
info(`Error: ${connection.last_error}`);
|
|
221
|
+
info(`Logs: ${dim(links.logs_url)}`);
|
|
222
|
+
info(`Live: ${teal(links.live_url)}`);
|
|
223
|
+
console.log('');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
error(err instanceof Error ? err.message : String(err));
|
|
228
|
+
process.exitCode = 1;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
git
|
|
232
|
+
.command('disconnect [project]')
|
|
233
|
+
.description('Stop GitHub push-to-deploy without changing the deployed site')
|
|
234
|
+
.option('-p, --project <id-or-slug>', 'Project ID or slug (defaults to the positional project or .somewhere.json)')
|
|
235
|
+
.option('-y, --yes', 'Disconnect without prompting')
|
|
236
|
+
.option('--json', 'Print structured JSON')
|
|
237
|
+
.action(async (project, opts) => {
|
|
238
|
+
try {
|
|
239
|
+
const client = new ApiClient(getToken());
|
|
240
|
+
const ref = projectRef(opts.project || project);
|
|
241
|
+
if (!opts.yes) {
|
|
242
|
+
if (!process.stdin.isTTY)
|
|
243
|
+
throw new Error('Pass --yes to disconnect in a non-interactive shell.');
|
|
244
|
+
const answer = await prompts({
|
|
245
|
+
type: 'confirm',
|
|
246
|
+
name: 'confirmed',
|
|
247
|
+
message: 'Disconnect GitHub? The current deployed site stays live.',
|
|
248
|
+
initial: false,
|
|
249
|
+
});
|
|
250
|
+
if (!answer.confirmed)
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
await client.call('DELETE', '/github/connection', undefined, { project_id: ref });
|
|
254
|
+
if (opts.json)
|
|
255
|
+
printJson({ disconnected: true, project_id: ref });
|
|
256
|
+
else
|
|
257
|
+
success('GitHub disconnected. The current deployed site is unchanged.');
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
error(err instanceof Error ? err.message : String(err));
|
|
261
|
+
process.exitCode = 1;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/commands/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { callPlatformTool } from '../lib/platform-tools.js';
|
|
2
|
+
import { compactRecord, isRecord, resolveProjectRef, unwrapPlatformData, } from '../lib/platform-command.js';
|
|
3
|
+
import { error, printJson } from '../lib/output.js';
|
|
4
|
+
export function registerGrep(program) {
|
|
5
|
+
program
|
|
6
|
+
.command('grep <pattern>')
|
|
7
|
+
.description('Regex-search deployed project source and print file:line matches')
|
|
8
|
+
.option('-p, --project <project>', 'Project slug or ID; defaults to the linked project')
|
|
9
|
+
.option('-g, --glob <glob>', 'Limit matching paths, for example src/** or *.tsx')
|
|
10
|
+
.option('--env <env>', 'prod or dev', 'prod')
|
|
11
|
+
.option('--max-results <n>', 'Maximum matches, up to 1000', '100')
|
|
12
|
+
.option('-i, --ignore-case', 'Match case-insensitively')
|
|
13
|
+
.option('--json', 'Print the complete response as JSON')
|
|
14
|
+
.action(async (pattern, opts) => {
|
|
15
|
+
try {
|
|
16
|
+
const maxResults = Number(opts.maxResults);
|
|
17
|
+
if (!Number.isInteger(maxResults) || maxResults < 1 || maxResults > 1000) {
|
|
18
|
+
throw new Error('--max-results must be an integer from 1 to 1000.');
|
|
19
|
+
}
|
|
20
|
+
const value = await callPlatformTool('project_grep', compactRecord([
|
|
21
|
+
['project_id', resolveProjectRef(opts.project)],
|
|
22
|
+
['pattern', pattern],
|
|
23
|
+
['glob', opts.glob],
|
|
24
|
+
['env', opts.env],
|
|
25
|
+
['max_results', maxResults],
|
|
26
|
+
['case_insensitive', opts.ignoreCase],
|
|
27
|
+
]), { allTools: true });
|
|
28
|
+
if (opts.json) {
|
|
29
|
+
printJson(value);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const data = unwrapPlatformData(value);
|
|
33
|
+
if (!isRecord(data) || !Array.isArray(data.matches)) {
|
|
34
|
+
throw new Error('project_grep returned an unexpected response.');
|
|
35
|
+
}
|
|
36
|
+
for (const match of data.matches) {
|
|
37
|
+
if (!isRecord(match))
|
|
38
|
+
continue;
|
|
39
|
+
const path = typeof match.path === 'string' ? match.path : 'unknown';
|
|
40
|
+
const line = typeof match.line === 'number' ? match.line : 0;
|
|
41
|
+
const col = typeof match.col === 'number' ? `:${match.col}` : '';
|
|
42
|
+
const text = typeof match.text === 'string' ? match.text.trimEnd() : '';
|
|
43
|
+
process.stdout.write(`${path}:${line}${col}: ${text}\n`);
|
|
44
|
+
}
|
|
45
|
+
if (data.truncated === true) {
|
|
46
|
+
process.stderr.write('Results truncated. Narrow --glob or pattern, or raise --max-results.\n');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
error(err instanceof Error ? err.message : String(err));
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=grep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grep.js","sourceRoot":"","sources":["../../src/commands/grep.ts"],"names":[],"mappings":"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"}
|