@guiho/mirror 3.2.0 → 3.3.0-alpha.1

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 (54) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/DOCS.md +142 -76
  3. package/README.md +15 -41
  4. package/jsr.json +4 -2
  5. package/package.json +11 -20
  6. package/schema/mirror.config.schema.json +231 -0
  7. package/scripts/install-package.ts +70 -0
  8. package/scripts/mirror-bin.ts +20 -0
  9. package/skills/guiho-as-mirror/SKILL.md +2 -29
  10. package/library/adapters.d.ts +0 -32
  11. package/library/adapters.d.ts.map +0 -1
  12. package/library/adapters.js +0 -210
  13. package/library/agents.d.ts +0 -27
  14. package/library/agents.d.ts.map +0 -1
  15. package/library/agents.js +0 -200
  16. package/library/cli.d.ts +0 -29
  17. package/library/cli.d.ts.map +0 -1
  18. package/library/cli.js +0 -387
  19. package/library/config.d.ts +0 -18
  20. package/library/config.d.ts.map +0 -1
  21. package/library/config.js +0 -277
  22. package/library/errors.d.ts +0 -9
  23. package/library/errors.d.ts.map +0 -1
  24. package/library/errors.js +0 -15
  25. package/library/executor.d.ts +0 -7
  26. package/library/executor.d.ts.map +0 -1
  27. package/library/executor.js +0 -32
  28. package/library/flags.d.ts +0 -6
  29. package/library/flags.d.ts.map +0 -1
  30. package/library/flags.js +0 -80
  31. package/library/guiho-mirror-bin.d.ts +0 -6
  32. package/library/guiho-mirror-bin.d.ts.map +0 -1
  33. package/library/guiho-mirror-bin.js +0 -6
  34. package/library/guiho-mirror.d.ts +0 -17
  35. package/library/guiho-mirror.d.ts.map +0 -1
  36. package/library/guiho-mirror.js +0 -15
  37. package/library/init.d.ts +0 -12
  38. package/library/init.d.ts.map +0 -1
  39. package/library/init.js +0 -100
  40. package/library/plan.d.ts +0 -10
  41. package/library/plan.d.ts.map +0 -1
  42. package/library/plan.js +0 -85
  43. package/library/reporter.d.ts +0 -14
  44. package/library/reporter.d.ts.map +0 -1
  45. package/library/reporter.js +0 -156
  46. package/library/schema.d.ts +0 -133
  47. package/library/schema.d.ts.map +0 -1
  48. package/library/schema.js +0 -128
  49. package/library/types.d.ts +0 -190
  50. package/library/types.d.ts.map +0 -1
  51. package/library/types.js +0 -4
  52. package/library/version.d.ts +0 -10
  53. package/library/version.d.ts.map +0 -1
  54. package/library/version.js +0 -31
@@ -143,6 +143,237 @@
143
143
  "description": "Install guiho-as-mirror globally when missing."
144
144
  }
145
145
  }
