@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 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 |
@@ -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
- const MCP_URL = process.env.SOMEWHERE_MCP_URL?.replace(/\/$/, '') || 'https://mcp.somewhere.tech/mcp';
5
- function toolErrorMessage(text) {
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":"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"}
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":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAQzE,KAAK,UAAU,YAAY,CACzB,IAA6B,EAC7B,IAAyB,EACzB,OAAiC;IAEjC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,IAAI,IAAI;YAAE,SAAS,CAAC,KAAK,CAAC,CAAC;;YACtB,OAAO,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAY,EAAE;QAC3C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;YAChD,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACjD,CAAC,CAAC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;gBAClC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,GAAG,CAAC;QACV,OAAO;YACL,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;YACzC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7B,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;YACzF,OAAO;SACR,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,yDAAyD,CAAC,CAAC;IAE1E,QAAQ;SACL,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,yBAAyB,EAAE,oDAAoD,CAAC;SACvF,MAAM,CAAC,QAAQ,EAAE,qCAAqC,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,IAAqB,EAAE,EAAE;QACtC,MAAM,YAAY,CAChB,EAAE,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAC/C,IAAI,CAAC,IAAI,EACT,iBAAiB,CAClB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,gDAAgD,CAAC;SAC7D,MAAM,CAAC,yBAAyB,EAAE,oDAAoD,CAAC;SACvF,MAAM,CAAC,kBAAkB,EAAE,gCAAgC,CAAC;SAC5D,MAAM,CAAC,QAAQ,EAAE,qCAAqC,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAqB,EAAE,EAAE;QACvD,MAAM,YAAY,CAAC;YACjB,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3C,OAAO;YACP,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpD,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YACvC,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAC,CAAC;QACjH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -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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"}