skillgauntlet 1.3.6 → 1.3.8
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/lib/github.js +14 -2
- package/lib/i18n.js +3 -0
- package/lib/submit.js +24 -4
- package/package.json +1 -1
package/lib/github.js
CHANGED
|
@@ -110,16 +110,28 @@ export async function ensureTool(tool, { exec = quiet, run = live, pick, out, pl
|
|
|
110
110
|
export const signedIn = (exec = quiet) => { try { exec('gh', ['auth', 'status']); return true; } catch { return false; } };
|
|
111
111
|
|
|
112
112
|
// The GitHub sign-in: the CLI's own browser flow (it shows a one-time code and opens the browser after enter).
|
|
113
|
+
// The arguments of the browser sign-in for the installed gh. `-p https` (the git protocol) exists only in newer versions;
|
|
114
|
+
// the gh in an older Ubuntu's own repositories rejects it ("unknown shorthand flag: 'p'"), so it is added only when this
|
|
115
|
+
// gh lists it, and otherwise gh asks that one question itself.
|
|
116
|
+
export function loginArgs(exec = quiet) {
|
|
117
|
+
let help = '';
|
|
118
|
+
try { help = String(exec('gh', ['auth', 'login', '--help'])); } catch (err) { help = `${err.stdout || ''}${err.stderr || ''}`; }
|
|
119
|
+
const args = ['auth', 'login', '-h', 'github.com', '-w'];
|
|
120
|
+
return /--git-protocol/.test(help) ? [...args, '-p', 'https'] : args;
|
|
121
|
+
}
|
|
122
|
+
|
|
113
123
|
export async function ensureSignedIn({ exec = quiet, run = live, pick, out } = {}) {
|
|
114
124
|
while (!signedIn(exec)) {
|
|
115
125
|
out(`\n${t('ghLoginNeeded')}`);
|
|
126
|
+
const args = loginArgs(exec);
|
|
116
127
|
const choice = await pick(t('ghLoginQ'), [
|
|
117
|
-
{ label: t('ghLoginNow'), hint: t('toolRuns', { cmd:
|
|
128
|
+
{ label: t('ghLoginNow'), hint: t('toolRuns', { cmd: `gh ${args.join(' ')}` }), value: 'now' },
|
|
118
129
|
{ label: t('ghLoginSkip'), value: 'skip' },
|
|
119
130
|
], 1);
|
|
120
131
|
if (choice !== 'now') return false;
|
|
121
132
|
out(`\n${t('ghLoginHint')}\n`);
|
|
122
|
-
run('gh',
|
|
133
|
+
const r = run('gh', args);
|
|
134
|
+
if (r?.error || (r && r.status != null && r.status !== 0)) out(`\n${t('ghLoginFailed')}`);
|
|
123
135
|
}
|
|
124
136
|
return true;
|
|
125
137
|
}
|
package/lib/i18n.js
CHANGED
|
@@ -168,6 +168,7 @@ const MESSAGES = {
|
|
|
168
168
|
prTimeout: '等了 {m} 分钟还没合并,PR 还在:{url},之后随时在浏览器里看。',
|
|
169
169
|
toolSudo: '这一步要用管理员权限安装:下面可能会让你输入这台电脑的登录密码(输入时不会显示字符,输完按回车)。',
|
|
170
170
|
hostInstallUserDir: '这台电脑的 npm 全局目录你没有写权限(装到系统目录要 sudo),所以会装到你自己的目录:{dir},不需要 sudo 和密码。',
|
|
171
|
+
ghLoginFailed: '登录没有完成(上面是 gh 自己的提示)。可以再试一次,或先选“先不登录”,之后自己运行 gh auth login。',
|
|
171
172
|
modelUnknown: '{host} 的模型清单里没有“{model}”。它现在支持:{list}。请重新选一个,或选“默认模型”。',
|
|
172
173
|
updateAvail: '有新版本 {latest}(你现在用的是 {current})。',
|
|
173
174
|
updateQ: '要更新吗?',
|
|
@@ -601,6 +602,7 @@ const MESSAGES = {
|
|
|
601
602
|
prTimeout: 'Waited {m} minutes and it is not merged yet. The pull request is still there: {url}; look any time in the browser.',
|
|
602
603
|
toolSudo: 'This install needs administrator rights: you may be asked for this computer\'s password below (nothing is shown as you type; press enter when done).',
|
|
603
604
|
hostInstallUserDir: 'You cannot write to this computer\'s global npm folder (installing there needs sudo), so it is installed into your own folder instead: {dir}. No sudo or password is needed.',
|
|
605
|
+
ghLoginFailed: 'The sign-in did not finish (gh\'s own message is above). Try again, or choose "Not now" and run gh auth login yourself later.',
|
|
604
606
|
modelUnknown: '{host} does not list a model called "{model}". It currently supports: {list}. Pick another, or choose the default model.',
|
|
605
607
|
updateAvail: 'A newer version {latest} is available (you are on {current}).',
|
|
606
608
|
updateQ: 'Update?',
|
|
@@ -1082,6 +1084,7 @@ Layer 0 always runs first: it is free, and it disqualifies most problems before
|
|
|
1082
1084
|
prTimeout: '{m} 分待ちましたがまだマージされていません。プルリクエストは残っています:{url}。いつでもブラウザで確認できます。',
|
|
1083
1085
|
toolSudo: 'このインストールには管理者権限が必要です。このコンピューターのパスワードの入力を求められることがあります(入力中は何も表示されません。入力後に Enter)。',
|
|
1084
1086
|
hostInstallUserDir: 'このコンピューターのグローバル npm フォルダには書き込めません(sudo が必要)。代わりにあなた自身のフォルダ {dir} にインストールします。sudo もパスワードも不要です。',
|
|
1087
|
+
ghLoginFailed: 'サインインが完了しませんでした(上は gh 自身のメッセージです)。もう一度試すか、「今はしない」を選んで後で gh auth login を実行してください。',
|
|
1085
1088
|
modelUnknown: '{host} のモデル一覧に「{model}」はありません。現在対応:{list}。別のものを選ぶか、既定のモデルを選んでください。',
|
|
1086
1089
|
updateAvail: '新しいバージョン {latest} があります(現在は {current})。',
|
|
1087
1090
|
updateQ: '更新しますか?',
|
package/lib/submit.js
CHANGED
|
@@ -92,15 +92,36 @@ function prBody(pkg) {
|
|
|
92
92
|
].join('\n');
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
// A fork that was just created is not always cloneable at once; try a few times, a few seconds apart.
|
|
96
|
+
function cloneWithRetry(exec, url, dir, { tries = 5, waitMs = 3000 } = {}) {
|
|
97
|
+
let last;
|
|
98
|
+
for (let i = 0; i < tries; i += 1) {
|
|
99
|
+
try {
|
|
100
|
+
exec('git', ['clone', '--depth', '1', '-c', 'credential.helper=', '-c', 'credential.https://github.com.helper=!gh auth git-credential', url, dir]);
|
|
101
|
+
return;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
last = err;
|
|
104
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
105
|
+
if (i < tries - 1) Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, waitMs);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
throw last;
|
|
109
|
+
}
|
|
110
|
+
|
|
95
111
|
// Fork, branch, commit, push, open. Every GitHub call goes through `exec` so tests can fake them.
|
|
96
|
-
export function openPullRequest({ pkgDir, pkg, gh, exec = defaultExec, say: out = say }) {
|
|
112
|
+
export function openPullRequest({ pkgDir, pkg, gh, exec = defaultExec, say: out = say, cloneWait = 3000 }) {
|
|
97
113
|
const work = fs.mkdtempSync(path.join(os.tmpdir(), 'sg-pr-'));
|
|
98
114
|
try {
|
|
99
115
|
out(t('submitForking', { upstream: UPSTREAM }));
|
|
100
116
|
exec('gh', ['repo', 'fork', UPSTREAM, '--clone=false']);
|
|
101
117
|
out(t('submitPreparing'));
|
|
102
118
|
const repoDir = path.join(work, 'repo');
|
|
103
|
-
|
|
119
|
+
const forkUrl = `https://github.com/${gh.user}/${UPSTREAM.split('/')[1]}.git`;
|
|
120
|
+
// The branch is made from the contributor's own fork, not from upstream's main. A fork made before upstream gained
|
|
121
|
+
// workflow files lacks them, and pushing a branch built on upstream's main would then "create" those workflows in
|
|
122
|
+
// the fork, which GitHub refuses for a token without the `workflow` scope (the default gh sign-in has none). A branch
|
|
123
|
+
// made on the fork adds only the submission, and the pull request's diff against upstream is still just that.
|
|
124
|
+
cloneWithRetry(exec, forkUrl, repoDir, { waitMs: cloneWait });
|
|
104
125
|
const g = (...a) => exec('git', ['-C', repoDir, ...a]);
|
|
105
126
|
const branch = `submit/${slug(pkg.files.meta.skill)}-${pkg.files.meta.submission.host.id}-${pkg.path[2].split('-')[0].toLowerCase()}`;
|
|
106
127
|
g('checkout', '-b', branch);
|
|
@@ -115,8 +136,7 @@ export function openPullRequest({ pkgDir, pkg, gh, exec = defaultExec, say: out
|
|
|
115
136
|
const ident = ['-c', `user.name=${gh.user}`, '-c', `user.email=${gh.id}+${gh.user}@users.noreply.github.com`];
|
|
116
137
|
g(...ident, 'commit', '-q', '-F', msg);
|
|
117
138
|
out(t('submitPushing'));
|
|
118
|
-
g('
|
|
119
|
-
g('-c', 'credential.helper=', '-c', 'credential.https://github.com.helper=!gh auth git-credential', 'push', '-q', 'fork', branch);
|
|
139
|
+
g('-c', 'credential.helper=', '-c', 'credential.https://github.com.helper=!gh auth git-credential', 'push', '-q', 'origin', branch);
|
|
120
140
|
out(t('submitOpening'));
|
|
121
141
|
const body = path.join(work, 'body.md');
|
|
122
142
|
fs.writeFileSync(body, prBody(pkg));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillgauntlet",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"description": "Check an agent skill before you install it: context cost, permission surface, code risk, instruction hijacking, description quality, trigger rate and gain.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|