146
+ },
147
+ "hooks": {
148
+ "type": "object",
149
+ "description": "Lifecycle hook commands that run at defined points during version apply.",
150
+ "additionalProperties": {
151
+ "oneOf": [
152
+ {
153
+ "type": "string",
154
+ "description": "A single shell command."
155
+ },
156
+ {
157
+ "type": "array",
158
+ "items": {
159
+ "type": "string"
160
+ },
161
+ "description": "Multiple shell commands run sequentially."
162
+ }
163
+ ]
164
+ },
165
+ "properties": {
166
+ "before_everything": {
167
+ "oneOf": [
168
+ {
169
+ "type": "string",
170
+ "description": "A single shell command to run at the before:everything lifecycle point."
171
+ },
172
+ {
173
+ "type": "array",
174
+ "items": {
175
+ "type": "string"
176
+ },
177
+ "description": "Multiple shell commands to run sequentially at the before:everything lifecycle point."
178
+ }
179
+ ]
180
+ },
181
+ "after_everything": {
182
+ "oneOf": [
183
+ {
184
+ "type": "string",
185
+ "description": "A single shell command to run at the after:everything lifecycle point."
186
+ },
187
+ {
188
+ "type": "array",
189
+ "items": {
190
+ "type": "string"
191
+ },
192
+ "description": "Multiple shell commands to run sequentially at the after:everything lifecycle point."
193
+ }
194
+ ]
195
+ },
196
+ "before_plan": {
197
+ "oneOf": [
198
+ {
199
+ "type": "string",
200
+ "description": "A single shell command to run at the before:plan lifecycle point."
201
+ },
202
+ {
203
+ "type": "array",
204
+ "items": {
205
+ "type": "string"
206
+ },
207
+ "description": "Multiple shell commands to run sequentially at the before:plan lifecycle point."
208
+ }
209
+ ]
210
+ },
211
+ "after_plan": {
212
+ "oneOf": [
213
+ {
214
+ "type": "string",
215
+ "description": "A single shell command to run at the after:plan lifecycle point."
216
+ },
217
+ {
218
+ "type": "array",
219
+ "items": {
220
+ "type": "string"
221
+ },
222
+ "description": "Multiple shell commands to run sequentially at the after:plan lifecycle point."
223
+ }
224
+ ]
225
+ },
226
+ "before_apply": {
227
+ "oneOf": [
228
+ {
229
+ "type": "string",
230
+ "description": "A single shell command to run at the before:apply lifecycle point."
231
+ },
232
+ {
233
+ "type": "array",
234
+ "items": {
235
+ "type": "string"
236
+ },
237
+ "description": "Multiple shell commands to run sequentially at the before:apply lifecycle point."
238
+ }
239
+ ]
240
+ },
241
+ "after_apply": {
242
+ "oneOf": [
243
+ {
244
+ "type": "string",
245
+ "description": "A single shell command to run at the after:apply lifecycle point."
246
+ },
247
+ {
248
+ "type": "array",
249
+ "items": {
250
+ "type": "string"
251
+ },
252
+ "description": "Multiple shell commands to run sequentially at the after:apply lifecycle point."
253
+ }
254
+ ]
255
+ },
256
+ "before_write": {
257
+ "oneOf": [
258
+ {
259
+ "type": "string",
260
+ "description": "A single shell command to run at the before:write lifecycle point."
261
+ },
262
+ {
263
+ "type": "array",
264
+ "items": {
265
+ "type": "string"
266
+ },
267
+ "description": "Multiple shell commands to run sequentially at the before:write lifecycle point."
268
+ }
269
+ ]
270
+ },
271
+ "after_write": {
272
+ "oneOf": [
273
+ {
274
+ "type": "string",
275
+ "description": "A single shell command to run at the after:write lifecycle point."
276
+ },
277
+ {
278
+ "type": "array",
279
+ "items": {
280
+ "type": "string"
281
+ },
282
+ "description": "Multiple shell commands to run sequentially at the after:write lifecycle point."
283
+ }
284
+ ]
285
+ },
286
+ "before_commit": {
287
+ "oneOf": [
288
+ {
289
+ "type": "string",
290
+ "description": "A single shell command to run at the before:commit lifecycle point."
291
+ },
292
+ {
293
+ "type": "array",
294
+ "items": {
295
+ "type": "string"
296
+ },
297
+ "description": "Multiple shell commands to run sequentially at the before:commit lifecycle point."
298
+ }
299
+ ]
300
+ },
301
+ "after_commit": {
302
+ "oneOf": [
303
+ {
304
+ "type": "string",
305
+ "description": "A single shell command to run at the after:commit lifecycle point."
306
+ },
307
+ {
308
+ "type": "array",
309
+ "items": {
310
+ "type": "string"
311
+ },
312
+ "description": "Multiple shell commands to run sequentially at the after:commit lifecycle point."
313
+ }
314
+ ]
315
+ },
316
+ "before_tag": {
317
+ "oneOf": [
318
+ {
319
+ "type": "string",
320
+ "description": "A single shell command to run at the before:tag lifecycle point."
321
+ },
322
+ {
323
+ "type": "array",
324
+ "items": {
325
+ "type": "string"
326
+ },
327
+ "description": "Multiple shell commands to run sequentially at the before:tag lifecycle point."
328
+ }
329
+ ]
330
+ },
331
+ "after_tag": {
332
+ "oneOf": [
333
+ {
334
+ "type": "string",
335
+ "description": "A single shell command to run at the after:tag lifecycle point."
336
+ },
337
+ {
338
+ "type": "array",
339
+ "items": {
340
+ "type": "string"
341
+ },
342
+ "description": "Multiple shell commands to run sequentially at the after:tag lifecycle point."
343
+ }
344
+ ]
345
+ },
346
+ "before_push": {
347
+ "oneOf": [
348
+ {
349
+ "type": "string",
350
+ "description": "A single shell command to run at the before:push lifecycle point."
351
+ },
352
+ {
353
+ "type": "array",
354
+ "items": {
355
+ "type": "string"
356
+ },
357
+ "description": "Multiple shell commands to run sequentially at the before:push lifecycle point."
358
+ }
359
+ ]
360
+ },
361
+ "after_push": {
362
+ "oneOf": [
363
+ {
364
+ "type": "string",
365
+ "description": "A single shell command to run at the after:push lifecycle point."
366
+ },
367
+ {
368
+ "type": "array",
369
+ "items": {
370
+ "type": "string"
371
+ },
372
+ "description": "Multiple shell commands to run sequentially at the after:push lifecycle point."
373
+ }
374
+ ]
375
+ }
376
+ }
146
377
  }
