@nan0web/release 1.0.2 → 3.1.0

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.
Files changed (57) hide show
  1. package/README.md +42 -17
  2. package/bin/nan0release.js +3 -39
  3. package/knip.json +21 -0
  4. package/nan0web.nan0 +16 -0
  5. package/package.json +48 -49
  6. package/project.yaml +79 -0
  7. package/src/README.md.js +463 -0
  8. package/src/Release/Person.js +1 -1
  9. package/src/agents/inspectors/git-reviewer.md +35 -0
  10. package/src/agents/inspectors/package-hygiene.md +63 -0
  11. package/src/agents/workflows/commit.md +28 -0
  12. package/src/agents/workflows/npm-release.md +40 -0
  13. package/src/agents/workflows/release.md +205 -0
  14. package/src/agents/workflows/zero-tolerance-git.md +21 -0
  15. package/src/domain/App.js +33 -0
  16. package/src/domain/CheckCommand.js +193 -0
  17. package/src/domain/CloseCommand.js +68 -0
  18. package/src/domain/DepsCommand.js +104 -0
  19. package/src/domain/InitCommand.js +57 -0
  20. package/src/domain/PublishCommand.js +89 -0
  21. package/src/domain/SpecCommand.js +43 -0
  22. package/src/domain/StatusCommand.js +25 -0
  23. package/src/index.js +9 -0
  24. package/types/Release/Person.d.ts +3 -3
  25. package/types/Team.d.ts +3 -3
  26. package/types/commands/CheckCommand.d.ts +24 -0
  27. package/types/commands/CloseCommand.d.ts +2 -1
  28. package/types/commands/Command.d.ts +6 -1
  29. package/types/commands/DepsCommand.d.ts +2 -1
  30. package/types/commands/InitCommand.d.ts +2 -1
  31. package/types/commands/PublishCommand.d.ts +2 -1
  32. package/types/commands/SpecCommand.d.ts +2 -1
  33. package/types/domain/App.d.ts +16 -0
  34. package/types/domain/CheckCommand.d.ts +24 -0
  35. package/types/domain/CloseCommand.d.ts +17 -0
  36. package/types/domain/DepsCommand.d.ts +22 -0
  37. package/types/domain/InitCommand.d.ts +18 -0
  38. package/types/domain/PublishCommand.d.ts +27 -0
  39. package/types/domain/SpecCommand.d.ts +17 -0
  40. package/types/domain/StatusCommand.d.ts +7 -0
  41. package/types/index.d.ts +8 -0
  42. package/types/ui/cli/index.d.ts +1 -0
  43. package/types/utils/runSpawn.d.ts +1 -0
  44. package/src/Team.js +0 -35
  45. package/src/cli/index.js +0 -9
  46. package/src/co/AppCommandOptions.js +0 -25
  47. package/src/commands/CloseCommand.js +0 -67
  48. package/src/commands/Command.js +0 -48
  49. package/src/commands/DepsCommand.js +0 -143
  50. package/src/commands/InitCommand.js +0 -57
  51. package/src/commands/PublishCommand.js +0 -105
  52. package/src/commands/SpecCommand.js +0 -41
  53. package/src/commands/StatusCommand.js +0 -26
  54. package/src/db/ReleaseDB.js +0 -54
  55. package/src/ui/cli/ReleaseCLi.js +0 -52
  56. package/src/ui/cli/index.js +0 -0
  57. package/src/utils/runSpawn.js +0 -0
