@gh-symphony/cli 0.0.17 → 0.0.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/README.md +105 -9
- package/dist/{chunk-EFMFGOWM.js → chunk-6CI3UUMH.js} +282 -57
- package/dist/chunk-C7G7RJ4G.js +146 -0
- package/dist/{chunk-MHIWAIVD.js → chunk-GKENCODJ.js} +141 -53
- package/dist/{project-557FE2GD.js → chunk-H2YXSYOZ.js} +108 -92
- package/dist/{chunk-TF3QNWNC.js → chunk-M3IFVLQS.js} +246 -212
- package/dist/{chunk-IWR4UQEJ.js → chunk-RN2PACNV.js} +350 -523
- package/dist/chunk-TILHWBP6.js +638 -0
- package/dist/{chunk-6HBZC3BE.js → chunk-XN5ABWZ6.js} +23 -5
- package/dist/{chunk-76QPITKI.js → chunk-Y6TYJMNT.js} +1 -1
- package/dist/{config-cmd-AZ7POMAA.js → config-cmd-DNXNL26Z.js} +3 -1
- package/dist/doctor-IYHCFXOZ.js +1126 -0
- package/dist/index.js +157 -19
- package/dist/init-KZT6YNOH.js +33 -0
- package/dist/{logs-6LNGT2GF.js → logs-6JKKYDGJ.js} +1 -1
- package/dist/project-DNALEWO3.js +22 -0
- package/dist/{recover-LVBI2TGH.js → recover-C3V2QAUB.js} +3 -3
- package/dist/repo-HDDE7OUI.js +321 -0
- package/dist/{run-WITYAYFZ.js → run-XI2S5Y4V.js} +3 -3
- package/dist/setup-K4CYYJBF.js +431 -0
- package/dist/{start-JUFKNL3N.js → start-M6IQGRFO.js} +5 -5
- package/dist/{status-3WK5BWRZ.js → status-QSCFVGRQ.js} +2 -2
- package/dist/{stop-AA3AP5M6.js → stop-7MFCBQVW.js} +2 -2
- package/dist/upgrade-F4VE4XBS.js +165 -0
- package/dist/{version-YVM2A25J.js → version-Y5RYNWMF.js} +1 -1
- package/dist/worker-entry.js +39 -11
- package/dist/workflow-TBIFY5MO.js +497 -0
- package/package.json +4 -4
- package/dist/chunk-JO3AXHQI.js +0 -130
- package/dist/chunk-TH5QPO3Y.js +0 -67
- package/dist/init-EZXQAXZM.js +0 -17
- package/dist/repo-R3XBIVAX.js +0 -121
package/dist/chunk-JO3AXHQI.js
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/github/gh-auth.ts
|
|
4
|
-
import { execFileSync, spawnSync } from "child_process";
|
|
5
|
-
var REQUIRED_SCOPES = ["repo", "read:org", "project"];
|
|
6
|
-
var GhAuthError = class extends Error {
|
|
7
|
-
constructor(code, message) {
|
|
8
|
-
super(message);
|
|
9
|
-
this.code = code;
|
|
10
|
-
this.name = "GhAuthError";
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
function checkGhInstalled(opts) {
|
|
14
|
-
const execImpl = opts?.execImpl ?? execFileSync;
|
|
15
|
-
try {
|
|
16
|
-
execImpl("gh", ["--version"], { stdio: "pipe" });
|
|
17
|
-
return true;
|
|
18
|
-
} catch (error) {
|
|
19
|
-
const execError = error;
|
|
20
|
-
if (execError.code === "ENOENT") {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
throw error;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function checkGhAuthenticated(opts) {
|
|
27
|
-
const spawnImpl = opts?.spawnImpl ?? spawnSync;
|
|
28
|
-
const result = spawnImpl("gh", ["auth", "status"], {
|
|
29
|
-
encoding: "utf8",
|
|
30
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
31
|
-
});
|
|
32
|
-
if ((result.status ?? 1) !== 0) {
|
|
33
|
-
return { authenticated: false };
|
|
34
|
-
}
|
|
35
|
-
const login = parseLogin((result.stdout ?? "").toString());
|
|
36
|
-
return { authenticated: true, login };
|
|
37
|
-
}
|
|
38
|
-
function checkGhScopes(opts) {
|
|
39
|
-
const spawnImpl = opts?.spawnImpl ?? spawnSync;
|
|
40
|
-
const result = spawnImpl("gh", ["auth", "status"], {
|
|
41
|
-
encoding: "utf8",
|
|
42
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
43
|
-
});
|
|
44
|
-
const output = (result.stdout ?? "").toString();
|
|
45
|
-
const scopes = parseScopes(output);
|
|
46
|
-
if (scopes.length === 0) {
|
|
47
|
-
return { valid: true, missing: [], scopes: [] };
|
|
48
|
-
}
|
|
49
|
-
const normalized = scopes.map((scope) => scope.toLowerCase());
|
|
50
|
-
const missing = REQUIRED_SCOPES.filter(
|
|
51
|
-
(scope) => !normalized.includes(scope)
|
|
52
|
-
);
|
|
53
|
-
return {
|
|
54
|
-
valid: missing.length === 0,
|
|
55
|
-
missing: [...missing],
|
|
56
|
-
scopes
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
function getGhToken(opts) {
|
|
60
|
-
if (process.env.GITHUB_GRAPHQL_TOKEN) {
|
|
61
|
-
return process.env.GITHUB_GRAPHQL_TOKEN;
|
|
62
|
-
}
|
|
63
|
-
const execImpl = opts?.execImpl ?? execFileSync;
|
|
64
|
-
try {
|
|
65
|
-
const token = execImpl("gh", ["auth", "token"], {
|
|
66
|
-
encoding: "utf8",
|
|
67
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
68
|
-
}).toString().trim();
|
|
69
|
-
if (!token) {
|
|
70
|
-
throw new GhAuthError(
|
|
71
|
-
"token_failed",
|
|
72
|
-
"gh auth token \uC2E4\uD328. gh auth status \uB97C \uD655\uC778\uD558\uC138\uC694."
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
return token;
|
|
76
|
-
} catch (error) {
|
|
77
|
-
if (error instanceof GhAuthError) {
|
|
78
|
-
throw error;
|
|
79
|
-
}
|
|
80
|
-
throw new GhAuthError(
|
|
81
|
-
"token_failed",
|
|
82
|
-
"gh auth token \uC2E4\uD328. gh auth status \uB97C \uD655\uC778\uD558\uC138\uC694."
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function ensureGhAuth(opts) {
|
|
87
|
-
const execImpl = opts?.execImpl ?? execFileSync;
|
|
88
|
-
const spawnImpl = opts?.spawnImpl ?? spawnSync;
|
|
89
|
-
if (!checkGhInstalled({ execImpl })) {
|
|
90
|
-
throw new GhAuthError(
|
|
91
|
-
"not_installed",
|
|
92
|
-
"gh CLI\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. https://cli.github.com \uC5D0\uC11C \uC124\uCE58\uD558\uC138\uC694."
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
const auth = checkGhAuthenticated({ spawnImpl });
|
|
96
|
-
if (!auth.authenticated) {
|
|
97
|
-
throw new GhAuthError(
|
|
98
|
-
"not_authenticated",
|
|
99
|
-
"gh auth login --scopes repo,read:org,project \uB97C \uC2E4\uD589\uD558\uC138\uC694."
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
const scopeCheck = checkGhScopes({ spawnImpl });
|
|
103
|
-
if (!scopeCheck.valid) {
|
|
104
|
-
throw new GhAuthError(
|
|
105
|
-
"missing_scopes",
|
|
106
|
-
`gh auth refresh --scopes repo,read:org,project \uB97C \uC2E4\uD589\uD558\uC138\uC694. (missing: ${scopeCheck.missing.join(", ")})`
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
const token = getGhToken({ execImpl });
|
|
110
|
-
return { login: auth.login ?? "unknown", token };
|
|
111
|
-
}
|
|
112
|
-
function parseLogin(output) {
|
|
113
|
-
const matched = output.match(
|
|
114
|
-
/Logged in to github\.com account\s+\*?\*?([A-Za-z0-9_-]+)\*?\*?/i
|
|
115
|
-
);
|
|
116
|
-
return matched?.[1];
|
|
117
|
-
}
|
|
118
|
-
function parseScopes(output) {
|
|
119
|
-
const matched = output.match(/Token scopes:\s*(.+)/i);
|
|
120
|
-
if (!matched) {
|
|
121
|
-
return [];
|
|
122
|
-
}
|
|
123
|
-
return matched[1].split(",").map((scope) => scope.trim().replace(/^'+|'+$/g, "")).filter((scope) => scope.length > 0);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export {
|
|
127
|
-
GhAuthError,
|
|
128
|
-
getGhToken,
|
|
129
|
-
ensureGhAuth
|
|
130
|
-
};
|
package/dist/chunk-TH5QPO3Y.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
loadGlobalConfig,
|
|
4
|
-
loadProjectConfig
|
|
5
|
-
} from "./chunk-ROGRTUFI.js";
|
|
6
|
-
|
|
7
|
-
// src/project-selection.ts
|
|
8
|
-
import * as p from "@clack/prompts";
|
|
9
|
-
function isInteractiveTerminal() {
|
|
10
|
-
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
11
|
-
}
|
|
12
|
-
function explicitProjectRequiredMessage() {
|
|
13
|
-
return "Multiple projects are configured. Re-run with --project-id in non-interactive environments.\n";
|
|
14
|
-
}
|
|
15
|
-
async function resolveManagedProjectConfig(input) {
|
|
16
|
-
if (input.requestedProjectId) {
|
|
17
|
-
return loadProjectConfig(input.configDir, input.requestedProjectId);
|
|
18
|
-
}
|
|
19
|
-
const global = await loadGlobalConfig(input.configDir);
|
|
20
|
-
const projectIds = global?.projects ?? [];
|
|
21
|
-
if (projectIds.length === 0) {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
if (projectIds.length === 1) {
|
|
25
|
-
return loadProjectConfig(input.configDir, projectIds[0]);
|
|
26
|
-
}
|
|
27
|
-
if (!isInteractiveTerminal()) {
|
|
28
|
-
process.stderr.write(explicitProjectRequiredMessage());
|
|
29
|
-
process.exitCode = 1;
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
const projects = await Promise.all(
|
|
33
|
-
projectIds.map(async (projectId) => ({
|
|
34
|
-
projectId,
|
|
35
|
-
config: await loadProjectConfig(input.configDir, projectId)
|
|
36
|
-
}))
|
|
37
|
-
);
|
|
38
|
-
const selected = await p.select({
|
|
39
|
-
message: "Select a project:",
|
|
40
|
-
options: projects.map(({ projectId, config }) => ({
|
|
41
|
-
value: projectId,
|
|
42
|
-
label: config?.displayName ?? config?.slug ?? projectId,
|
|
43
|
-
hint: projectId === global?.activeProject ? "current" : config && config.displayName && config.displayName !== projectId ? projectId : void 0
|
|
44
|
-
})),
|
|
45
|
-
maxItems: 10
|
|
46
|
-
});
|
|
47
|
-
if (p.isCancel(selected)) {
|
|
48
|
-
p.cancel("Cancelled.");
|
|
49
|
-
process.exitCode = 130;
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return loadProjectConfig(input.configDir, selected);
|
|
53
|
-
}
|
|
54
|
-
function handleMissingManagedProjectConfig() {
|
|
55
|
-
if (process.exitCode) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
process.stderr.write(
|
|
59
|
-
"No project configured. Run 'gh-symphony project add' first.\n"
|
|
60
|
-
);
|
|
61
|
-
process.exitCode = 1;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export {
|
|
65
|
-
resolveManagedProjectConfig,
|
|
66
|
-
handleMissingManagedProjectConfig
|
|
67
|
-
};
|
package/dist/init-EZXQAXZM.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
abortIfCancelled,
|
|
4
|
-
generateProjectId,
|
|
5
|
-
init_default,
|
|
6
|
-
writeConfig,
|
|
7
|
-
writeEcosystem
|
|
8
|
-
} from "./chunk-IWR4UQEJ.js";
|
|
9
|
-
import "./chunk-JO3AXHQI.js";
|
|
10
|
-
import "./chunk-ROGRTUFI.js";
|
|
11
|
-
export {
|
|
12
|
-
abortIfCancelled,
|
|
13
|
-
init_default as default,
|
|
14
|
-
generateProjectId,
|
|
15
|
-
writeConfig,
|
|
16
|
-
writeEcosystem
|
|
17
|
-
};
|
package/dist/repo-R3XBIVAX.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
loadActiveProjectConfig,
|
|
4
|
-
loadGlobalConfig,
|
|
5
|
-
saveProjectConfig
|
|
6
|
-
} from "./chunk-ROGRTUFI.js";
|
|
7
|
-
|
|
8
|
-
// src/commands/repo.ts
|
|
9
|
-
var handler = async (args, options) => {
|
|
10
|
-
const [subcommand, ...rest] = args;
|
|
11
|
-
switch (subcommand) {
|
|
12
|
-
case "list":
|
|
13
|
-
await repoList(options);
|
|
14
|
-
break;
|
|
15
|
-
case "add":
|
|
16
|
-
await repoAdd(rest, options);
|
|
17
|
-
break;
|
|
18
|
-
case "remove":
|
|
19
|
-
await repoRemove(rest, options);
|
|
20
|
-
break;
|
|
21
|
-
default:
|
|
22
|
-
process.stderr.write(
|
|
23
|
-
"Usage: gh-symphony repo <list|add|remove> [repo]\n"
|
|
24
|
-
);
|
|
25
|
-
process.exitCode = 2;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
var repo_default = handler;
|
|
29
|
-
async function repoList(options) {
|
|
30
|
-
const ws = await loadActiveProjectConfig(options.configDir);
|
|
31
|
-
if (!ws) {
|
|
32
|
-
process.stderr.write("No project configured.\n");
|
|
33
|
-
process.exitCode = 1;
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (options.json) {
|
|
37
|
-
process.stdout.write(JSON.stringify(ws.repositories, null, 2) + "\n");
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
process.stdout.write("Repositories:\n");
|
|
41
|
-
for (const repo of ws.repositories) {
|
|
42
|
-
process.stdout.write(` ${repo.owner}/${repo.name}
|
|
43
|
-
`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
async function repoAdd(args, options) {
|
|
47
|
-
const [repoSpec] = args;
|
|
48
|
-
if (!repoSpec || !repoSpec.includes("/")) {
|
|
49
|
-
process.stderr.write("Usage: gh-symphony repo add <owner/name>\n");
|
|
50
|
-
process.exitCode = 2;
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const global = await loadGlobalConfig(options.configDir);
|
|
54
|
-
if (!global?.activeProject) {
|
|
55
|
-
process.stderr.write("No active project.\n");
|
|
56
|
-
process.exitCode = 1;
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const ws = await loadActiveProjectConfig(options.configDir);
|
|
60
|
-
if (!ws) {
|
|
61
|
-
process.stderr.write("Project config missing.\n");
|
|
62
|
-
process.exitCode = 1;
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const [owner, name] = repoSpec.split("/");
|
|
66
|
-
if (!owner || !name) {
|
|
67
|
-
process.stderr.write("Invalid repo format. Use: owner/name\n");
|
|
68
|
-
process.exitCode = 2;
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (ws.repositories.some((r) => r.owner === owner && r.name === name)) {
|
|
72
|
-
process.stdout.write(`Repository ${repoSpec} is already configured.
|
|
73
|
-
`);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
ws.repositories.push({
|
|
77
|
-
owner,
|
|
78
|
-
name,
|
|
79
|
-
cloneUrl: `https://github.com/${owner}/${name}.git`
|
|
80
|
-
});
|
|
81
|
-
await saveProjectConfig(options.configDir, global.activeProject, ws);
|
|
82
|
-
process.stdout.write(`Added repository: ${repoSpec}
|
|
83
|
-
`);
|
|
84
|
-
}
|
|
85
|
-
async function repoRemove(args, options) {
|
|
86
|
-
const [repoSpec] = args;
|
|
87
|
-
if (!repoSpec || !repoSpec.includes("/")) {
|
|
88
|
-
process.stderr.write("Usage: gh-symphony repo remove <owner/name>\n");
|
|
89
|
-
process.exitCode = 2;
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
const global = await loadGlobalConfig(options.configDir);
|
|
93
|
-
if (!global?.activeProject) {
|
|
94
|
-
process.stderr.write("No active project.\n");
|
|
95
|
-
process.exitCode = 1;
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const ws = await loadActiveProjectConfig(options.configDir);
|
|
99
|
-
if (!ws) {
|
|
100
|
-
process.stderr.write("Project config missing.\n");
|
|
101
|
-
process.exitCode = 1;
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
const [owner, name] = repoSpec.split("/");
|
|
105
|
-
const idx = ws.repositories.findIndex(
|
|
106
|
-
(r) => r.owner === owner && r.name === name
|
|
107
|
-
);
|
|
108
|
-
if (idx === -1) {
|
|
109
|
-
process.stderr.write(`Repository ${repoSpec} is not configured.
|
|
110
|
-
`);
|
|
111
|
-
process.exitCode = 1;
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
ws.repositories.splice(idx, 1);
|
|
115
|
-
await saveProjectConfig(options.configDir, global.activeProject, ws);
|
|
116
|
-
process.stdout.write(`Removed repository: ${repoSpec}
|
|
117
|
-
`);
|
|
118
|
-
}
|
|
119
|
-
export {
|
|
120
|
-
repo_default as default
|
|
121
|
-
};
|