147
378
  }
148
379
  }
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Package-manager install helper for GUIHO Mirror.
4
+ *
5
+ * This script uses Bun APIs only. It downloads the platform-native Mirror binary
6
+ * into `vendor/mirror`. Package-manager installs use the small Bun launcher in
7
+ * `scripts/mirror-bin.ts`; direct installers remain the no-Bun runtime path.
8
+ */
9
+
10
+ type PackageJson = {
11
+ version?: string
12
+ repository?: string | { url?: string }
13
+ }
14
+
15
+ const packageJson = await Bun.file(new URL('../package.json', import.meta.url)).json() as PackageJson
16
+ const sourceEntrypoint = Bun.file(new URL('../source/guiho-mirror-bin.ts', import.meta.url))
17
+
18
+ if (await sourceEntrypoint.exists()) {
19
+ console.log('source checkout detected; skipping native binary download')
20
+ process.exit(0)
21
+ }
22
+
23
+ const version = process.env['MIRROR_VERSION'] ?? packageJson.version ?? 'latest'
24
+ const repo = process.env['MIRROR_REPO'] ?? 'CGuiho/mirror'
25
+ const asset = detectAsset()
26
+ const bundledAsset = Bun.file(new URL(`../bin/${asset}`, import.meta.url))
27
+ const destination = new URL('../vendor/mirror', import.meta.url)
28
+
29
+ if (await bundledAsset.exists()) {
30
+ await Bun.write(destination, bundledAsset)
31
+ console.log(`installed bundled GUIHO Mirror native binary: ${asset}`)
32
+ process.exit(0)
33
+ }
34
+
35
+ const tag = version === 'latest' ? 'latest' : `@guiho/mirror@${version}`
36
+ const url = tag === 'latest'
37
+ ? `https://github.com/${repo}/releases/latest/download/${asset}`
38
+ : `https://github.com/${repo}/releases/download/${encodeURIComponent(tag)}/${asset}`
39
+
40
+ const response = await fetch(url)
41
+
42
+ if (!response.ok) {
43
+ console.error(`error: failed to download ${url}`)
44
+ console.error(`status: ${response.status} ${response.statusText}`)
45
+ process.exit(1)
46
+ }
47
+
48
+ await Bun.write(destination, response)
49
+ console.log(`installed GUIHO Mirror native binary: ${asset}`)
50
+
51
+ function detectAsset() {
52
+ const os = detectOs()
53
+ const arch = detectArch()
54
+ return `guiho-mirror-${os}-${arch}${os === 'windows' ? '.exe' : ''}`
55
+ }
56
+
57
+ function detectOs() {
58
+ if (process.platform === 'linux') return 'linux'
59
+ if (process.platform === 'darwin') return 'macos'
60
+ if (process.platform === 'win32') return 'windows'
61
+ console.error(`error: unsupported OS: ${process.platform}`)
62
+ process.exit(1)
63
+ }
64
+
65
+ function detectArch() {
66
+ if (process.arch === 'x64') return 'x64'
67
+ if (process.arch === 'arm64') return 'arm64'
68
+ console.error(`error: unsupported architecture: ${process.arch}`)
69
+ process.exit(1)
70
+ }
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Small package-manager launcher for the downloaded native Mirror binary.
4
+ */
5
+
6
+ const binaryPath = new URL('../vendor/mirror', import.meta.url)
7
+ const binary = Bun.file(binaryPath)
8
+
9
+ if (!(await binary.exists())) {
10
+ console.error('error: GUIHO Mirror native binary is missing. Reinstall @guiho/mirror or run `bun run scripts/install-package.ts`.')
11
+ process.exit(1)
12
+ }
13
+
14
+ const proc = Bun.spawn([binaryPath.pathname, ...process.argv.slice(2)], {
15
+ stdin: 'inherit',
16
+ stdout: 'inherit',
17
+ stderr: 'inherit',
18
+ })
19
+
20
+ process.exit(await proc.exited)
@@ -5,7 +5,7 @@ description: Use this skill whenever the user asks to version, bump, release, ta
5
5
 
6
6
  # GUIHO Mirror
7
7
 
