@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
package/library/config.js DELETED
@@ -1,277 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import { existsSync } from 'node:fs';
5
- import { readFile, writeFile } from 'node:fs/promises';
6
- import { basename, isAbsolute, join, relative, resolve } from 'node:path';
7
- import { parse as parseToml } from 'smol-toml';
8
- import { MirrorError } from './errors.js';
9
- import { mirrorConfigSchemaReference } from './schema.js';
10
- const adapters = new Set(['package.json', 'jsr.json', 'git']);
11
- const projectNameSources = new Set(['package.json', 'jsr.json']);
12
- export const resolveMirrorPath = (cwd, path) => (isAbsolute(path) ? path : resolve(cwd, path));
13
- export const relativeFromCwd = (cwd, path) => {
14
- const relativePath = relative(cwd, resolveMirrorPath(cwd, path));
15
- return relativePath || '.';
16
- };
17
- export const discoverMirrorConfig = async (cwd, explicitPath) => {
18
- if (explicitPath) {
19
- const configPath = resolveMirrorPath(cwd, explicitPath);
20
- return { path: configPath, raw: await readConfigFile(configPath) };
21
- }
22
- const rootConfigPath = resolve(cwd, 'mirror.config.toml');
23
- if (existsSync(rootConfigPath))
24
- return { path: rootConfigPath, raw: await readConfigFile(rootConfigPath) };
25
- const nestedConfigPath = resolve(cwd, 'config', 'mirror.config.toml');
26
- if (existsSync(nestedConfigPath))
27
- return { path: nestedConfigPath, raw: await readConfigFile(nestedConfigPath) };
28
- return {};
29
- };
30
- export const readConfigFile = async (path) => {
31
- if (!existsSync(path))
32
- throw new MirrorError(`Configuration file not found: ${path}`);
33
- const content = await readFile(path, 'utf8');
34
- let parsed;
35
- try {
36
- parsed = parseToml(content);
37
- }
38
- catch (error) {
39
- const message = error instanceof Error ? error.message : String(error);
40
- throw new MirrorError(`Invalid TOML in configuration file: ${path}\n${message}`);
41
- }
42
- if (!isRecord(parsed))
43
- throw new MirrorError(`Configuration file must contain a TOML object: ${path}`);
44
- return parsed;
45
- };
46
- export const loadMirrorConfig = async (options = {}) => {
47
- const cwd = resolve(options.cwd ?? process.cwd());
48
- const discovered = await discoverMirrorConfig(cwd, options.config);
49
- if (!discovered.raw)
50
- throw new MirrorError('Mirror configuration not found. Run `mirror init package`, `mirror init jsr`, or `mirror init git`.');
51
- return normalizeMirrorConfig(discovered.raw, cwd, discovered.path, options);
52
- };
53
- export const normalizeMirrorConfig = (raw, cwd, configPath, options = {}) => {
54
- if (raw.schema !== 1)
55
- throw new MirrorError('Unsupported or missing configuration schema. Expected `schema = 1`.');
56
- if (raw.version?.scheme !== undefined && raw.version.scheme !== 'semver')
57
- throw new MirrorError('Only `version.scheme = "semver"` is supported.');
58
- const source = options.source ?? assertAdapter(raw.version?.source, 'version.source');
59
- const output = dedupeAdapters(options.output ?? assertOutput(raw.version?.output));
60
- const nameSource = raw.project?.name_source
61
- ? assertProjectNameSource(raw.project.name_source, 'project.name_source')
62
- : undefined;
63
- const projectName = optionalString(raw.project?.name, 'project.name');
64
- const prereleaseId = options.preid ?? optionalString(raw.version?.prerelease_id, 'version.prerelease_id') ?? '';
65
- const packagePath = options.packageFile ?? optionalString(raw.package?.path, 'package.path') ?? 'package.json';
66
- const packageAuxiliaryPaths = assertStringArray(raw.package?.auxiliary_paths, 'package.auxiliary_paths');
67
- const jsrPath = options.jsrFile ?? optionalString(raw.jsr?.path, 'jsr.path') ?? 'jsr.json';
68
- const tagTemplate = optionalString(raw.git?.tag_template, 'git.tag_template') ?? 'v{version}';
69
- const gitCommit = optionalBoolean(raw.git?.commit, 'git.commit') === true;
70
- const gitPush = optionalBoolean(raw.git?.push, 'git.push') === true;
71
- const gitAllowDirty = optionalBoolean(raw.git?.allow_dirty, 'git.allow_dirty') === true;
72
- const writeChangelog = optionalBoolean(raw.agents?.write_changelog, 'agents.write_changelog') !== false;
73
- const changelogPath = optionalString(raw.agents?.changelog_path, 'agents.changelog_path') ?? 'CHANGELOG.md';
74
- const autoAgentsMd = optionalBoolean(raw.agents?.auto_agents_md, 'agents.auto_agents_md') !== false;
75
- const autoSkillInstall = optionalBoolean(raw.agents?.auto_skill_install, 'agents.auto_skill_install') !== false;
76
- return {
77
- schema: 1,
78
- cwd,
79
- configPath,
80
- project: {
81
- name: projectName,
82
- nameSource,
83
- },
84
- version: {
85
- scheme: 'semver',
86
- source,
87
- output,
88
- prereleaseId,
89
- },
90
- package: {
91
- path: packagePath,
92
- auxiliaryPaths: packageAuxiliaryPaths,
93
- },
94
- jsr: {
95
- path: jsrPath,
96
- },
97
- git: {
98
- tagTemplate,
99
- commit: options.commit === true || options.push === true || gitCommit || gitPush,
100
- push: options.push === true || gitPush,
101
- allowDirty: options.allowDirty === true || gitAllowDirty,
102
- },
103
- agents: {
104
- writeChangelog,
105
- changelogPath,
106
- autoAgentsMd,
107
- autoSkillInstall,
108
- },
109
- };
110
- };
111
- export const defaultInitAnswersForSource = (kind, cwd) => ({
112
- source: kind,
113
- output: kind === 'git' ? ['git'] : [kind, 'git'],
114
- packagePath: 'package.json',
115
- auxiliaryPaths: [],
116
- jsrPath: 'jsr.json',
117
- name: kind === 'git' ? basename(cwd) : undefined,
118
- prereleaseId: '',
119
- tagTemplate: '{name}@{version}',
120
- commit: kind !== 'git',
121
- push: false,
122
- });
123
- export const generateInitConfig = (answers, cwd) => {
124
- const lines = [];
125
- lines.push(`#:schema ${mirrorConfigSchemaReference}`);
126
- lines.push('');
127
- lines.push('schema = 1');
128
- lines.push('');
129
- lines.push('[project]');
130
- if (answers.source === 'package.json')
131
- lines.push('name_source = "package.json"');
132
- else if (answers.source === 'jsr.json')
133
- lines.push('name_source = "jsr.json"');
134
- else
135
- lines.push(`name = "${answers.name ?? basename(cwd)}"`);
136
- lines.push('');
137
- lines.push('[version]');
138
- lines.push('scheme = "semver"');
139
- lines.push(`source = "${answers.source}"`);
140
- lines.push(`output = [${answers.output.map((value) => `"${value}"`).join(', ')}]`);
141
- lines.push(`prerelease_id = "${answers.prereleaseId}"`);
142
- lines.push('');
143
- lines.push('[package]');
144
- lines.push(`path = "${answers.packagePath}"`);
145
- lines.push(`auxiliary_paths = [${answers.auxiliaryPaths.map((value) => `"${value}"`).join(', ')}]`);
146
- lines.push('');
147
- lines.push('[jsr]');
148
- lines.push(`path = "${answers.jsrPath}"`);
149
- lines.push('');
150
- lines.push('[git]');
151
- lines.push(`tag_template = "${answers.tagTemplate}"`);
152
- lines.push(`commit = ${String(answers.commit)}`);
153
- lines.push(`push = ${String(answers.push)}`);
154
- lines.push('allow_dirty = false');
155
- lines.push('');
156
- lines.push('[agents]');
157
- lines.push('write_changelog = true');
158
- lines.push('changelog_path = "CHANGELOG.md"');
159
- lines.push('auto_agents_md = true');
160
- lines.push('auto_skill_install = true');
161
- return `${lines.join('\n')}\n`;
162
- };
163
- export const createInitConfig = (kind, cwd) => generateInitConfig(defaultInitAnswersForSource(kind, cwd), cwd);
164
- export const writeInitConfig = async (kind, cwd, overwrite = false) => writeInitConfigFromAnswers(defaultInitAnswersForSource(kind, cwd), cwd, overwrite);
165
- export const writeInitConfigFromAnswers = async (answers, cwd, overwrite = false) => {
166
- const path = join(cwd, 'mirror.config.toml');
167
- const generated = generateInitConfig(answers, cwd);
168
- if (existsSync(path) && !overwrite) {
169
- await writeFile(path, reconcileInitConfig(await readFile(path, 'utf8'), generated), 'utf8');
170
- return path;
171
- }
172
- await writeFile(path, generated, 'utf8');
173
- return path;
174
- };
175
- export const reconcileInitConfig = (existingContent, defaultsContent) => {
176
- const existingRaw = parseConfigContent(existingContent, 'existing configuration');
177
- const defaultsRaw = parseConfigContent(defaultsContent, 'default configuration');
178
- const additions = [];
179
- for (const [sectionName, defaultSection] of Object.entries(defaultsRaw)) {
180
- if (!isRecord(defaultSection))
181
- continue;
182
- const existingSection = existingRaw[sectionName];
183
- if (!isRecord(existingSection)) {
184
- additions.push(renderTomlSection(sectionName, defaultSection));
185
- continue;
186
- }
187
- const missingValues = Object.fromEntries(Object.entries(defaultSection).filter(([key]) => existingSection[key] === undefined));
188
- if (Object.keys(missingValues).length > 0)
189
- existingContent = insertTomlValuesIntoSection(existingContent, sectionName, missingValues);
190
- }
191
- if (additions.length === 0)
192
- return existingContent;
193
- return `${existingContent.trimEnd()}\n\n${additions.join('\n\n')}\n`;
194
- };
195
- export const configPathForDisplay = (config) => (config.configPath ? relativeFromCwd(config.cwd, config.configPath) : '(none)');
196
- const assertAdapter = (value, key) => {
197
- if (typeof value !== 'string' || !adapters.has(value))
198
- throw new MirrorError(`Invalid or missing ${key}. Expected package.json, jsr.json, or git.`);
199
- return value;
200
- };
201
- const assertProjectNameSource = (value, key) => {
202
- if (typeof value !== 'string' || !projectNameSources.has(value))
203
- throw new MirrorError(`Invalid ${key}. Expected package.json or jsr.json.`);
204
- return value;
205
- };
206
- const assertOutput = (value) => {
207
- if (!Array.isArray(value) || value.length === 0)
208
- throw new MirrorError('Invalid or missing version.output. Expected at least one output adapter.');
209
- return value.map((item) => assertAdapter(item, 'version.output'));
210
- };
211
- const assertStringArray = (value, key) => {
212
- if (value === undefined)
213
- return [];
214
- if (!Array.isArray(value))
215
- throw new MirrorError(`Invalid ${key}. Expected an array of strings.`);
216
- return value.map((item) => {
217
- if (typeof item !== 'string' || item.length === 0)
218
- throw new MirrorError(`Invalid ${key}. Expected an array of strings.`);
219
- return item;
220
- });
221
- };
222
- const dedupeAdapters = (value) => [...new Set(value)];
223
- const optionalString = (value, key) => {
224
- if (value === undefined)
225
- return undefined;
226
- if (typeof value !== 'string')
227
- throw new MirrorError(`Invalid ${key}. Expected a string.`);
228
- return value;
229
- };
230
- const optionalBoolean = (value, key) => {
231
- if (value === undefined)
232
- return undefined;
233
- if (typeof value !== 'boolean')
234
- throw new MirrorError(`Invalid ${key}. Expected true or false.`);
235
- return value;
236
- };
237
- const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
238
- const parseConfigContent = (content, label) => {
239
- let parsed;
240
- try {
241
- parsed = parseToml(content);
242
- }
243
- catch (error) {
244
- const message = error instanceof Error ? error.message : String(error);
245
- throw new MirrorError(`Invalid TOML in ${label}:\n${message}`);
246
- }
247
- if (!isRecord(parsed))
248
- throw new MirrorError(`Invalid ${label}. Expected a TOML object.`);
249
- return parsed;
250
- };
251
- const renderTomlSection = (sectionName, values) => {
252
- const lines = [`[${sectionName}]`];
253
- for (const [key, value] of Object.entries(values)) {
254
- lines.push(`${key} = ${renderTomlValue(value)}`);
255
- }
256
- return lines.join('\n');
257
- };
258
- const insertTomlValuesIntoSection = (content, sectionName, values) => {
259
- const lines = content.split(/\r?\n/);
260
- const sectionIndex = lines.findIndex((line) => line.trim() === `[${sectionName}]`);
261
- if (sectionIndex === -1)
262
- return `${content.trimEnd()}\n\n${renderTomlSection(sectionName, values)}\n`;
263
- const nextSectionIndex = lines.findIndex((line, index) => index > sectionIndex && /^\[[^\]]+]\s*$/.test(line.trim()));
264
- const insertIndex = nextSectionIndex === -1 ? lines.length : nextSectionIndex;
265
- const renderedValues = Object.entries(values).map(([key, value]) => `${key} = ${renderTomlValue(value)}`);
266
- lines.splice(insertIndex, 0, ...renderedValues);
267
- return lines.join('\n');
268
- };
269
- const renderTomlValue = (value) => {
270
- if (typeof value === 'string')
271
- return JSON.stringify(value);
272
- if (typeof value === 'number' || typeof value === 'boolean')
273
- return String(value);
274
- if (Array.isArray(value))
275
- return `[${value.map(renderTomlValue).join(', ')}]`;
276
- throw new MirrorError('Cannot render unsupported init configuration value.');
277
- };
@@ -1,9 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- export declare class MirrorError extends Error {
5
- readonly exitCode: number;
6
- constructor(message: string, exitCode?: number);
7
- }
8
- export declare const invariant: (condition: unknown, message: string) => asserts condition;
9
- //# sourceMappingURL=errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../source/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBAEb,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI;CAK1C;AAED,eAAO,MAAM,SAAS,GAAI,WAAW,OAAO,EAAE,SAAS,MAAM,KAAG,QAAQ,SAEvE,CAAA"}
package/library/errors.js DELETED
@@ -1,15 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- export class MirrorError extends Error {
5
- exitCode;
6
- constructor(message, exitCode = 1) {
7
- super(message);
8
- this.name = 'MirrorError';
9
- this.exitCode = exitCode;
10
- }
11
- }
12
- export const invariant = (condition, message) => {
13
- if (!condition)
14
- throw new MirrorError(message);
15
- };
@@ -1,7 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import type { MirrorCliOptions, MirrorExecutionResult } from './types.js';
5
- export declare const applyVersionPlan: (target: string, options?: MirrorCliOptions) => Promise<MirrorExecutionResult>;
6
- export declare const executeVersionPlan: (plan: MirrorExecutionResult["plan"], options?: MirrorCliOptions) => Promise<MirrorExecutionResult>;
7
- //# sourceMappingURL=executor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../source/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAKzE,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,EAAE,UAAS,gBAAqB,KAAG,OAAO,CAAC,qBAAqB,CAIpH,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,MAAM,qBAAqB,CAAC,MAAM,CAAC,EACnC,UAAS,gBAAqB,KAC7B,OAAO,CAAC,qBAAqB,CAgB/B,CAAA"}
@@ -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 { MirrorError } from './errors.js';
5
- import { createGitCommit, createGitTag, isGitDirty, isGitRepository, pushGitRefs, writeJsrVersionFile, writePackageVersionFile } from './adapters.js';
6
- import { buildVersionPlan } from './plan.js';
7
- export const applyVersionPlan = async (target, options = {}) => {
8
- const plan = await buildVersionPlan(target, options);
9
- return executeVersionPlan(plan, options);
10
- };
11
- export const executeVersionPlan = async (plan, options = {}) => {
12
- if (options.dryRun)
13
- return { plan, applied: false, dryRun: true };
14
- if (!plan.allowDirty && (await isGitRepository(plan.cwd)) && (await isGitDirty(plan.cwd))) {
15
- throw new MirrorError('Git worktree is dirty. Commit changes or pass --allow-dirty.');
16
- }
17
- if (!options.yes)
18
- throw new MirrorError('Refusing to apply without confirmation. Pass --yes to apply the plan.');
19
- for (const action of plan.actions) {
20
- if (action.type === 'write-file' && action.adapter === 'package.json')
21
- await writePackageVersionFile(action.path, plan.nextVersion);
22
- if (action.type === 'write-file' && action.adapter === 'jsr.json')
23
- await writeJsrVersionFile(action.path, plan.nextVersion);
24
- if (action.type === 'git-commit')
25
- await createGitCommit(plan.cwd, action.paths, action.message);
26
- if (action.type === 'git-tag')
27
- await createGitTag(plan.cwd, action.tag);
28
- if (action.type === 'git-push')
29
- await pushGitRefs(plan.cwd, action.includeCommit, action.includeTags);
30
- }
31
- return { plan, applied: true, dryRun: false };
32
- };
@@ -1,6 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import type { MirrorCliOptions } from './types.js';
5
- export declare const parseMirrorCliOptions: (rawArgs: string[]) => MirrorCliOptions;
6
- //# sourceMappingURL=flags.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../source/flags.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAqB,gBAAgB,EAAgB,MAAM,YAAY,CAAA;AAenF,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,EAAE,KAAG,gBAkEzD,CAAA"}
package/library/flags.js DELETED
@@ -1,80 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import { MirrorError } from './errors.js';
5
- const booleanFlags = new Set(['dry-run', 'commit', 'push', 'allow-dirty', 'non-interactive', 'yes', 'no-color', 'verbose', 'help', 'version']);
6
- const adapterNames = new Set(['package.json', 'jsr.json', 'git']);
7
- const shortFlagAliases = {
8
- '-dy': '--dry-run',
9
- '-y': '--yes',
10
- };
11
- const normalizeKey = (key) => key.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase());
12
- const expandShortFlags = (rawArgs) => rawArgs.map((token) => shortFlagAliases[token] ?? token);
13
- export const parseMirrorCliOptions = (rawArgs) => {
14
- const parsed = {};
15
- const args = expandShortFlags(rawArgs);
16
- for (let index = 0; index < args.length; index += 1) {
17
- const token = args[index];
18
- if (!token?.startsWith('--'))
19
- continue;
20
- const withoutPrefix = token.slice(2);
21
- const equalsIndex = withoutPrefix.indexOf('=');
22
- const rawKey = equalsIndex >= 0 ? withoutPrefix.slice(0, equalsIndex) : withoutPrefix;
23
- const key = normalizeKey(rawKey);
24
- if (booleanFlags.has(rawKey)) {
25
- parsed[key] = true;
26
- continue;
27
- }
28
- const value = equalsIndex >= 0
29
- ? withoutPrefix.slice(equalsIndex + 1)
30
- : args[index + 1] && !args[index + 1]?.startsWith('-')
31
- ? args[++index] ?? ''
32
- : '';
33
- if (!value)
34
- throw new MirrorError(`Missing value for --${rawKey}`);
35
- if (key === 'output') {
36
- const nextValues = value.split(',').map((item) => item.trim()).filter(Boolean);
37
- const current = parsed['output'];
38
- parsed['output'] = [...(Array.isArray(current) ? current : current ? [String(current)] : []), ...nextValues];
39
- continue;
40
- }
41
- if (key === 'auxiliary') {
42
- const nextValues = value.split(',').map((item) => item.trim()).filter(Boolean);
43
- const current = parsed['auxiliary'];
44
- parsed['auxiliary'] = [...(Array.isArray(current) ? current : current ? [String(current)] : []), ...nextValues];
45
- continue;
46
- }
47
- parsed[key] = value;
48
- }
49
- return {
50
- cwd: typeof parsed['cwd'] === 'string' ? parsed['cwd'] : undefined,
51
- config: typeof parsed['config'] === 'string' ? parsed['config'] : undefined,
52
- format: typeof parsed['format'] === 'string' ? assertFormat(parsed['format']) : undefined,
53
- noColor: parsed['noColor'] === true,
54
- source: typeof parsed['source'] === 'string' ? assertAdapter(parsed['source'], '--source') : undefined,
55
- output: Array.isArray(parsed['output']) ? parsed['output'].map((value) => assertAdapter(value, '--output')) : undefined,
56
- packageFile: typeof parsed['packageFile'] === 'string' ? parsed['packageFile'] : undefined,
57
- jsrFile: typeof parsed['jsrFile'] === 'string' ? parsed['jsrFile'] : undefined,
58
- auxiliary: Array.isArray(parsed['auxiliary']) ? parsed['auxiliary'].map((value) => String(value)) : undefined,
59
- tagTemplate: typeof parsed['tagTemplate'] === 'string' ? parsed['tagTemplate'] : undefined,
60
- name: typeof parsed['name'] === 'string' ? parsed['name'] : undefined,
61
- preid: typeof parsed['preid'] === 'string' ? parsed['preid'] : undefined,
62
- dryRun: parsed['dryRun'] === true,
63
- commit: parsed['commit'] === true,
64
- push: parsed['push'] === true,
65
- allowDirty: parsed['allowDirty'] === true,
66
- nonInteractive: parsed['nonInteractive'] === true,
67
- yes: parsed['yes'] === true,
68
- verbose: parsed['verbose'] === true,
69
- };
70
- };
71
- const assertAdapter = (value, flagName) => {
72
- if (!adapterNames.has(value))
73
- throw new MirrorError(`Invalid ${flagName} value: ${value}`);
74
- return value;
75
- };
76
- const assertFormat = (value) => {
77
- if (value !== 'text' && value !== 'json')
78
- throw new MirrorError(`Invalid --format value: ${value}`);
79
- return value;
80
- };
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
4
- */
5
- export {};
6
- //# sourceMappingURL=guiho-mirror-bin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guiho-mirror-bin.d.ts","sourceRoot":"","sources":["../source/guiho-mirror-bin.ts"],"names":[],"mappings":";AACA;;GAEG"}
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
4
- */
5
- import { runMirrorCli } from './guiho-mirror.js';
6
- await runMirrorCli();
@@ -1,17 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- export type { MirrorAdapterName, MirrorCliOptions, MirrorConfig, MirrorExecutionResult, MirrorFormat, MirrorAgentAutomationResult, MirrorAgentSettings, MirrorAgentsInstructionsResult, MirrorInitAnswers, MirrorInitFlags, MirrorInitPrompter, MirrorRawConfig, MirrorSkillInstallResult, MirrorSkillInstallScope, MirrorVersionPlan, MirrorVersionPlanAction, MirrorVersionTarget, } from './types.js';
5
- export { MirrorError, invariant } from './errors.js';
6
- export { parseMirrorCliOptions } from './flags.js';
7
- export { defaultMirrorAgentSettings, ensureMirrorAgentsInstructions, findAgentsFile, installMirrorSkill, isMirrorSkillInstalled, mirrorAgentsSection, mirrorAgentsSectionHeading, mirrorSkillName, resolveMirrorAgentSettings, resolveMirrorSkillPath, runMirrorAgentAutomation, } from './agents.js';
8
- export { createInitConfig, defaultInitAnswersForSource, discoverMirrorConfig, generateInitConfig, loadMirrorConfig, normalizeMirrorConfig, reconcileInitConfig, writeInitConfig, writeInitConfigFromAnswers, } from './config.js';
9
- export { createReadlineInitPrompter, isInteractiveInit, parseAdapterList, resolveInitAnswers } from './init.js';
10
- export { mirrorConfigJsonSchema, mirrorConfigSchemaReference, renderMirrorConfigJsonSchema } from './schema.js';
11
- export { assertValidSemver, isMirrorReleaseTarget, mirrorReleaseTargets, resolveNextVersion, sortSemverDescending } from './version.js';
12
- export { createGitCommit, createGitTag, ensureAdapterFiles, ensureGitAvailable, assertSupportedGitTagTemplate, isGitDirty, isGitRepository, readCurrentVersion, readGitVersion, readJsrName, readJsrVersion, readJsrVersionFile, readPackageName, readPackageVersion, readPackageVersionFile, renderGitTag, resolveProjectName, supportedGitTagTemplates, versionFromTag, writeJsrVersion, writeJsrVersionFile, writePackageVersion, writePackageVersionFile, } from './adapters.js';
13
- export { buildVersionPlan, releaseLabel, resolveFileOutputPaths, validateMirrorConfig } from './plan.js';
14
- export { applyVersionPlan, executeVersionPlan } from './executor.js';
15
- export { mirrorBanner, reportAgentsInstructions, reportConfig, reportConfigSchema, reportExecution, reportExecutionSummary, reportPlan, reportSkillInstall, reportValue, } from './reporter.js';
16
- export { createMirrorCommand, runMirrorCli } from './cli.js';
17
- //# sourceMappingURL=guiho-mirror.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guiho-mirror.d.ts","sourceRoot":"","sources":["../source/guiho-mirror.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,qBAAqB,EACrB,YAAY,EACZ,2BAA2B,EAC3B,mBAAmB,EACnB,8BAA8B,EAC9B,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,EAC9B,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,EAC1B,eAAe,EACf,0BAA0B,EAC1B,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,gBAAgB,EAChB,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,0BAA0B,GAC3B,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC/G,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA;AAC/G,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACvI,OAAO,EACL,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,6BAA6B,EAC7B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACxG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACpE,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EAClB,WAAW,GACZ,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA"}
@@ -1,15 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- export { MirrorError, invariant } from './errors.js';
5
- export { parseMirrorCliOptions } from './flags.js';
6
- export { defaultMirrorAgentSettings, ensureMirrorAgentsInstructions, findAgentsFile, installMirrorSkill, isMirrorSkillInstalled, mirrorAgentsSection, mirrorAgentsSectionHeading, mirrorSkillName, resolveMirrorAgentSettings, resolveMirrorSkillPath, runMirrorAgentAutomation, } from './agents.js';
7
- export { createInitConfig, defaultInitAnswersForSource, discoverMirrorConfig, generateInitConfig, loadMirrorConfig, normalizeMirrorConfig, reconcileInitConfig, writeInitConfig, writeInitConfigFromAnswers, } from './config.js';
8
- export { createReadlineInitPrompter, isInteractiveInit, parseAdapterList, resolveInitAnswers } from './init.js';
9
- export { mirrorConfigJsonSchema, mirrorConfigSchemaReference, renderMirrorConfigJsonSchema } from './schema.js';
10
- export { assertValidSemver, isMirrorReleaseTarget, mirrorReleaseTargets, resolveNextVersion, sortSemverDescending } from './version.js';
11
- export { createGitCommit, createGitTag, ensureAdapterFiles, ensureGitAvailable, assertSupportedGitTagTemplate, isGitDirty, isGitRepository, readCurrentVersion, readGitVersion, readJsrName, readJsrVersion, readJsrVersionFile, readPackageName, readPackageVersion, readPackageVersionFile, renderGitTag, resolveProjectName, supportedGitTagTemplates, versionFromTag, writeJsrVersion, writeJsrVersionFile, writePackageVersion, writePackageVersionFile, } from './adapters.js';
12
- export { buildVersionPlan, releaseLabel, resolveFileOutputPaths, validateMirrorConfig } from './plan.js';
13
- export { applyVersionPlan, executeVersionPlan } from './executor.js';
14
- export { mirrorBanner, reportAgentsInstructions, reportConfig, reportConfigSchema, reportExecution, reportExecutionSummary, reportPlan, reportSkillInstall, reportValue, } from './reporter.js';
15
- export { createMirrorCommand, runMirrorCli } from './cli.js';
package/library/init.d.ts DELETED
@@ -1,12 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import type { MirrorAdapterName, MirrorInitAnswers, MirrorInitFlags, MirrorInitPrompter } from './types.js';
5
- export declare const parseAdapterList: (value: string) => MirrorAdapterName[];
6
- export declare const resolveInitAnswers: (flags: MirrorInitFlags, cwd: string, prompter?: MirrorInitPrompter) => Promise<MirrorInitAnswers>;
7
- export declare const isInteractiveInit: (options: {
8
- yes?: boolean;
9
- nonInteractive?: boolean;
10
- }) => boolean;
11
- export declare const createReadlineInitPrompter: () => MirrorInitPrompter;
12
- //# sourceMappingURL=init.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../source/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAI3G,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,iBAAiB,EAQjE,CAAA;AAQD,eAAO,MAAM,kBAAkB,GAC7B,OAAO,eAAe,EACtB,KAAK,MAAM,EACX,WAAW,kBAAkB,KAC5B,OAAO,CAAC,iBAAiB,CAkD3B,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,SAAS;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,YACG,CAAA;AAEzF,eAAO,MAAM,0BAA0B,QAAO,kBAmB7C,CAAA"}
package/library/init.js DELETED
@@ -1,100 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import { createInterface } from 'node:readline/promises';
5
- import { basename } from 'node:path';
6
- const adapterValues = new Set(['package.json', 'jsr.json', 'git']);
7
- export const parseAdapterList = (value) => {
8
- const values = value
9
- .split(',')
10
- .map((item) => item.trim())
11
- .filter(Boolean)
12
- .filter((item) => adapterValues.has(item));
13
- return [...new Set(values)];
14
- };
15
- const parsePathList = (value) => value
16
- .split(',')
17
- .map((item) => item.trim())
18
- .filter(Boolean);
19
- export const resolveInitAnswers = async (flags, cwd, prompter) => {
20
- const source = flags.source ?? (await askAdapter(prompter, 'Version source (package.json, jsr.json, git)', 'package.json'));
21
- const output = flags.output ?? (await askAdapterList(prompter, 'Version outputs (comma separated)', ['package.json', 'git']));
22
- const usesPackage = source === 'package.json' || output.includes('package.json');
23
- const usesJsr = source === 'jsr.json' || output.includes('jsr.json');
24
- const usesGit = source === 'git' || output.includes('git');
25
- const hasFileOutput = output.includes('package.json') || output.includes('jsr.json');
26
- const packagePath = usesPackage
27
- ? flags.packagePath ?? (prompter ? await prompter.text('package.json path', 'package.json') : 'package.json')
28
- : 'package.json';
29
- const auxiliaryPaths = usesPackage
30
- ? flags.auxiliaryPaths ??
31
- (prompter ? parsePathList(await prompter.text('Auxiliary package.json paths (comma separated, blank for none)', '')) : [])
32
- : [];
33
- const jsrPath = usesJsr
34
- ? flags.jsrPath ?? (prompter ? await prompter.text('jsr.json path', 'jsr.json') : 'jsr.json')
35
- : 'jsr.json';
36
- const name = flags.name ?? (source === 'git' ? basename(cwd) : undefined);
37
- const nameAvailable = source === 'package.json' || source === 'jsr.json' || Boolean(name);
38
- const defaultTagTemplate = nameAvailable ? '{name}@{version}' : 'v{version}';
39
- const tagTemplate = usesGit
40
- ? flags.tagTemplate ?? (prompter ? await prompter.text('Git tag template', defaultTagTemplate) : defaultTagTemplate)
41
- : defaultTagTemplate;
42
- const defaultCommit = usesGit && hasFileOutput;
43
- const commit = flags.commit ?? (usesGit && prompter ? await prompter.confirm('Create release commits?', defaultCommit) : defaultCommit);
44
- const push = flags.push ?? (usesGit && prompter ? await prompter.confirm('Push release refs?', false) : false);
45
- const prereleaseId = flags.prereleaseId ?? '';
46
- return {
47
- source,
48
- output,
49
- packagePath,
50
- auxiliaryPaths,
51
- jsrPath,
52
- name,
53
- prereleaseId,
54
- tagTemplate,
55
- commit,
56
- push,
57
- };
58
- };
59
- export const isInteractiveInit = (options) => Boolean(process.stdin.isTTY) && options.yes !== true && options.nonInteractive !== true;
60
- export const createReadlineInitPrompter = () => {
61
- const rl = createInterface({ input: process.stdin, output: process.stdout });
62
- return {
63
- async text(question, defaultValue) {
64
- const suffix = defaultValue.length > 0 ? ` [${defaultValue}]` : ' [none]';
65
- const answer = (await rl.question(`${question}${suffix}: `)).trim();
66
- return answer.length > 0 ? answer : defaultValue;
67
- },
68
- async confirm(question, defaultValue) {
69
- const suffix = defaultValue ? ' [Y/n]' : ' [y/N]';
70
- const answer = (await rl.question(`${question}${suffix}: `)).trim().toLowerCase();
71
- if (answer.length === 0)
72
- return defaultValue;
73
- return answer === 'y' || answer === 'yes';
74
- },
75
- close() {
76
- rl.close();
77
- },
78
- };
79
- };
80
- const askAdapter = async (prompter, question, defaultValue) => {
81
- if (!prompter)
82
- return defaultValue;
83
- for (let attempt = 0; attempt < 3; attempt += 1) {
84
- const answer = (await prompter.text(question, defaultValue)).trim();
85
- if (adapterValues.has(answer))
86
- return answer;
87
- }
88
- return defaultValue;
89
- };
90
- const askAdapterList = async (prompter, question, defaultValue) => {
91
- if (!prompter)
92
- return defaultValue;
93
- for (let attempt = 0; attempt < 3; attempt += 1) {
94
- const answer = await prompter.text(question, defaultValue.join(', '));
95
- const parsed = parseAdapterList(answer);
96
- if (parsed.length > 0)
97
- return parsed;
98
- }
99
- return defaultValue;
100
- };
package/library/plan.d.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
- */
4
- import type { MirrorCliOptions, MirrorConfig, MirrorVersionPlan } from './types.js';
5
- export declare const validateMirrorConfig: (options?: MirrorCliOptions) => Promise<MirrorConfig>;
6
- export declare const buildVersionPlan: (target: string, options?: MirrorCliOptions) => Promise<MirrorVersionPlan>;
7
- export declare const resolveFileOutputPaths: (config: MirrorConfig) => string[];
8
- export declare const releaseLabel: (version: string, projectName?: string) => string;
9
- export declare const planPathForDisplay: (plan: MirrorVersionPlan, path: string) => string;
10
- //# sourceMappingURL=plan.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../source/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAA;AAM5G,eAAO,MAAM,oBAAoB,GAAU,UAAS,gBAAqB,KAAG,OAAO,CAAC,YAAY,CAW/F,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,EAAE,UAAS,gBAAqB,KAAG,OAAO,CAAC,iBAAiB,CA8DhH,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,QAAQ,YAAY,aAU1D,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,cAAc,MAAM,WAAgE,CAAA;AAElI,eAAO,MAAM,kBAAkB,GAAI,MAAM,iBAAiB,EAAE,MAAM,MAAM,WAAoC,CAAA"}