@@ -0,0 +1,463 @@
1
+ import { describe, it, before, beforeEach } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { readFile } from 'node:fs/promises'
4
+ import FS from '@nan0web/db-fs'
5
+ import { NoConsole } from '@nan0web/log'
6
+ import { DatasetParser, DocsParser, runSpawn } from '@nan0web/test'
7
+ import { App } from './index.js'
8
+ import Release from './Release.js'
9
+ import ReleaseDocument from './Release/Document.js'
10
+ import Person from './Release/Person.js'
11
+ import {
12
+ ProjectManagement,
13
+ ReleaseManager,
14
+ TaskTestSuite,
15
+ ChangelogTaskManager,
16
+ } from './architecture/ProjectManagementAsCode.js'
17
+
18
+ const fs = new FS()
19
+ let pkg
20
+
21
+ // Load package.json once before tests
22
+ before(async () => {
23
+ const doc = await fs.loadDocument('package.json', {})
24
+ pkg = doc || {}
25
+ })
26
+
27
+ let console = new NoConsole()
28
+
29
+ beforeEach(() => {
30
+ console = new NoConsole()
31
+ })
32
+
33
+ /**
34
+ * Core test suite that also serves as the source for README generation.
35
+ *
36
+ * The block comments inside each `it` block are extracted to build
37
+ * the final `README.md`. Keeping the comments here ensures the
38
+ * documentation stays close to the code.
39
+ */
40
+ function testRender() {
41
+ /**
42
+ * @docs
43
+ * # @nan0web/release
44
+ *
45
+ * <!-- %PACKAGE_STATUS% -->
46
+ *
47
+ * Project management as code, Git-native, GPG-signed, and test-driven.
48
+ *
49
+ * Unlike traditional project tools that require constant syncing or manual updates,
50
+ * `@nan0web/release` enforces project structure where:
51
+ * - Tasks are represented as tests in `.test.js` files.
52
+ * - Status is tracked via test outcomes.
53
+ * - Team roles and approvals are stored in structured files.
54
+ * - All changes are signed, versioned, and composable.
55
+ *
56
+ * This ensures:
57
+ * - Clear, automatable project tracking.
58
+ * - Immutable release notes and retro reflections.
59
+ * - Zero ambiguity – tasks don't exist unless tested.
60
+ *
61
+ * ## Installation
62
+ */
63
+ it('How to install with pnpm?', () => {
64
+ /**
65
+ * ```bash
66
+ * pnpm add @nan0web/release
67
+ * ```
68
+ */
69
+ assert.equal(pkg.name, '@nan0web/release')
70
+ })
71
+ /**
72
+ * @docs
73
+ */
74
+ it('How to install with npm?', () => {
75
+ /**
76
+ * ```bash
77
+ * npm install @nan0web/release
78
+ * ```
79
+ */
80
+ assert.equal(pkg.name, '@nan0web/release')
81
+ })
82
+ /**
83
+ * @docs
84
+ */
85
+ it('How to install with yarn?', () => {
86
+ /**
87
+ * ```bash
88
+ * yarn add @nan0web/release
89
+ * ```
90
+ */
91
+ assert.equal(pkg.name, '@nan0web/release')
92
+ })
93
+
94
+ /**
95
+ * @docs
96
+ * ## CLI Usage
97
+ *
98
+ * Start by initializing a new release:
99
+ */
100
+ it('How to initialize a new release version?', () => {
101
+ /**
102
+ * ```bash
103
+ * nan0release init v1.0.0
104
+ * ```
105
+ */
106
+ assert.ok(new App().constructor.command.options)
107
+ })
108
+
109
+ /**
110
+ * @docs
111
+ * Show release details:
112
+ */
113
+ it('How to show release information?', () => {
114
+ /**
115
+ * ```bash
116
+ * release show [--full]
117
+ * ```
118
+ */
119
+ const release = new Release({
120
+ version: 'v1.0.0',
121
+ createdAt: new Date('2025-08-20'),
122
+ })
123
+ console.info(release.version) // v1.0.0
124
+ assert.strictEqual(console.output()[0][1], 'v1.0.0')
125
+ })
126
+
127
+ /**
128
+ * @docs
129
+ * List all releases in the project:
130
+ */
131
+ it('How to list all releases?', () => {
132
+ /**
133
+ * ```bash
134
+ * nan0release list [--json]
135
+ * ```
136
+ */
137
+ assert.ok(new App().constructor.command.options)
138
+ })
139
+
140
+ /**
141
+ * @docs
142
+ * Add a chat message to the current release:
143
+ */
144
+ it('How to write a release chat message?', () => {
145
+ /**
146
+ * ```bash
147
+ * nan0release chat write --user alice "Issue with the build pipeline"
148
+ * ```
149
+ */
150
+ assert.ok(new App().constructor.command.options)
151
+ })
152
+
153
+ /**
154
+ * @docs
155
+ * Host a static server for viewing releases:
156
+ */
157
+ it('How to host release UI?', () => {
158
+ /**
159
+ * ```bash
160
+ * nan0release host [--webui] [--port 3000]
161
+ * ```
162
+ */
163
+ assert.ok(new App().constructor.command.options)
164
+ })
165
+
166
+ /**
167
+ * @docs
168
+ * Serve all release files for local inspection:
169
+ */
170
+ it('How to serve release static assets?', () => {
171
+ /**
172
+ * ```bash
173
+ * nan0release serve [--port 8080]
174
+ * ```
175
+ */
176
+ assert.ok(new App().constructor.command.options)
177
+ })
178
+
179
+ /**
180
+ * @docs
181
+ * Validate release tasks and integrity:
182
+ */
183
+ it('How to validate release tasks?', () => {
184
+ /**
185
+ * ```bash
186
+ * nan0release validate [--ignore-fail]
187
+ * ```
188
+ */
189
+ assert.ok(true)
190
+ const release = new Release({
191
+ version: 'v1.0.0',
192
+ createdAt: new Date('2025-08-20'),
193
+ })
194
+ assert.ok(release instanceof Release)
195
+ })
196
+
197
+ /**
198
+ * @docs
199
+ * Seal the release with retro reflection:
200
+ */
201
+ it('How to seal a release?', () => {
202
+ /**
203
+ * ```bash
204
+ * nan0release seal [--message "All core APIs are stable and tested"]
205
+ * ```
206
+ */
207
+ assert.ok(new App().constructor.command.options)
208
+ })
209
+
210
+ /**
211
+ * @docs
212
+ * ## Core Concepts
213
+ *
214
+ * ### 1. Release as Object
215
+ *
216
+ * A `Release` is a structured class containing:
217
+ * - `version`: release identifier (vX.Y.Z).
218
+ * - `createdAt`, `startAt`, `planAt`, `completeAt`: datetime milestones.
219
+ * - `document`: parsed markdown document with structure-aware parsing.
220
+ *
221
+ * Each property is typed and validated automatically via JSDoc and runtime parsing.
222
+ */
223
+ it('How to instantiate a Release?', () => {
224
+ //import { Release } from '@nan0web/release'
225
+ const release = new Release({
226
+ version: 'v1.0.0',
227
+ createdAt: '2025-08-20T10:00:00Z',
228
+ })
229
+ console.info(release.version) // ← v1.0.0
230
+ console.info(release.createdAt instanceof Date) // ← true
231
+
232
+ assert.strictEqual(console.output()[0][1], 'v1.0.0')
233
+ assert.strictEqual(console.output()[1][1], true)
234
+ })
235
+
236
+ /**
237
+ * @docs
238
+ * ### 2. Release Document Parsing
239
+ *
240
+ * A `ReleaseDocument` extends `@nan0web/markdown` with:
241
+ * - Structured parsing of markdown release notes
242
+ * - Extraction of sections and tasks
243
+ * - Team and role parsing from markdown frontmatter or code
244
+ */
245
+ it('How to parse release notes markdown into structured data?', () => {
246
+ //import { ReleaseDocument } from '@nan0web/release'
247
+ const md = `# v1.0.0 - 2025-08-20
248
+
249
+ ## Overview
250
+ Release milestone includes UI polish and core API stabilization.
251
+
252
+ ### Tasks
253
+ ### Done **Implement core UI design** [ui.core-design]
254
+ ### InProgress **Fix responsive issues in mobile layout** [ui.mobile-fixes]`
255
+
256
+ const doc = ReleaseDocument.from(md)
257
+ console.info(doc.version) // ← v1.0.0
258
+ console.info(doc.date instanceof Date) // ← true
259
+ console.info(doc.document.children instanceof Array) // ← true
260
+
261
+ assert.strictEqual(console.output()[0][1], 'v1.0.0')
262
+ assert.strictEqual(console.output()[1][1], true)
263
+ assert.strictEqual(console.output()[2][1], true)
264
+ })
265
+
266
+ /**
267
+ * @docs
268
+ * ### 3. Person & Team Structures
269
+ *
270
+ * A `Person` instance includes:
271
+ * - `name`: HumanName
272
+ * - `gender`: HumanGender
273
+ * - `contacts`: array of HumanContact
274
+ */
275
+ it('How to create a Person with typed properties?', () => {
276
+ //import { Person } from '@nan0web/release'
277
+ const person = new Person({
278
+ name: ['Alice', 'Developer'],
279
+ gender: 'female',
280
+ contacts: ['mailto:alice@example.com'],
281
+ })
282
+ console.info(person.name.firstName) // ← Alice
283
+ console.info(person.contacts.length >= 0) // ← true
284
+
285
+ assert.strictEqual(console.output()[0][1], 'Alice')
286
+ assert.strictEqual(console.output()[1][1], true)
287
+ })
288
+
289
+ /**
290
+ * @docs
291
+ * ## Architecture: Project Management as Code
292
+ *
293
+ * This architecture treats tasks as tests, roles as classes, and progress as validated outcomes.
294
+ *
295
+ * ### Task Management
296
+ *
297
+ * Tasks are registered as `taskId` → `testFilePath` in `ProjectManagement`.
298
+ * Their status is derived by running `node:test` suites.
299
+ */
300
+ it('How to register and validate tasks as tests?', async () => {
301
+ //import { ProjectManagement } from '@nan0web/release'
302
+ const pm = new ProjectManagement()
303
+ pm.registerTask('task-1', './tests/task1.test.js')
304
+ pm.registerTask('task-2', './tests/task2.test.js')
305
+
306
+ const mockResults = {
307
+ passed: ['task-1'],
308
+ failed: [],
309
+ pending: ['task-2'],
310
+ }
311
+
312
+ pm.validateProjectState = async () => mockResults
313
+ const results = await pm.validateProjectState()
314
+
315
+ console.info(results.passed.includes('task-1')) // ← true
316
+ console.info(results.pending.includes('task-2')) // ← true
317
+
318
+ assert.strictEqual(console.output()[0][1], true)
319
+ assert.strictEqual(console.output()[1][1], true)
320
+ })
321
+
322
+ /**
323
+ * @docs
324
+ * ### Release Processing
325
+ *
326
+ * The `ReleaseManager` coordinates releases and validates readiness.
327
+ * It ensures:
328
+ * - All registered tests pass
329
+ * - Version is correctly incremented
330
+ * - Git tag is applied if all validations succeed
331
+ */
332
+ it('How to execute a release after validation?', async () => {
333
+ //import { ReleaseManager, ProjectManagement } from '@nan0web/release'
334
+ const pm = new ProjectManagement()
335
+ const rm = new ReleaseManager(pm)
336
+
337
+ rm.calculateVersion = () => 'v1.0.1'
338
+ rm.publish = async () => true
339
+
340
+ const result = await rm.executeRelease('patch')
341
+ console.info(result.version) // ← v1.0.1
342
+ console.info(result.published) // ← true
343
+
344
+ assert.strictEqual(console.output()[0][1], 'v1.0.1')
345
+ assert.strictEqual(console.output()[1][1], true)
346
+ })
347
+
348
+ /**
349
+ * @docs
350
+ * ### Changelog Integration
351
+ *
352
+ * Using `ChangelogTaskManager`, you can:
353
+ * - Extract task definitions from changelog entries
354
+ * - Generate corresponding test files
355
+ * - Automate task progression in CI
356
+ */
357
+ it('How to parse changelog and extract tasks?', () => {
358
+ //import { ChangelogTaskManager } from '@nan0web/release'
359
+ const ctm = new ChangelogTaskManager()
360
+ const changelog = `# Changelog
361
+
362
+ ## [1.0.0] - 2025-08-20
363
+ ### Added
364
+ - Initial structure [core.init]
365
+ - Release notes support [docs.release-notes]`
366
+
367
+ const tasks = ctm.parseChangelog(changelog)
368
+ console.info(Array.isArray(tasks)) // ← true
369
+ console.info(tasks.length >= 0) // ← true
370
+
371
+ assert.strictEqual(console.output()[0][1], true)
372
+ assert.strictEqual(console.output()[1][1], true)
373
+ })
374
+
375
+ /**
376
+ * @docs
377
+ * ## Java•Script Features
378
+ */
379
+ it('Uses JSDoc and .d.ts files for autocompletion', () => {
380
+ assert.ok(pkg.types)
381
+ assert.ok(pkg.types.includes('.d.ts'))
382
+ })
383
+
384
+ /**
385
+ * @docs
386
+ * ## CLI Playground
387
+ *
388
+ * Try the package in the terminal:
389
+ */
390
+ it('How to run playground demo?', async () => {
391
+ /**
392
+ * ```bash
393
+ * git clone https://github.com/nan0web/release.git
394
+ * cd release
395
+ * pnpm install
396
+ * pnpm run playground
397
+ * ```
398
+ */
399
+ assert.ok(pkg.scripts?.playground)
400
+ const response = await runSpawn('git', ['remote', 'get-url', 'origin'])
401
+ assert.ok(response.code === 0)
402
+ assert.ok(
403
+ response.text.trim().endsWith('nan0web/monorepo.git') ||
404
+ response.text.trim().endsWith('nan0web/release.git'),
405
+ )
406
+ })
407
+
408
+ /**
409
+ * @docs
410
+ * ## Project Status
411
+ *
412
+ * To verify the project is ready, run:
413
+ */
414
+ it('How to check project status before publishing?', async () => {
415
+ /**
416
+ * ```bash
417
+ * npm test
418
+ * npm run test:coverage
419
+ * npm run test:status
420
+ * ```
421
+ */
422
+ assert.ok(pkg.scripts?.test)
423
+ assert.ok(pkg.scripts?.['test:coverage'])
424
+ assert.ok(pkg.scripts?.['test:status'])
425
+ })
426
+
427
+ /**
428
+ * @docs
429
+ * ## Contributing
430
+ */
431
+ it('How to contribute? - [check here](./CONTRIBUTING.md)', async () => {
432
+ assert.equal(pkg.scripts?.precommit, 'npm test')
433
+ assert.equal(pkg.scripts?.prepush, 'npm test')
434
+ assert.equal(pkg.scripts?.prepare, 'husky')
435
+ })
436
+
437
+ /**
438
+ * @docs
439
+ * ## License
440
+ */
441
+ it('How to license ISC? - [check here](./LICENSE)', async () => {
442
+ /** @docs */
443
+ const text = await fs.loadDocument('LICENSE')
444
+ assert.ok(String(text).includes('ISC'))
445
+ })
446
+ }
447
+
448
+ describe('README.md testing', testRender)
449
+
450
+ describe('Rendering README.md', async () => {
451
+ let text = ''
452
+ const format = new Intl.NumberFormat('en-US').format
453
+ const parser = new DocsParser()
454
+ text = String(parser.decode(testRender))
455
+ await fs.saveDocument('README.md', text)
456
+ const dataset = DatasetParser.parse(text, pkg.name)
457
+ await fs.saveDocument('.datasets/README.dataset.jsonl', dataset)
458
+
459
+ it(`document is rendered [${format(Buffer.byteLength(text))}b]`, async () => {
460
+ const text = await readFile('README.md', 'utf8')
461
+ assert.ok(text.includes('## License'))
462
+ })
463
+ })
@@ -1,4 +1,4 @@
1
- import { HumanName, HumanContact, HumanGender } from '@nan0web/verse'
1
+ import { HumanName, HumanContact, HumanGender } from '@nan0web/logos'
2
2
 