8
- GUIHO Mirror is a deterministic CLI and TypeScript library for semantic project versioning. It reads one version source, calculates the next semantic version, builds a transparent read-only plan, and applies the plan to configured outputs such as `package.json`, `jsr.json`, and Git tags.
8
+ GUIHO Mirror is a deterministic CLI for semantic project versioning. It reads one version source, calculates the next semantic version, builds a transparent read-only plan, and applies the plan to configured outputs such as `package.json`, `jsr.json`, and Git tags.
9
9
 
10
10
  ```text
11
11
  source -> version engine -> plan -> outputs
@@ -23,7 +23,7 @@ Choose the Mirror command in this order:
23
23
 
24
24
  When unsure, run a cheap availability check (`bun @guiho/mirror --help`, `mirror --help`, or `bunx @guiho/mirror --help`) and then reuse the working command consistently. Run `mirror --help` or `mirror <command> --help` for command-specific details when needed.
25
25
 
26
- Mirror runs on Node >= 20 at runtime, Bun, and Deno. Bun is the recommended development tool for the Mirror project itself. Git is required only for Git-based workflows: `source = "git"`, `output = ["git"]`, commits, tags, or pushes.
26
+ Mirror ships as a Bun-compiled native CLI binary. The installed `mirror` command should not require Node.js or Bun at runtime. Bun is required for Mirror project development and binary compilation. Git is required only for Git-based workflows: `source = "git"`, `output = ["git"]`, commits, tags, or pushes.
27
27
 
28
28
  ## Release Workflow
29
29
 
@@ -177,33 +177,6 @@ mirror version apply <target> --yes
177
177
 
178
178
  Supported targets are `major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, `prerelease`, or an exact semantic version such as `2.0.0`.
179
179
 
180
- ## TypeScript API
181
-
182
- When the user wants automation code rather than CLI usage, use the typed API:
183
-
184
- ```ts
185
- import { applyVersionPlan, buildVersionPlan, executeVersionPlan } from '@guiho/mirror';
186
-
187
- const plan = await buildVersionPlan('patch', { cwd: process.cwd() });
188
-
189
- console.log(plan.currentVersion);
190
- console.log(plan.nextVersion);
191
- console.log(plan.actions);
192
-
193
- await executeVersionPlan(plan, { dryRun: false, yes: true });
194
-
195
- await applyVersionPlan('minor', { cwd: process.cwd(), yes: true });
196
- ```
197
-
198
- For reading state:
199
-
200
- ```ts
201
- import { loadMirrorConfig, readCurrentVersion } from '@guiho/mirror';
202
-
203
- const config = await loadMirrorConfig({ cwd: process.cwd() });
204
- const version = await readCurrentVersion(config);
205
- ```
206
-
207
180
  ## Mirror Project Development
208
181
 
209
182
  When working inside the Mirror project repository itself, run development commands from the `mirror/` directory:
