@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 +1 -0
- package/dist/git-wrapper.js +85 -0
- package/dist/index.js +11 -0
- package/package.json +1 -1
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