@anvil-works/anvil-cli 0.8.0-canary.17 → 0.8.0-canary.19

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/dist/cli.js CHANGED
@@ -12904,9 +12904,6 @@ var __webpack_exports__ = {};
12904
12904
  function getGlobalOutputConfig() {
12905
12905
  return globalOutputConfig;
12906
12906
  }
12907
- function canPrompt() {
12908
- return !globalOutputConfig.jsonMode && !!(process.stdin.isTTY && process.stdout.isTTY);
12909
- }
12910
12907
  function assertCanPrompt(action = "This command", explicitAlternative = "Pass explicit flags instead.") {
12911
12908
  if (globalOutputConfig.jsonMode) throw new Error(`${action} requires interactive input, but --json disables prompts. ${explicitAlternative}`);
12912
12909
  if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error(`${action} requires interactive input, but stdin/stdout is not a TTY. ${explicitAlternative}`);
@@ -23676,21 +23673,22 @@ print(json.dumps({"issues": issues}))
23676
23673
  if (!response.ok) throw new Error(formatHttpError("Failed to apply database schema", response.status, await response.text()));
23677
23674
  return await response.json();
23678
23675
  }
23679
- async function confirmSchemaApplication(message) {
23680
- if (!canPrompt()) return true;
23681
- return logger_logger.confirm(message, true);
23676
+ async function confirmSchemaApplication(force = false) {
23677
+ if (force) return true;
23678
+ assertCanPrompt("Applying database schema", "Pass --force to apply without prompting.");
23679
+ return logger_logger.confirm("Apply the app environment's schema to its database? This may delete tables, columns, or data.", true);
23682
23680
  }
23683
23681
  function registerDbCommand(program) {
23684
23682
  if ("1" !== process.env.ANVIL_AGENT_HOST) return;
23685
23683
  const db = program.command("db").description("Manage app databases");
23686
- db.command("apply-schema").description("Apply the app schema to the database for the current environment").action(async ()=>{
23684
+ db.command("apply-schema").description("Apply the app schema to the database for the current environment").option("-f, --force", "Apply the schema without asking for confirmation").action(async (options)=>{
23687
23685
  try {
23688
23686
  const projectRoot = process.cwd();
23689
23687
  auth_setRepoContext(projectRoot);
23690
23688
  const anvilUrl = await resolveAuthAnvilUrl();
23691
23689
  const appId = await resolvePrimaryAppId(projectRoot, anvilUrl);
23692
23690
  if (!appId) throw new Error("No Anvil app found in current directory. Make sure you're in a directory with an Anvil app git remote.");
23693
- if (!await confirmSchemaApplication("Apply the app environment's schema to its database? This may delete tables, columns, or data.")) return void logger_logger.info("Schema application cancelled.");
23691
+ if (!await confirmSchemaApplication(options.force)) return void logger_logger.info("Schema application cancelled.");
23694
23692
  const response = await applyDatabaseSchema(appId, {
23695
23693
  anvilUrl,
23696
23694
  projectRoot
@@ -23712,37 +23710,325 @@ print(json.dumps({"issues": issues}))
23712
23710
  async function ensureEnvironmentUrl(appId, envPid, options = {}) {
23713
23711
  const anvilUrl = options.anvilUrl ?? await resolveAuthAnvilUrl();
23714
23712
  const token = await auth_getValidAuthToken(anvilUrl);
23715
- const response = await fetch(`${anvilUrl}/ide/api/_/apps/${encodeURIComponent(appId)}/environments/${encodeURIComponent(envPid)}/ensure-url`, {
23713
+ const response = await fetch(`${anvilUrl}/ide/api/_/apps/${encodeURIComponent(appId)}/environments/${encodeURIComponent(envPid)}/temporary-url`, {
23716
23714
  method: "POST",
23717
23715
  headers: {
23718
23716
  Authorization: `Bearer ${token}`
23719
23717
  }
23720
23718
  });
23721
23719
  if (!response.ok) throw new Error(formatHttpError("Failed to get environment URL", response.status, await response.text()));
23722
- const result = await response.json();
23723
- return result.url;
23720
+ const { url, expires_at } = await response.json();
23721
+ return {
23722
+ url,
23723
+ expires_at
23724
+ };
23725
+ }
23726
+ async function getTemporaryUplinkKey(appId, envPid, options = {}) {
23727
+ const anvilUrl = options.anvilUrl ?? await resolveAuthAnvilUrl();
23728
+ const token = await auth_getValidAuthToken(anvilUrl);
23729
+ const response = await fetch(`${anvilUrl}/ide/api/_/apps/${encodeURIComponent(appId)}/environments/${encodeURIComponent(envPid)}/temporary-uplink-key`, {
23730
+ method: "POST",
23731
+ headers: {
23732
+ Authorization: `Bearer ${token}`
23733
+ }
23734
+ });
23735
+ if (!response.ok) throw new Error(formatHttpError("Failed to get temporary uplink key", response.status, await response.text()));
23736
+ const { key, url, expires_at } = await response.json();
23737
+ return {
23738
+ key,
23739
+ url,
23740
+ expires_at
23741
+ };
23742
+ }
23743
+ async function resolveEnvironmentContext() {
23744
+ const projectRoot = process.cwd();
23745
+ const envPid = await readEnvironmentPid(projectRoot);
23746
+ if (!envPid) throw new Error("No app environment associated with the current directory.");
23747
+ auth_setRepoContext(projectRoot);
23748
+ const anvilUrl = await resolveAuthAnvilUrl();
23749
+ const appId = await resolvePrimaryAppId(projectRoot, anvilUrl);
23750
+ if (!appId) throw new Error("No Anvil app found in current directory. Make sure you're in a directory with an Anvil app git remote.");
23751
+ return {
23752
+ envPid,
23753
+ anvilUrl,
23754
+ appId
23755
+ };
23724
23756
  }
23725
23757
  function registerEnvCommand(program) {
23726
23758
  if ("1" !== process.env.ANVIL_AGENT_HOST) return;
23727
23759
  const env = program.command("env").description("Manage app environments");
23728
- env.command("url").description("Get a private app URL for the current environment, creating one if necessary").action(async ()=>{
23760
+ env.command("url").description("Get a temporary private app URL for the current environment").action(async ()=>{
23729
23761
  try {
23730
- const projectRoot = process.cwd();
23731
- const envPid = await readEnvironmentPid(projectRoot);
23732
- if (!envPid) throw new Error("No app environment associated with the current directory.");
23733
- auth_setRepoContext(projectRoot);
23734
- const anvilUrl = await resolveAuthAnvilUrl();
23735
- const appId = await resolvePrimaryAppId(projectRoot, anvilUrl);
23736
- if (!appId) throw new Error("No Anvil app found in current directory. Make sure you're in a directory with an Anvil app git remote.");
23737
- logger_logger.info(await ensureEnvironmentUrl(appId, envPid, {
23762
+ const { appId, envPid, anvilUrl } = await resolveEnvironmentContext();
23763
+ const { url, expires_at } = await ensureEnvironmentUrl(appId, envPid, {
23738
23764
  anvilUrl
23739
- }));
23765
+ });
23766
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(true, {
23767
+ data: {
23768
+ url,
23769
+ expires_at
23770
+ }
23771
+ });
23772
+ else logger_logger.info(`URL: ${url}\nExpires at: ${expires_at}`);
23773
+ } catch (error) {
23774
+ const message = errors_getErrorMessage(error);
23775
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(false, {
23776
+ error: message
23777
+ });
23778
+ else logger_logger.error(message);
23779
+ process.exit(1);
23780
+ }
23781
+ });
23782
+ env.command("uplink").description("Get a temporary uplink key for the current environment").action(async ()=>{
23783
+ try {
23784
+ const { appId, envPid, anvilUrl } = await resolveEnvironmentContext();
23785
+ const { key, url, expires_at } = await getTemporaryUplinkKey(appId, envPid, {
23786
+ anvilUrl
23787
+ });
23788
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(true, {
23789
+ data: {
23790
+ key,
23791
+ url,
23792
+ expires_at
23793
+ }
23794
+ });
23795
+ else logger_logger.info(`Key: ${key}\nURL: ${url}\nExpires at: ${expires_at}`);
23740
23796
  } catch (error) {
23741
- logger_logger.error(errors_getErrorMessage(error));
23797
+ const message = errors_getErrorMessage(error);
23798
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(false, {
23799
+ error: message
23800
+ });
23801
+ else logger_logger.error(message);
23742
23802
  process.exit(1);
23743
23803
  }
23744
23804
  });
23745
23805
  }
23806
+ const external_events_namespaceObject = require("events");
23807
+ function replError(error) {
23808
+ if ("string" == typeof error) return {
23809
+ message: error
23810
+ };
23811
+ if (error && "object" == typeof error) {
23812
+ const value = error;
23813
+ return {
23814
+ message: String(value.message ?? value["anvil/server-error"] ?? JSON.stringify(value)),
23815
+ ..."string" == typeof value.type ? {
23816
+ type: value.type
23817
+ } : {},
23818
+ ...Array.isArray(value.trace) ? {
23819
+ trace: value.trace.filter((frame)=>Array.isArray(frame) && "string" == typeof frame[0] && "number" == typeof frame[1])
23820
+ } : {}
23821
+ };
23822
+ }
23823
+ return {
23824
+ message: String(error)
23825
+ };
23826
+ }
23827
+ class ReplServerError extends Error {
23828
+ detail;
23829
+ constructor(detail){
23830
+ super(detail.message), this.detail = detail;
23831
+ }
23832
+ }
23833
+ async function runRepl(appId, envPid, options) {
23834
+ const interrupted = ()=>new Error("REPL interrupted.");
23835
+ const anvilUrl = options.anvilUrl ?? await resolveAuthAnvilUrl();
23836
+ const token = await auth_getValidAuthToken(anvilUrl);
23837
+ const url = new URL(`${anvilUrl.replace(/\/$/, "")}/ide/api/_/apps/${encodeURIComponent(appId)}/environments/${encodeURIComponent(envPid)}/ws`);
23838
+ url.protocol = "https:" === url.protocol ? "wss:" : "ws:";
23839
+ if (options.signal?.aborted) throw interrupted();
23840
+ const ws = new (external_ws_default())(url, {
23841
+ headers: {
23842
+ Authorization: `Bearer ${token}`
23843
+ },
23844
+ handshakeTimeout: 30000
23845
+ });
23846
+ const controller = new AbortController();
23847
+ let repl;
23848
+ let nextId = 1;
23849
+ let output = "";
23850
+ let keepalive;
23851
+ let pongTimeout;
23852
+ let closeTimeout;
23853
+ const startupTimeout = setTimeout(()=>{
23854
+ controller.abort(new Error("Timed out waiting for the REPL to start."));
23855
+ }, 30000);
23856
+ const onAbort = ()=>controller.abort(interrupted());
23857
+ const markResponsive = ()=>{
23858
+ clearTimeout(pongTimeout);
23859
+ pongTimeout = void 0;
23860
+ };
23861
+ options.signal?.addEventListener("abort", onAbort, {
23862
+ once: true
23863
+ });
23864
+ ws.on("pong", markResponsive);
23865
+ ws.on("unexpected-response", (request, response)=>{
23866
+ response.resume();
23867
+ controller.abort(new Error(`REPL websocket handshake failed (${response.statusCode} ${response.statusMessage}).`));
23868
+ request.destroy();
23869
+ });
23870
+ ws.on("error", (error)=>controller.abort(new Error(`REPL websocket connection failed: ${error.message}`)));
23871
+ ws.on("close", (code, reason)=>{
23872
+ clearTimeout(closeTimeout);
23873
+ controller.abort(new Error(`REPL websocket disconnected unexpectedly (code ${code}${reason.length ? `: ${reason}` : ""}).`));
23874
+ });
23875
+ const messages = (0, external_events_namespaceObject.on)(ws, "message", {
23876
+ signal: controller.signal
23877
+ });
23878
+ function send(message) {
23879
+ const id = nextId++;
23880
+ ws.send(JSON.stringify({
23881
+ ...message,
23882
+ id
23883
+ }), (error)=>{
23884
+ if (error) controller.abort(new Error(`REPL websocket send failed: ${error.message}`));
23885
+ });
23886
+ return id;
23887
+ }
23888
+ async function readUntil(matches) {
23889
+ while(true){
23890
+ const { value, done } = await messages.next();
23891
+ options.signal?.throwIfAborted();
23892
+ if (done) throw new Error("REPL websocket message stream ended unexpectedly.");
23893
+ markResponsive();
23894
+ let message;
23895
+ try {
23896
+ message = JSON.parse(value[0].toString());
23897
+ if (!message || "object" != typeof message || Array.isArray(message)) throw new Error("Expected an object");
23898
+ } catch {
23899
+ throw new Error("Invalid REPL websocket message.");
23900
+ }
23901
+ if ("REPL_UPDATE" === message.event) {
23902
+ if (!repl || message.repl !== repl) continue;
23903
+ if ("string" == typeof message.output) {
23904
+ output += message.output;
23905
+ options.onOutput?.(message.output);
23906
+ options.signal?.throwIfAborted();
23907
+ }
23908
+ }
23909
+ if (message.error) throw new ReplServerError(replError(message.error));
23910
+ if ("REPL_UPDATE" === message.event && message.terminated) throw new Error("REPL terminated unexpectedly.");
23911
+ if (matches(message)) return message;
23912
+ }
23913
+ }
23914
+ try {
23915
+ await (0, external_events_namespaceObject.once)(ws, "open", {
23916
+ signal: controller.signal
23917
+ });
23918
+ const launchId = send({
23919
+ cmd: "LAUNCH_REPL"
23920
+ });
23921
+ const launched = await readUntil((message)=>message.id === launchId);
23922
+ if ("string" != typeof launched.repl || !launched.repl) throw new Error("Invalid REPL launch response: missing REPL ID.");
23923
+ repl = launched.repl;
23924
+ keepalive = setInterval(()=>{
23925
+ try {
23926
+ send({
23927
+ cmd: "REPL_KEEPALIVE",
23928
+ repl
23929
+ });
23930
+ pongTimeout = setTimeout(()=>controller.abort(new Error("REPL websocket heartbeat timed out.")), 10000);
23931
+ ws.ping();
23932
+ } catch (error) {
23933
+ controller.abort(error);
23934
+ }
23935
+ }, 20000);
23936
+ const isReady = (message)=>"REPL_UPDATE" === message.event && true === message.ready;
23937
+ await readUntil(isReady);
23938
+ clearTimeout(startupTimeout);
23939
+ send({
23940
+ cmd: "REPL_COMMAND",
23941
+ repl,
23942
+ command: options.code
23943
+ });
23944
+ await readUntil(isReady);
23945
+ return {
23946
+ output
23947
+ };
23948
+ } catch (error) {
23949
+ if (error instanceof ReplServerError) return {
23950
+ output,
23951
+ error: error.detail
23952
+ };
23953
+ const failure = controller.signal.aborted ? controller.signal.reason : error;
23954
+ throw failure instanceof Error ? failure : new Error(String(failure));
23955
+ } finally{
23956
+ clearTimeout(startupTimeout);
23957
+ clearInterval(keepalive);
23958
+ clearTimeout(pongTimeout);
23959
+ options.signal?.removeEventListener("abort", onAbort);
23960
+ controller.abort();
23961
+ await messages.return?.();
23962
+ if (ws.readyState === external_ws_default().OPEN) {
23963
+ if (repl) ws.send(JSON.stringify({
23964
+ id: nextId++,
23965
+ cmd: "TERMINATE_REPL",
23966
+ repl
23967
+ }), ()=>{});
23968
+ ws.close();
23969
+ } else if (ws.readyState === external_ws_default().CONNECTING) ws.terminate();
23970
+ if (ws.readyState !== external_ws_default().CLOSED) {
23971
+ closeTimeout = setTimeout(()=>ws.terminate(), 1000);
23972
+ closeTimeout.unref();
23973
+ }
23974
+ }
23975
+ }
23976
+ function writeJsonReplOutput(output) {
23977
+ process.stdout.write(JSON.stringify({
23978
+ type: "repl_output",
23979
+ output,
23980
+ timestamp: new Date().toISOString()
23981
+ }) + "\n");
23982
+ }
23983
+ function registerReplCommand(program) {
23984
+ if ("1" !== process.env.ANVIL_AGENT_HOST) return;
23985
+ program.command("repl <code>").description("Run Python in a fresh server REPL for the current environment; use - to read stdin").addHelpText("after", `
23986
+ Examples:
23987
+ anvil repl '1 + 2'
23988
+ anvil --json repl '1 + 2'
23989
+ anvil repl - < script.py
23990
+ `).action(async (code)=>{
23991
+ const controller = new AbortController();
23992
+ const onInterrupt = ()=>controller.abort();
23993
+ try {
23994
+ const { appId, envPid, anvilUrl } = await resolveEnvironmentContext();
23995
+ if ("-" === code) {
23996
+ const chunks = [];
23997
+ for await (const chunk of process.stdin)chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
23998
+ code = Buffer.concat(chunks).toString("utf8");
23999
+ }
24000
+ process.on("SIGINT", onInterrupt);
24001
+ const response = await runRepl(appId, envPid, {
24002
+ code,
24003
+ anvilUrl,
24004
+ signal: controller.signal,
24005
+ onOutput: getGlobalOutputConfig().jsonMode ? writeJsonReplOutput : (output)=>{
24006
+ process.stdout.write(output);
24007
+ }
24008
+ });
24009
+ const error = response.error;
24010
+ const message = error ? `${error.type ? `${error.type}: ` : ""}${error.message}` : void 0;
24011
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(!error, {
24012
+ data: response,
24013
+ error: message
24014
+ });
24015
+ else if (error) {
24016
+ process.stderr.write(`${message}\n`);
24017
+ for (const [file, line] of error.trace ?? [])process.stderr.write(` at ${file}:${line}\n`);
24018
+ }
24019
+ if (error) process.exitCode = 1;
24020
+ } catch (error) {
24021
+ const message = errors_getErrorMessage(error);
24022
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(false, {
24023
+ error: message
24024
+ });
24025
+ else logger_logger.error(message);
24026
+ process.exitCode = controller.signal.aborted ? 130 : 1;
24027
+ } finally{
24028
+ process.removeListener("SIGINT", onInterrupt);
24029
+ }
24030
+ });
24031
+ }
23746
24032
  const program_packageJson = JSON.parse((0, external_fs_.readFileSync)((0, external_path_namespaceObject.join)(__dirname, "../package.json"), "utf-8"));
23747
24033
  const VERSION = program_packageJson.version;
23748
24034
  setLogger(new CLILogger({
@@ -24165,6 +24451,7 @@ print(json.dumps({"issues": issues}))
24165
24451
  registerDepsCommand(program);
24166
24452
  registerDbCommand(program);
24167
24453
  registerEnvCommand(program);
24454
+ registerReplCommand(program);
24168
24455
  program.command("update").description("Update anvil to the latest version").alias("u").action(async ()=>{
24169
24456
  await handleUpdateCommand();
24170
24457
  });
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/commands/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2CxD"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/commands/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2CxD"}
@@ -1,3 +1,8 @@
1
1
  import { Command } from "commander";
2
+ export declare function resolveEnvironmentContext(): Promise<{
3
+ envPid: string;
4
+ anvilUrl: string;
5
+ appId: string;
6
+ }>;
2
7
  export declare function registerEnvCommand(program: Command): void;
3
8
  //# sourceMappingURL=env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgCzD"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAsB,yBAAyB;;;;GAe9C;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoDzD"}
@@ -15,4 +15,5 @@ export { registerConfigureCommand } from "./configure";
15
15
  export { registerDepsCommand } from "./deps";
16
16
  export { registerDbCommand } from "./db";
17
17
  export { registerEnvCommand } from "./env";
18
+ export { registerReplCommand } from "./repl";
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerReplCommand(program: Command): void;
3
+ //# sourceMappingURL=repl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../../src/commands/repl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+D1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC,OAAO,EAAyD,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAiC3G,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAoKF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAO7F;AAmLD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,EAAE,CAezE;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwFzD;AAiBD,wBAAgB,YAAY,IAAI,OAAO,CAmGtC"}
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC,OAAO,EAAyD,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAiC3G,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAoKF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAO7F;AAmLD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,EAAE,CAezE;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwFzD;AAiBD,wBAAgB,YAAY,IAAI,OAAO,CAoGtC"}
@@ -1,5 +1,16 @@
1
1
  export interface EnsureEnvironmentUrlOptions {
2
2
  anvilUrl?: string;
3
3
  }
4
- export declare function ensureEnvironmentUrl(appId: string, envPid: string, options?: EnsureEnvironmentUrlOptions): Promise<string>;
4
+ export declare function ensureEnvironmentUrl(appId: string, envPid: string, options?: EnsureEnvironmentUrlOptions): Promise<{
5
+ url: string;
6
+ expires_at: string;
7
+ }>;
8
+ export interface GetTemporaryUplinkKeyOptions {
9
+ anvilUrl?: string;
10
+ }
11
+ export declare function getTemporaryUplinkKey(appId: string, envPid: string, options?: GetTemporaryUplinkKeyOptions): Promise<{
12
+ key: string;
13
+ url: string;
14
+ expires_at: string;
15
+ }>;
5
16
  //# sourceMappingURL=environment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/services/environment.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,2BAA2B;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,oBAAoB,CACtC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,2BAAgC,GAC1C,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/services/environment.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,2BAA2B;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,oBAAoB,CACtC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,2BAAgC,GAC1C,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB9C;AAED,MAAM,WAAW,4BAA4B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,qBAAqB,CACvC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,4BAAiC,GAC3C,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB3D"}
@@ -0,0 +1,18 @@
1
+ export interface RunReplOptions {
2
+ code: string;
3
+ anvilUrl?: string;
4
+ /** Receives each output chunk immediately; the result also contains the full transcript. */
5
+ onOutput?: (output: string) => void;
6
+ signal?: AbortSignal;
7
+ }
8
+ export interface ReplResult {
9
+ output: string;
10
+ error?: {
11
+ type?: string;
12
+ message: string;
13
+ trace?: Array<[string, number]>;
14
+ };
15
+ }
16
+ /** Run one command in a fresh environment scope, then terminate it. */
17
+ export declare function runRepl(appId: string, envPid: string, options: RunReplOptions): Promise<ReplResult>;
18
+ //# sourceMappingURL=repl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../../src/services/repl.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACJ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;KACnC,CAAC;CACL;AAwBD,uEAAuE;AACvE,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CA2IzG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvil-works/anvil-cli",
3
- "version": "0.8.0-canary.17",
3
+ "version": "0.8.0-canary.19",
4
4
  "description": "CLI tool for developing Anvil apps locally",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/api.d.ts",