@@ -1,32 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import type { MirrorConfig, MirrorJsonObject } from './types.js';
5
- export declare const ensureGitAvailable: () => Promise<void>;
6
- export declare const supportedGitTagTemplates: readonly ["v{version}", "{name}@{version}", "{name}/v{version}"];
7
- export declare const readPackageJson: (path: string) => Promise<MirrorJsonObject>;
8
- export declare const readJsrJson: (path: string) => Promise<MirrorJsonObject>;
9
- export declare const writeJsonObject: (path: string, object: MirrorJsonObject) => Promise<void>;
10
- export declare const readPackageVersion: (config: MirrorConfig) => Promise<string>;
11
- export declare const readJsrVersion: (config: MirrorConfig) => Promise<string>;
12
- export declare const readPackageVersionFile: (path: string) => Promise<string>;
13
- export declare const readJsrVersionFile: (path: string) => Promise<string>;
14
- export declare const readPackageName: (config: MirrorConfig) => Promise<string>;
15
- export declare const readJsrName: (config: MirrorConfig) => Promise<string>;
16
- export declare const writePackageVersion: (config: MirrorConfig, nextVersion: string) => Promise<void>;
17
- export declare const writeJsrVersion: (config: MirrorConfig, nextVersion: string) => Promise<void>;
18
- export declare const writePackageVersionFile: (path: string, nextVersion: string) => Promise<void>;
19
- export declare const writeJsrVersionFile: (path: string, nextVersion: string) => Promise<void>;
20
- export declare const ensureAdapterFiles: (config: MirrorConfig) => Promise<void>;
21
- export declare const resolveProjectName: (config: MirrorConfig) => Promise<string | undefined>;
22
- export declare const readCurrentVersion: (config: MirrorConfig, projectName?: string) => Promise<string>;
23
- export declare const readGitVersion: (config: MirrorConfig, projectName?: string) => Promise<string>;
24
- export declare const renderGitTag: (template: string, version: string, projectName?: string) => string;
25
- export declare const versionFromTag: (template: string, tag: string, projectName?: string) => string | undefined;
26
- export declare const assertSupportedGitTagTemplate: (template: string) => void;
27
- export declare const isGitRepository: (cwd: string) => Promise<boolean>;
28
- export declare const isGitDirty: (cwd: string) => Promise<boolean>;
29
- export declare const createGitCommit: (cwd: string, paths: string[], message: string) => Promise<void>;
30
- export declare const createGitTag: (cwd: string, tag: string) => Promise<void>;
31
- export declare const pushGitRefs: (cwd: string, includeCommit: boolean, includeTags: boolean) => Promise<void>;
32
- //# sourceMappingURL=adapters.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../source/adapters.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAsBhE,eAAO,MAAM,kBAAkB,qBAI9B,CAAA;AAiBD,eAAO,MAAM,wBAAwB,kEAAmE,CAAA;AAExG,eAAO,MAAM,eAAe,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAAyC,CAAA;AACtH,eAAO,MAAM,WAAW,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAAqC,CAAA;AAE9G,eAAO,MAAM,eAAe,GAAU,MAAM,MAAM,EAAE,QAAQ,gBAAgB,kBAE3E,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAU,QAAQ,YAAY,oBAAyF,CAAA;AACtJ,eAAO,MAAM,cAAc,GAAU,QAAQ,YAAY,oBAAiF,CAAA;AAC1I,eAAO,MAAM,sBAAsB,GAAU,MAAM,MAAM,oBAA2C,CAAA;AACpG,eAAO,MAAM,kBAAkB,GAAU,MAAM,MAAM,oBAAuC,CAAA;AAC5F,eAAO,MAAM,eAAe,GAAU,QAAQ,YAAY,oBAAsF,CAAA;AAChJ,eAAO,MAAM,WAAW,GAAU,QAAQ,YAAY,oBAA8E,CAAA;AAEpI,eAAO,MAAM,mBAAmB,GAAU,QAAQ,YAAY,EAAE,aAAa,MAAM,kBACiB,CAAA;AAEpG,eAAO,MAAM,eAAe,GAAU,QAAQ,YAAY,EAAE,aAAa,MAAM,kBACa,CAAA;AAE5F,eAAO,MAAM,uBAAuB,GAAU,MAAM,MAAM,EAAE,aAAa,MAAM,kBAAyD,CAAA;AACxI,eAAO,MAAM,mBAAmB,GAAU,MAAM,MAAM,EAAE,aAAa,MAAM,kBAAqD,CAAA;AAEhI,eAAO,MAAM,kBAAkB,GAAU,QAAQ,YAAY,kBAO5D,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAU,QAAQ,YAAY,gCAK5D,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAU,QAAQ,YAAY,EAAE,cAAc,MAAM,oBAIlF,CAAA;AAED,eAAO,MAAM,cAAc,GAAU,QAAQ,YAAY,EAAE,cAAc,MAAM,oBAe9E,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,EAAE,cAAc,MAAM,WAOnF,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,EAAE,KAAK,MAAM,EAAE,cAAc,MAAM,uBAmBjF,CAAA;AAED,eAAO,MAAM,6BAA6B,GAAI,UAAU,MAAM,SAI7D,CAAA;AAED,eAAO,MAAM,eAAe,GAAU,KAAK,MAAM,qBAQhD,CAAA;AAED,eAAO,MAAM,UAAU,GAAU,KAAK,MAAM,qBAG3C,CAAA;AAED,eAAO,MAAM,eAAe,GAAU,KAAK,MAAM,EAAE,OAAO,MAAM,EAAE,EAAE,SAAS,MAAM,kBAIlF,CAAA;AAED,eAAO,MAAM,YAAY,GAAU,KAAK,MAAM,EAAE,KAAK,MAAM,kBAG1D,CAAA;AAED,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,EAAE,eAAe,OAAO,EAAE,aAAa,OAAO,kBAI1F,CAAA"}
@@ -1,210 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import { execFile } from 'node:child_process';
5
- import { existsSync } from 'node:fs';
6
- import { readFile, writeFile } from 'node:fs/promises';
7
- import { promisify } from 'node:util';
8
- import { MirrorError } from './errors.js';
9
- import { assertValidSemver, sortSemverDescending } from './version.js';
10
- import { resolveMirrorPath } from './config.js';
11
- const execFileAsync = promisify(execFile);
12
- let gitChecked = false;
13
- let gitExists = false;
14
- const checkGitAvailable = async () => {
15
- if (gitChecked)
16
- return gitExists;
17
- gitChecked = true;
18
- try {
19
- await execFileAsync('git', ['--version']);
20
- gitExists = true;
21
- }
22
- catch {
23
- gitExists = false;
24
- }
25
- return gitExists;
26
- };
27
- export const ensureGitAvailable = async () => {
28
- if (!(await checkGitAvailable())) {
29
- throw new MirrorError('Git executable not found. Git is required when using git as a source or output.');
30
- }
31
- };
32
- const gitNotFoundMessage = 'Git executable not found. Git is required when using git as a source or output.';
33
- const runGit = async (cwd, args) => {
34
- if (!(await checkGitAvailable())) {
35
- throw new MirrorError(gitNotFoundMessage);
36
- }
37
- try {
38
- const { stdout } = await execFileAsync('git', args, { cwd });
39
- return stdout;
40
- }
41
- catch (error) {
42
- const message = error instanceof Error ? error.message : String(error);
43
- throw new MirrorError(`Git command failed: git ${args.join(' ')}\n${message}`);
44
- }
45
- };
46
- export const supportedGitTagTemplates = ['v{version}', '{name}@{version}', '{name}/v{version}'];
47
- export const readPackageJson = async (path) => readJsonObject(path, 'package.json');
48
- export const readJsrJson = async (path) => readJsonObject(path, 'jsr.json');
49
- export const writeJsonObject = async (path, object) => {
50
- await writeFile(path, `${JSON.stringify(object, null, 2)}\n`, 'utf8');
51
- };
52
- export const readPackageVersion = async (config) => readVersionField(resolveMirrorPath(config.cwd, config.package.path), 'package.json');
53
- export const readJsrVersion = async (config) => readVersionField(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json');
54
- export const readPackageVersionFile = async (path) => readVersionField(path, 'package.json');
55
- export const readJsrVersionFile = async (path) => readVersionField(path, 'jsr.json');
56
- export const readPackageName = async (config) => readNameField(resolveMirrorPath(config.cwd, config.package.path), 'package.json');
57
- export const readJsrName = async (config) => readNameField(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json');
58
- export const writePackageVersion = async (config, nextVersion) => writeVersionField(resolveMirrorPath(config.cwd, config.package.path), 'package.json', nextVersion);
59
- export const writeJsrVersion = async (config, nextVersion) => writeVersionField(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json', nextVersion);
60
- export const writePackageVersionFile = async (path, nextVersion) => writeVersionField(path, 'package.json', nextVersion);
61
- export const writeJsrVersionFile = async (path, nextVersion) => writeVersionField(path, 'jsr.json', nextVersion);
62
- export const ensureAdapterFiles = async (config) => {
63
- if (usesAdapter(config, 'package.json')) {
64
- ensureFile(resolveMirrorPath(config.cwd, config.package.path), 'package.json');
65
- for (const path of config.package.auxiliaryPaths)
66
- ensureFile(resolveMirrorPath(config.cwd, path), 'package.json');
67
- }
68
- if (usesAdapter(config, 'jsr.json'))
69
- ensureFile(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json');
70
- if (usesAdapter(config, 'git'))
71
- await ensureGitRepository(config.cwd);
72
- };
73
- export const resolveProjectName = async (config) => {
74
- if (config.project.name)
75
- return config.project.name;
76
- if (config.project.nameSource === 'package.json')
77
- return readPackageName(config);
78
- if (config.project.nameSource === 'jsr.json')
79
- return readJsrName(config);
80
- return undefined;
81
- };
82
- export const readCurrentVersion = async (config, projectName) => {
83
- if (config.version.source === 'package.json')
84
- return readPackageVersion(config);
85
- if (config.version.source === 'jsr.json')
86
- return readJsrVersion(config);
87
- return readGitVersion(config, projectName);
88
- };
89
- export const readGitVersion = async (config, projectName) => {
90
- await ensureGitAvailable();
91
- await ensureGitRepository(config.cwd);
92
- const tagsOutput = await runGit(config.cwd, ['-C', config.cwd, 'tag', '--list']);
93
- const versions = tagsOutput
94
- .split(/\r?\n/)
95
- .map((line) => line.trim())
96
- .filter(Boolean)
97
- .map((tag) => versionFromTag(config.git.tagTemplate, tag, projectName))
98
- .filter((version) => Boolean(version));
99
- if (versions.length === 0)
100
- throw new MirrorError(`No Git tags match template: ${config.git.tagTemplate}`);
101
- return sortSemverDescending(versions)[0] ?? '';
102
- };
103
- export const renderGitTag = (template, version, projectName) => {
104
- assertSupportedGitTagTemplate(template);
105
- assertValidSemver(version, 'Git tag version');
106
- if (template.includes('{name}') && !projectName)
107
- throw new MirrorError(`Tag template requires a project name: ${template}`);
108
- return template.replaceAll('{version}', version).replaceAll('{name}', projectName ?? '');
109
- };
110
- export const versionFromTag = (template, tag, projectName) => {
111
- assertSupportedGitTagTemplate(template);
112
- if (template.includes('{name}') && !projectName)
113
- throw new MirrorError(`Tag template requires a project name: ${template}`);
114
- const escapedTemplate = escapeRegex(template)
115
- .replaceAll('\\{version\\}', '(?<version>.+)')
116
- .replaceAll('\\{name\\}', escapeRegex(projectName ?? ''));
117
- const match = new RegExp(`^${escapedTemplate}$`).exec(tag);
118
- const version = match?.groups?.['version'];
119
- if (!version)
120
- return undefined;
121
- try {
122
- assertValidSemver(version, 'Git tag version');
123
- return version;
124
- }
125
- catch {
126
- return undefined;
127
- }
128
- };
129
- export const assertSupportedGitTagTemplate = (template) => {
130
- if (!supportedGitTagTemplates.includes(template)) {
131
- throw new MirrorError(`Unsupported Git tag template: ${template}. Expected v{version}, {name}@{version}, or {name}/v{version}.`);
132
- }
133
- };
134
- export const isGitRepository = async (cwd) => {
135
- if (!(await checkGitAvailable()))
136
- return false;
137
- try {
138
- await execFileAsync('git', ['-C', cwd, 'rev-parse', '--is-inside-work-tree']);
139
- return true;
140
- }
141
- catch {
142
- return false;
143
- }
144
- };
145
- export const isGitDirty = async (cwd) => {
146
- const output = await runGit(cwd, ['-C', cwd, 'status', '--porcelain']);
147
- return output.trim().length > 0;
148
- };
149
- export const createGitCommit = async (cwd, paths, message) => {
150
- await ensureGitAvailable();
151
- for (const path of paths)
152
- await runGit(cwd, ['-C', cwd, 'add', path]);
153
- await runGit(cwd, ['-C', cwd, 'commit', '-m', message]);
154
- };
155
- export const createGitTag = async (cwd, tag) => {
156
- await ensureGitAvailable();
157
- await runGit(cwd, ['-C', cwd, 'tag', tag, '-m', `Release ${tag}`]);
158
- };
159
- export const pushGitRefs = async (cwd, includeCommit, includeTags) => {
160
- await ensureGitAvailable();
161
- if (includeCommit)
162
- await runGit(cwd, ['-C', cwd, 'push']);
163
- if (includeTags)
164
- await runGit(cwd, ['-C', cwd, 'push', '--tags']);
165
- };
166
- const readJsonObject = async (path, label) => {
167
- ensureFile(path, label);
168
- const content = await readFile(path, 'utf8');
169
- let json;
170
- try {
171
- json = JSON.parse(content);
172
- }
173
- catch {
174
- throw new MirrorError(`${label} must contain valid JSON: ${path}`);
175
- }
176
- if (typeof json !== 'object' || json === null || Array.isArray(json))
177
- throw new MirrorError(`${label} must contain a JSON object: ${path}`);
178
- return json;
179
- };
180
- const readVersionField = async (path, label) => {
181
- const json = await readJsonObject(path, label);
182
- const version = json['version'];
183
- if (typeof version !== 'string')
184
- throw new MirrorError(`${label} must contain a string version field: ${path}`);
185
- assertValidSemver(version, `${label} version`);
186
- return version;
187
- };
188
- const readNameField = async (path, label) => {
189
- const json = await readJsonObject(path, label);
190
- const name = json['name'];
191
- if (typeof name !== 'string' || name.length === 0)
192
- throw new MirrorError(`${label} must contain a string name field: ${path}`);
193
- return name;
194
- };
195
- const writeVersionField = async (path, label, nextVersion) => {
196
- const json = await readJsonObject(path, label);
197
- json['version'] = nextVersion;
198
- await writeJsonObject(path, json);
199
- };
200
- const ensureFile = (path, label) => {
201
- if (!existsSync(path))
202
- throw new MirrorError(`${label} file not found: ${path}`);
203
- };
204
- const ensureGitRepository = async (cwd) => {
205
- await ensureGitAvailable();
206
- if (!(await isGitRepository(cwd)))
207
- throw new MirrorError(`Not a Git repository: ${cwd}`);
208
- };
209
- const usesAdapter = (config, adapter) => config.version.source === adapter || config.version.output.includes(adapter);
210
- const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
@@ -1,27 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import type { MirrorAgentAutomationResult, MirrorAgentSettings, MirrorAgentsInstructionsResult, MirrorCliOptions, MirrorSkillInstallResult, MirrorSkillInstallScope } from './types.js';
5
- export declare const mirrorSkillName = "guiho-as-mirror";
6
- export declare const mirrorAgentsSectionHeading = "## Semantic Project Versioning -- GUIHO Mirror";
7
- export declare const defaultMirrorAgentSettings: MirrorAgentSettings;
8
- export declare const mirrorAgentsSection = "## Semantic Project Versioning -- GUIHO Mirror\n\nInvoke the guiho-as-mirror agent skill every time the user wants to bump, tag, release, plan, initialize, configure, or troubleshoot semantic project versioning with GUIHO Mirror.\n\nBefore editing release docs or changelogs, inspect mirror.config.toml. If [agents].write_changelog is false, skip changelog edits. If it is missing or true, changelog edits are allowed when the project has a changelog.\n\nUse [agents].changelog_path as the changelog file path. If it is missing, use CHANGELOG.md in the project root.\n";
9
- type MirrorSkillPathOptions = {
10
- cwd?: string;
11
- homeDirectory?: string;
12
- };
13
- type MirrorSkillInstallOptions = MirrorSkillPathOptions & {
14
- overwrite?: boolean;
15
- };
16
- type MirrorAgentAutomationOptions = MirrorCliOptions & {
17
- homeDirectory?: string;
18
- };
19
- export declare const resolveMirrorSkillPath: (scope: MirrorSkillInstallScope, options?: MirrorSkillPathOptions) => string;
20
- export declare const isMirrorSkillInstalled: (scope: MirrorSkillInstallScope, options?: MirrorSkillPathOptions) => boolean;
21
- export declare const installMirrorSkill: (scope: MirrorSkillInstallScope, options?: MirrorSkillInstallOptions) => Promise<MirrorSkillInstallResult>;
22
- export declare const ensureMirrorAgentsInstructions: (cwd: string, create?: boolean) => Promise<MirrorAgentsInstructionsResult>;
23
- export declare const findAgentsFile: (cwd: string) => string | undefined;
24
- export declare const resolveMirrorAgentSettings: (options?: MirrorCliOptions) => Promise<MirrorAgentSettings>;
25
- export declare const runMirrorAgentAutomation: (options?: MirrorAgentAutomationOptions, notify?: (message: string) => void) => Promise<MirrorAgentAutomationResult>;
26
- export {};
27
- //# sourceMappingURL=agents.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../source/agents.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EACV,2BAA2B,EAC3B,mBAAmB,EACnB,8BAA8B,EAC9B,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,YAAY,CAAA;AAInB,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAChD,eAAO,MAAM,0BAA0B,mDAAmD,CAAA;AAE1F,eAAO,MAAM,0BAA0B,EAAE,mBAKxC,CAAA;AAED,eAAO,MAAM,mBAAmB,6jBAO/B,CAAA;AAED,KAAK,sBAAsB,GAAG;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,KAAK,yBAAyB,GAAG,sBAAsB,GAAG;IACxD,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,KAAK,4BAA4B,GAAG,gBAAgB,GAAG;IACrD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,OAAO,uBAAuB,EAAE,UAAS,sBAA2B,WAI1G,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,OAAO,uBAAuB,EAAE,UAAS,sBAA2B,YACvD,CAAA;AAEpD,eAAO,MAAM,kBAAkB,GAC7B,OAAO,uBAAuB,EAC9B,UAAS,yBAA8B,KACtC,OAAO,CAAC,wBAAwB,CAelC,CAAA;AAED,eAAO,MAAM,8BAA8B,GAAU,KAAK,MAAM,EAAE,gBAAc,KAAG,OAAO,CAAC,8BAA8B,CAkBxH,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,SAWrD,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAU,UAAS,gBAAqB,KAAG,OAAO,CAAC,mBAAmB,CAa5G,CAAA;AAED,eAAO,MAAM,wBAAwB,GACnC,UAAS,4BAAiC,EAC1C,SAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,KAC3C,OAAO,CAAC,2BAA2B,CAkBrC,CAAA"}