3
3
  export default class Person {
4
4
  /** @type {HumanName} */
@@ -0,0 +1,35 @@
1
+ ---
2
+ description: Architectural Git Commit & Diff Validator Subagent
3
+ ---
4
+
5
+ # 🐙 Git Reviewer
6
+
7
+ **INPUTS REQUIRED:**
8
+
9
+ - `[PROJECT_MD]` (The 5-phase architectural spec, e.g. project.md from root)
10
+ - `[DIFF]` (The git diff patch output `git diff --cached`)
11
+
12
+ **SYSTEM PROMPT (Agnostic AI API Persona):**
13
+ You are an isolated, Agnostic Zero-Hallucination Git Reviewer. You do not code. You do not converse. You compare the semantic integrity of the `[DIFF]` against the core architecture.
14
+
15
+ You must evaluate the snippet rigorously based on structural integrity and specific rules provided.
16
+ There is no ambiguity: any deviation from the preset `[PROJECT_MD]` libraries or patterns must be strictly caught.
17
+ To reject a `[DIFF]`, provide the specific file name, the line number of code, and the specific phase of `[PROJECT_MD]` that it contradicts.
18
+
19
+ **OBJECTIVE:**
20
+ Ensure the developer is not sneaking in "hotfixes" that break structural agreements ("Zero-Trust Git Review").
21
+
22
+ - Locate any deviations from predefined libraries or patterns.
23
+ - Locate undocumented mutations in the `data/` or `ui/` layer.
24
+ - Ensure only required files are staged.
25
+
26
+ **STRICT OUTPUT CONTRACT:**
27
+
28
+ ```json
29
+ {
30
+ "score": 85,
31
+ "errors": [
32
+ "File 'src/index.js' introduces direct 'node:fs' usage instead of '@nan0web/db-fs', contradicting Phase 2 of project.md."
33
+ ]
34
+ }
35
+ ```
@@ -0,0 +1,63 @@
1
+ ---
2
+ description: Гігієна пакету — обовʼязкові скрипти, конвеєр test:all, knip, .npmignore
3
+ ---
4
+
5
+ # 🧹 Гігієна Пакету (Package Hygiene)
6
+
7
+ ## 1. Обов'язкові скрипти у кожному пакеті
8
+
9
+ - `"knip": "knip --production"` — перевірка невикористаних файлів, експортів та залежностей.
10
+ - `"audit": "pnpm audit --prod || true"` — інформативна перевірка вразливостей. `|| true` бо `pnpm audit` monorepo-wide — вразливості сусідніх пакетів не повинні блокувати реліз.
11
+ - `"release:spec": "node --test \"releases/**/*.spec.js\""` — контрактні тести відкритого релізу.
12
+ - `"test:release": "node --test \"src/test/releases/**/*.test.js\""` — регресійні тести закритих релізів.
13
+
14
+ ## 2. Повний конвеєр (`test:all`)
15
+
16
+ ```
17
+ test → test:docs → build → test:release → knip → audit
18
+ ```
19
+
20
+ - Всі кроки через `&&` — мають бути зеленими.
21
+
22
+ ## 3. Knip Конфігурація (`knip.json`)
23
+
24
+ - `entry`: головний `src/index.js`.
25
+ - `ignore`: `play/`, `releases/`, `types/`, `src/README.md.js`.
26
+ - `ignoreDependencies`: dev-інструменти (`husky`, `@nan0web/test`, тощо).
27
+
28
+ ## 4. `.npmignore` (ОБОВ'ЯЗКОВО у кожному пакеті)
29
+
30
+ Без `.npmignore` npm використовує `.gitignore`, що пропускає dev-артефакти в публікацію.
31
+ Мінімальний шаблон:
32
+
33
+ ```
34
+ # Tests
35
+ src/**/*.test.js
36
+ src/test/
37
+ types/test/
38
+
39
+ # ProvenDoc generator
40
+ src/README.md.js
41
+
42
+ # Dev files
43
+ play/
44
+ releases/
45
+ docs/
46
+ knip.json
47
+ system.md
48
+ next.md
49
+ tsconfig.json
50
+ .editorconfig
51
+ CONTRIBUTING.md
52
+
53
+ # LLiMo / AI artifacts
54
+ chat/
55
+ .datasets/
56
+ me.md
57
+
58
+ # Generated
59
+ dist/
60
+ .cache/
61
+ ```
62
+
63
+ **Перевірка**: `npm pack --dry-run` перед кожним `npm publish`.
@@ -0,0 +1,28 @@
1
+ ---
2
+ description: Safe Commit Workflow (No Auto-Run)
3
+ ---
4
+
5
+ # Safe Commit Procedure
6
+
7
+ 1. **Check Status**:
8
+ - Run `git status` to see what is staged/modified.
9
+ - Run `git diff --stat` to see the scope of changes.
10
+
11
+ 2. **Verify Integrity**:
12
+ - IF (and only if) tests exist, run them: `npm run test:all`.
13
+ - Ensure the build passes: `npm run build` (if applicable, must be included in test:all).
14
+
15
+ 3. **Formulate Message**:
16
+ - Create a concise, semantic commit message (e.g., `fix: ...`, `feat: ...`).
17
+ - Describe WHAT changed and WHY.
18
+
19
+ 4. **PROPOSE Command**:
20
+ - **DO NOT RUN THE COMMIT COMMAND.**
21
+ - Output the suggested command string:
22
+ ```bash
23
+ git add . && git commit -m "Your proposed message"
24
+ ```
25
+ - Ask the user: "Shall I execute this?"
26
+
27
+ 5. **Execute (On User Approval)**:
28
+ - Only after receiving explicit "Yes" or "Do it", run the command.
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: /release — Публікація пакету в NPM (Smart Test & Build & Publish)
3
+ ---
4
+
5
+ // turbo-all
6
+
7
+ До релізую НЕ МАЮТЬ потрапляти так файли:
8
+
9
+ - .agent/
10
+ - .vscode/
11
+ - docs/
12
+ - src/**/*.test.js{x}
13
+ - src/test/
14
+ - src/README.md.js{x}
15
+
16
+ Мають потрапляти:
17
+
18
+ - package.json
19
+ - LICENSE
20
+ - README.md
21
+ - bin/
22
+ - src/
23
+ - types/
24
+
25
+ 1. **Повна перевірка (Safety First)**: Запусти локальну перевірку пакету.
26
+
27
+ ```bash
28
+ pnpm test:all
29
+ ```
30
+
31
+ 2. **Публікація в NPM**: Виконай стандартний скрипт релізу.
32
+
33
+ ```bash
34
+ npm run release
35
+ ```
36
+
37
+ 3. **Верифікація статусів**: Перевір статус пакетів у монорепо.
38
+ ```bash
39
+ npm run test:status
40
+ ```