@instafy/cli 0.1.8-staging.365 → 0.1.8-staging.366

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
@@ -24,6 +24,7 @@ Run Instafy projects locally and connect them back to Instafy Studio — from an
24
24
  - `instafy runtime:start` — start a local runtime (agent + origin).
25
25
  - `instafy runtime:status` — show health of the last started runtime.
26
26
  - `instafy runtime:stop` — stop the last started runtime.
27
+ - `instafy git <args...>` — run git commands against an Instafy canonical checkout (`.instafy/.git`) when present.
27
28
  - `instafy tunnel` — start a detached tunnel for a local port.
28
29
  - `instafy tunnel:list` — list local tunnels started by the CLI.
29
30
  - `instafy tunnel:logs <tunnelId> --follow` — tail tunnel logs.
@@ -0,0 +1,85 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import kleur from "kleur";
5
+ function pathExists(candidate) {
6
+ try {
7
+ fs.statSync(candidate);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ export function findInstafyGitContext(startDir) {
15
+ let current = path.resolve(startDir);
16
+ const root = path.parse(current).root;
17
+ while (true) {
18
+ const gitDir = path.join(current, ".instafy", ".git");
19
+ if (pathExists(gitDir)) {
20
+ return { workTree: current, gitDir };
21
+ }
22
+ if (current === root)
23
+ break;
24
+ current = path.dirname(current);
25
+ }
26
+ return null;
27
+ }
28
+ function validateGitArgs(userArgs) {
29
+ let parsingGlobalOptions = true;
30
+ for (let index = 0; index < userArgs.length; index += 1) {
31
+ const arg = userArgs[index] ?? "";
32
+ if (!parsingGlobalOptions) {
33
+ continue;
34
+ }
35
+ if (arg === "--") {
36
+ parsingGlobalOptions = false;
37
+ continue;
38
+ }
39
+ if (!arg.startsWith("-") || arg === "-") {
40
+ parsingGlobalOptions = false;
41
+ continue;
42
+ }
43
+ if (arg === "--git-dir" || arg.startsWith("--git-dir=") || arg === "--work-tree" || arg.startsWith("--work-tree=") || arg === "-C") {
44
+ throw new Error(`Unsupported argument "${arg}". Use ${kleur.cyan("cd")} instead; ${kleur.cyan("instafy git")} manages --git-dir/--work-tree automatically.`);
45
+ }
46
+ // Skip the value for global options that consume the next token.
47
+ if (arg === "-c" || arg === "--config-env" || arg === "--exec-path" || arg === "--namespace") {
48
+ index += 1;
49
+ }
50
+ }
51
+ }
52
+ export function buildInstafyGitArgs(context, userArgs) {
53
+ validateGitArgs(userArgs);
54
+ return ["--git-dir", context.gitDir, "--work-tree", context.workTree, ...userArgs];
55
+ }
56
+ export function runInstafyGit(userArgs, options) {
57
+ const cwd = options?.cwd ?? process.cwd();
58
+ if (userArgs.length === 0 || userArgs[0] === "--help" || userArgs[0] === "-h") {
59
+ // Keep this minimal so it doesn't diverge from Git help output.
60
+ console.log("instafy git <git-args...>");
61
+ console.log("");
62
+ console.log(`Runs ${kleur.cyan("git")} against the Instafy canonical repo at ${kleur.cyan(".instafy/.git")} (auto-detected by walking up from cwd).`);
63
+ console.log("");
64
+ console.log("Example:");
65
+ console.log(` ${kleur.cyan('instafy git status')}`);
66
+ console.log(` ${kleur.cyan('instafy git commit -am "instafy: checkpoint"')}`);
67
+ return 0;
68
+ }
69
+ const context = findInstafyGitContext(cwd);
70
+ if (!context) {
71
+ throw new Error([
72
+ "No Instafy canonical git checkout found (expected .instafy/.git).",
73
+ "",
74
+ "Tips:",
75
+ `- Run this inside a git-canonical workspace (where ${kleur.cyan(".instafy/.git")} exists).`,
76
+ `- If you're trying to operate on a user repo, use normal ${kleur.cyan("git")} (it uses .git).`,
77
+ ].join("\n"));
78
+ }
79
+ const args = buildInstafyGitArgs(context, userArgs);
80
+ const result = spawnSync("git", args, { stdio: "inherit", cwd });
81
+ if (result.error) {
82
+ throw new Error(`Failed to run git: ${result.error.message}`);
83
+ }
84
+ return typeof result.status === "number" ? result.status : 1;
85
+ }
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import { listTunnelSessions, startTunnelDetached, stopTunnelSession, tailTunnelL
11
11
  import { requestControllerApi } from "./api.js";
12
12
  import { configGet, configList, configPath, configSet, configUnset } from "./config-command.js";
13
13
  import { getInstafyProfileConfigPath, listInstafyProfileNames, readInstafyProfileConfig } from "./config.js";
14
+ import { runInstafyGit } from "./git-wrapper.js";
14
15
  export const program = new Command();
15
16
  const require = createRequire(import.meta.url);
16
17
  const pkg = require("../package.json");
@@ -379,6 +380,10 @@ gitTokenCommand
379
380
  process.exit(1);
380
381
  }
381
382
  });
383
+ program
384
+ .command("git")
385
+ .description("Run git against the Instafy canonical checkout (.instafy/.git)")
386
+ .allowUnknownOption(true);
382
387
  program
383
388
  .command("git:credential", { hidden: true })
384
389
  .description("Internal: git credential helper (used by Git when configured)")
@@ -625,6 +630,12 @@ export async function runCli(argv = process.argv) {
625
630
  program.outputHelp();
626
631
  return;
627
632
  }
633
+ const args = argv.slice(2);
634
+ if (args[0] === "git") {
635
+ const code = runInstafyGit(args.slice(1));
636
+ process.exitCode = code;
637
+ return;
638
+ }
628
639
  await program.parseAsync(argv);
629
640
  }
630
641
  if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instafy/cli",
3
- "version": "0.1.8-staging.365",
3
+ "version": "0.1.8-staging.366",
4
4
  "description": "Run Instafy projects locally, link folders to Studio, and share previews/webhooks via tunnels.",
5
5
  "private": false,
6
6
  "publishConfig": {