@itcase/config 1.6.76 → 1.6.77
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 +2 -2
- package/package.json +4 -4
- package/smart-commit/cli.js +31 -4
- package/smart-commit/dancing-banana.js +339 -224
- package/smart-commit/nyan-cat.js +327 -0
- package/smart-commit/scripts/extract-banana.py +0 -255
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ npm install --save-dev commitizen @commitlint/cz-commitlint
|
|
|
87
87
|
|
|
88
88
|
## Smart commit
|
|
89
89
|
|
|
90
|
-
`smart-commit` — Cursor Agent (`ask`) планирует коммиты по `SCOPES`, печатает сообщения, спрашивает `[y/N]`.
|
|
90
|
+
`smart-commit` — Cursor Agent (`ask`) планирует коммиты по `SCOPES`, печатает сообщения, спрашивает `[y/N]`. Перед коммитом ждёт и снимает устаревший `.git/index.lock`, если его никто не держит.
|
|
91
91
|
|
|
92
92
|
```text
|
|
93
93
|
[yellow pixel banana animation]
|
|
@@ -146,7 +146,7 @@ CLI ставится в `~/.local/bin`. Логин в Cursor IDE этот CLI н
|
|
|
146
146
|
|
|
147
147
|
Обновление CLI: `agent update`.
|
|
148
148
|
|
|
149
|
-
Пока Agent думает, в терминале крутится pixel-анимация dancing banana + статус `(Ns)` на одной области экрана (`log-update`). Для полного лога: `npm run smart-commit -- --verbose --dry-run`.
|
|
149
|
+
Пока Agent думает, в терминале крутится pixel-анимация (случайно nyan cat или dancing banana) + статус `(Ns)` на одной области экрана (`log-update`). Принудительно: `--cat` / `--banana`. Для полного лога: `npm run smart-commit -- --verbose --dry-run`.
|
|
150
150
|
|
|
151
151
|
> **Важно:** в npm есть одноимённый пакет `smart-commit`. Используйте `npm run smart-commit` из проекта с `@itcase/config` — bin берётся из `node_modules`. `npx smart-commit` без локальной установки может подтянуть чужой пакет; CLI перед запуском проверяет, что выполняется именно `@itcase/config`.
|
|
152
152
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itcase/config",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.77",
|
|
4
4
|
"author": "ITCase",
|
|
5
5
|
"description": "ITCase Config",
|
|
6
6
|
"engines": {
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
"chokidar-cli": "^3.0.0",
|
|
68
68
|
"commitizen": "^4.3.2",
|
|
69
69
|
"conventional-changelog-conventionalcommits": "9.3.1",
|
|
70
|
-
"cssnano": "^9.0.
|
|
71
|
-
"cssnano-preset-default": "^9.0.
|
|
70
|
+
"cssnano": "^9.0.2",
|
|
71
|
+
"cssnano-preset-default": "^9.0.2",
|
|
72
72
|
"inquirer": "^14.2.0",
|
|
73
73
|
"log-update": "^8.0.0",
|
|
74
74
|
"postcss": "^8.5.26",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"postcss-combine-duplicated-selectors": "^10.0.3",
|
|
80
80
|
"postcss-convert-unit": "^0.1.3",
|
|
81
81
|
"postcss-dark-theme-class": "^2.0.0",
|
|
82
|
-
"postcss-discard-duplicates": "^9.0.
|
|
82
|
+
"postcss-discard-duplicates": "^9.0.1",
|
|
83
83
|
"postcss-each": "^1.1.0",
|
|
84
84
|
"postcss-easings": "^4.0.0",
|
|
85
85
|
"postcss-extend-rule": "^4.0.0",
|
package/smart-commit/cli.js
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
promptSubjectRules,
|
|
17
17
|
} from '../commitlint/commitlintCommon.js'
|
|
18
18
|
import { getBananaFrame } from './dancing-banana.js'
|
|
19
|
+
import { getNyanFrame } from './nyan-cat.js'
|
|
19
20
|
|
|
20
21
|
const PACKAGE_NAME = '@itcase/config'
|
|
21
22
|
const CLI_RELATIVE = 'smart-commit/cli.js'
|
|
@@ -23,6 +24,7 @@ const CLI_RELATIVE = 'smart-commit/cli.js'
|
|
|
23
24
|
const MAX_DIFF = 80_000
|
|
24
25
|
const AGENT_TIMEOUT_MS = 120_000
|
|
25
26
|
const AGENT_STEP_MS = 2_500
|
|
27
|
+
const NYAN_FRAME_MS = 90
|
|
26
28
|
const BANANA_FRAME_MS = 100
|
|
27
29
|
const INDEX_LOCK_RETRIES = 8
|
|
28
30
|
const INDEX_LOCK_WAIT_MS = 250
|
|
@@ -33,10 +35,13 @@ const AGENT_WAIT_STEPS = [
|
|
|
33
35
|
'Waiting for response',
|
|
34
36
|
]
|
|
35
37
|
const HELP = `smart-commit [--dry-run] [--yes|-y] [--type t] [--model id] [--verbose]
|
|
38
|
+
[--cat|--nyan] [--banana]
|
|
36
39
|
|
|
37
40
|
Cursor Agent → commit messages by SCOPES → [y/N] → git commit
|
|
38
41
|
Run via: npm exec smart-commit (from project with @itcase/config)
|
|
39
42
|
Needs: agent login (or CURSOR_API_KEY) + commitlint.config.* with SCOPES
|
|
43
|
+
|
|
44
|
+
Progress sprite is random (nyan cat or banana). Force with --cat or --banana.
|
|
40
45
|
`
|
|
41
46
|
const AGENT_MISSING = `Cursor Agent CLI not found — smart-commit cannot run.
|
|
42
47
|
|
|
@@ -74,7 +79,11 @@ async function main(argv) {
|
|
|
74
79
|
|
|
75
80
|
const prompt = buildPrompt(scopes, types, files, cwd, option.type)
|
|
76
81
|
const raw = await withAgentProgress(
|
|
77
|
-
{
|
|
82
|
+
{
|
|
83
|
+
fileCount: files.length,
|
|
84
|
+
sprite: pickSprite(option.sprite),
|
|
85
|
+
verbose: option.verbose,
|
|
86
|
+
},
|
|
78
87
|
(progress) =>
|
|
79
88
|
askAgent(
|
|
80
89
|
cwd,
|
|
@@ -157,6 +166,7 @@ function parseArgs(argv) {
|
|
|
157
166
|
type: '',
|
|
158
167
|
dryRun: false,
|
|
159
168
|
model: '',
|
|
169
|
+
sprite: '',
|
|
160
170
|
staged: false,
|
|
161
171
|
verbose: false,
|
|
162
172
|
yes: false,
|
|
@@ -167,6 +177,8 @@ function parseArgs(argv) {
|
|
|
167
177
|
else if (arg === '--yes' || arg === '-y') option.yes = true
|
|
168
178
|
else if (arg === '--verbose') option.verbose = true
|
|
169
179
|
else if (arg === '--staged') option.staged = true
|
|
180
|
+
else if (arg === '--cat' || arg === '--nyan') option.sprite = 'cat'
|
|
181
|
+
else if (arg === '--banana') option.sprite = 'banana'
|
|
170
182
|
else if (arg === '--type') option.type = argv[++i] || ''
|
|
171
183
|
else if (arg === '--model') option.model = argv[++i] || ''
|
|
172
184
|
else if (arg.startsWith('--type=')) option.type = arg.slice(7)
|
|
@@ -176,6 +188,11 @@ function parseArgs(argv) {
|
|
|
176
188
|
return option
|
|
177
189
|
}
|
|
178
190
|
|
|
191
|
+
function pickSprite(forced) {
|
|
192
|
+
if (forced === 'cat' || forced === 'banana') return forced
|
|
193
|
+
return Math.random() < 0.5 ? 'cat' : 'banana'
|
|
194
|
+
}
|
|
195
|
+
|
|
179
196
|
function assertItcaseConfigPackage(cwd) {
|
|
180
197
|
const scriptPath = fileURLToPath(import.meta.url)
|
|
181
198
|
|
|
@@ -381,13 +398,21 @@ async function withAgentProgress(context, callback) {
|
|
|
381
398
|
return callback({ onAgentActivity })
|
|
382
399
|
}
|
|
383
400
|
|
|
401
|
+
const columns = process.stderr.columns || process.stdout.columns || 80
|
|
402
|
+
const rows = process.stderr.rows || process.stdout.rows || 24
|
|
403
|
+
const getFrame =
|
|
404
|
+
context.sprite === 'cat'
|
|
405
|
+
? (index) => getNyanFrame(index, columns)
|
|
406
|
+
: (index) => getBananaFrame(index, columns, rows)
|
|
407
|
+
const frameMs = context.sprite === 'cat' ? NYAN_FRAME_MS : BANANA_FRAME_MS
|
|
408
|
+
process.stderr.write('\x1b[?7l')
|
|
409
|
+
|
|
384
410
|
const render = () => {
|
|
385
|
-
logUpdateStderr(`${
|
|
411
|
+
logUpdateStderr(`${getFrame(frameIndex)}\n${formatText()}`)
|
|
386
412
|
frameIndex++
|
|
387
413
|
}
|
|
388
414
|
|
|
389
|
-
render
|
|
390
|
-
const frameTimer = setInterval(render, BANANA_FRAME_MS)
|
|
415
|
+
const frameTimer = setInterval(render, frameMs)
|
|
391
416
|
const stepTimer = setInterval(() => {
|
|
392
417
|
if (phase === 'early') {
|
|
393
418
|
if (earlyStepIndex < earlySteps.length - 1) {
|
|
@@ -401,11 +426,13 @@ async function withAgentProgress(context, callback) {
|
|
|
401
426
|
}, AGENT_STEP_MS)
|
|
402
427
|
|
|
403
428
|
try {
|
|
429
|
+
render()
|
|
404
430
|
return await callback({ onAgentActivity })
|
|
405
431
|
} finally {
|
|
406
432
|
clearInterval(frameTimer)
|
|
407
433
|
clearInterval(stepTimer)
|
|
408
434
|
logUpdateStderr.clear()
|
|
435
|
+
process.stderr.write('\x1b[?7h')
|
|
409
436
|
}
|
|
410
437
|
}
|
|
411
438
|
|