@isomorph.ai/cli 0.10.9 → 0.10.10

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.
@@ -120,7 +120,7 @@ Rules live beside this file: \`core.md\` before the first edit; \`integrations.m
120
120
  | "does it work?" (and before reporting anything as working) | open the dev link in your own browser, press the control you built or changed, read what the app shows; a green \`isomorph check\` is not that proof (fixtures answer AI and company systems). A Send in development is real: reuse explicit authorization or ask once. No browser: say the button is untested. |
121
121
  | "I need Slack / Gmail / the warehouse" | read \`integrations.md\` beside this skill first; then: catalog, write the call (literals only), \`isomorph check\`, then submit the request; say READY or PENDING in one line. |
122
122
  | "summarise", "draft", "AI" | read \`ai.md\` beside this skill first; then one call behind a control they press. |
123
- | "ship it", "let my team try it" | show the person the three values in \`.isomorph/app.json\` (name, description, audience — "only you" when empty) and correct the file as they say; then \`isomorph deploy --app-root . --json\` (it runs the checks when needed and refuses once naming every blocker and its fix: relay that line; the app works meanwhile). Give them \`result.deployment.protectedUrl\`. \`--session-notes\`: what cost you time in Isomorph, or \`""\`. |
123
+ | "ship it", "let my team try it" | show the person the three values in \`.isomorph/app.json\` (name, description, audience — "only you" when empty) and correct the file as they say; then \`isomorph deploy --app-root . --json\` (it runs the checks when needed and refuses once naming every blocker and its fix: relay that line; the app works meanwhile). Give them \`result.deployment.protectedUrl\` and \`result.consoleUrl\` (its live checks). \`--session-notes\`: what cost you time in Isomorph, or \`""\`. |
124
124
  | "make it live" | only after they have tried the preview: \`isomorph promote --operation <ref> --app-root . --confirm-tested --json\`. Report the production link, or that operator approval is pending. |
125
125
  | "stop it" | \`isomorph stop --app-root .\` (data kept); \`isomorph dev --app-root . --reset\` only when they ask to start over. |
126
126
  | "every day at 2pm", "send this automatically" | read \`jobs.md\` beside this skill first (follow its in-conversation owner approval steps); write the job, run it once with \`isomorph jobs run\`, and report what was verified. |
@@ -203,4 +203,4 @@ function loopbackCallback() {
203
203
  server.on("error", reject);
204
204
  });
205
205
  }
206
- function openBrowser(url) { const command = platform() === "darwin" ? "open" : platform() === "win32" ? "cmd" : "xdg-open"; const args = platform() === "win32" ? ["/c", "start", "", url] : [url]; const child = spawn(command, args, { detached: true, stdio: "ignore" }); child.unref(); child.on("error", () => { }); }
206
+ export function openBrowser(url) { const command = platform() === "darwin" ? "open" : platform() === "win32" ? "cmd" : "xdg-open"; const args = platform() === "win32" ? ["/c", "start", "", url] : [url]; const child = spawn(command, args, { detached: true, stdio: "ignore" }); child.unref(); child.on("error", () => { }); }
@@ -3,7 +3,7 @@ import { appCallsAi, deploy, readDeployNote } from "./deploy.js";
3
3
  import { continueCommand, follow, promoteToProduction, retryDeployment, statusFetch, summarize } from "./operations.js";
4
4
  import { CliError, failureEnvelope, operationEnvelope, renderFailure, renderSummary } from "./output.js";
5
5
  import { CLI_VERSION } from "./version.js";
6
- import { alreadySignedIn, connectedAccount, login, logout, refreshStoredToken } from "./auth.js";
6
+ import { alreadySignedIn, connectedAccount, login, logout, openBrowser, refreshStoredToken } from "./auth.js";
7
7
  import { assertCliCurrent, CLI_INSTALL_COMMAND, cliStaleness, companyLabel, connect, loadConfig, resolveConfig } from "./config.js";
8
8
  import { EMBEDDED_KIT_BUNDLE } from "./kit-bundle.js";
9
9
  import { appRoot, assertLockCompany, readAppProfile, readKitLock, requestResourceName } from "./kit.js";
@@ -266,7 +266,7 @@ else {
266
266
  }
267
267
  }
268
268
  else if (command === "deploy") {
269
- const result = await deploy(root, governance, progress, tenant, { waitForDeployment: !noWait, waitOptions, bundle: EMBEDDED_KIT_BUNDLE, ...(sessionNotes ? { sessionNotes } : {}) });
269
+ const result = await deploy(root, governance, progress, tenant, { waitForDeployment: !noWait, waitOptions, bundle: EMBEDDED_KIT_BUNDLE, ...(sessionNotes ? { sessionNotes } : {}), ...(process.env.CI || process.env.ISOMORPH_NO_BROWSER ? {} : { openConsole: openBrowser }) });
270
270
  envelope = operationEnvelope(result.result, result.operationRef, CLI_VERSION);
271
271
  }
272
272
  else {
@@ -143,6 +143,12 @@ function minimumCliVersion(body) {
143
143
  function platformOrigin() {
144
144
  return process.env.ISOMORPH_PLATFORM_URL?.trim() || "https://platform.isomorph.ai";
145
145
  }
146
+ /** The console page where the builder watches one deployment: the app's releases, focused on this operation. */
147
+ export function consoleOperationUrl(tenantId, appId, operationRef) {
148
+ const url = new URL(`${platformOrigin().replace(/\/$/, "")}/t/${encodeURIComponent(tenantId)}`);
149
+ url.search = new URLSearchParams({ appId, tab: "releases", operationId: operationRef }).toString();
150
+ return url.toString();
151
+ }
146
152
  /**
147
153
  * The link as the person typed it, made fetchable: the console's company page
148
154
  * (`/t/<company>`) is a start link too, a link without its scheme (as a browser
@@ -6,6 +6,7 @@ import { archiveForManifest, putMultipart } from "./upload.js";
6
6
  import { CliError } from "./output.js";
7
7
  import { continueCommand, follow, outcomeFor, pickSourceFailure, recordedRefusal, runningLine, statusFetch, summarize } from "./operations.js";
8
8
  import { CLI_VERSION } from "./version.js";
9
+ import { consoleOperationUrl } from "./config.js";
9
10
  import { assertSafeAppRoot, readAppTree } from "./package.js";
10
11
  import { deployBlocked, ensureLinkedApp, kitLockBody } from "./integrations.js";
11
12
  import { assertLockCompany, describeSourceChange, kitPaths, readReviewedAppProfile, readDeclaration, readKitLock, sourceDigest } from "./kit.js";
@@ -127,6 +128,16 @@ async function runDeploy(rootArg, governance, output, tenantId, options) {
127
128
  if (opened.resumed && note?.sha256 !== archive.digest)
128
129
  output(`Isomorph is continuing operation ${operationRef}; no new deployment was started.`);
129
130
  output(`Isomorph operation saved. Continue with ${continueCommand(operationRef)}.`);
131
+ // Everything Isomorph checks, fixes and provisions for this version is shown
132
+ // live in the console; the builder is sent there the moment it starts.
133
+ const consoleUrl = consoleOperationUrl(tenantId, appId, operationRef);
134
+ output(`Watch Isomorph check, secure and deploy this app: ${consoleUrl}`);
135
+ if (!opened.resumed) {
136
+ try {
137
+ options.openConsole?.(consoleUrl);
138
+ }
139
+ catch { /* the printed link stands */ }
140
+ }
130
141
  const fetch = statusFetch(governance, appId, operationRef);
131
142
  try {
132
143
  let status = opened.status;
@@ -156,7 +167,7 @@ async function runDeploy(rootArg, governance, output, tenantId, options) {
156
167
  }
157
168
  output(outcomeLine(summary));
158
169
  }
159
- return { cliVersion: CLI_VERSION, operationRef, result: summary };
170
+ return { cliVersion: CLI_VERSION, operationRef, result: { ...summary, consoleUrl } };
160
171
  }
161
172
  catch (error) {
162
173
  throw await operationFailure(fetch, operationRef, error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isomorph.ai/cli",
3
- "version": "0.10.9",
3
+ "version": "0.10.10",
4
4
  "description": "Isomorph development kit CLI",
5
5
  "type": "module",
6
6
  "bin": {