@schnick371/devsteps-shared 1.1.0-next.2 → 1.1.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/agents.test.d.ts +18 -0
- package/dist/agents.test.d.ts.map +1 -0
- package/dist/agents.test.js +96 -0
- package/dist/agents.test.js.map +1 -0
- package/dist/constants/index.d.ts +2 -2
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +2 -2
- package/dist/constants/index.js.map +1 -1
- package/dist/core/add.d.ts.map +1 -1
- package/dist/core/add.js +4 -3
- package/dist/core/add.js.map +1 -1
- package/dist/core/context.d.ts +44 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +326 -1
- package/dist/core/context.js.map +1 -1
- package/dist/core/context.test.d.ts +10 -0
- package/dist/core/context.test.d.ts.map +1 -0
- package/dist/core/context.test.js +239 -0
- package/dist/core/context.test.js.map +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/update.js +4 -4
- package/dist/core/update.js.map +1 -1
- package/dist/schemas/cbp-mandate.d.ts +141 -6
- package/dist/schemas/cbp-mandate.d.ts.map +1 -1
- package/dist/schemas/cbp-mandate.js +121 -18
- package/dist/schemas/cbp-mandate.js.map +1 -1
- package/dist/schemas/cbp-mandate.test.d.ts +2 -1
- package/dist/schemas/cbp-mandate.test.d.ts.map +1 -1
- package/dist/schemas/cbp-mandate.test.js +130 -6
- package/dist/schemas/cbp-mandate.test.js.map +1 -1
- package/dist/utils/backup-github-files.d.ts +34 -0
- package/dist/utils/backup-github-files.d.ts.map +1 -0
- package/dist/utils/backup-github-files.js +137 -0
- package/dist/utils/backup-github-files.js.map +1 -0
- package/dist/utils/index.d.ts +25 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +36 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/init-helpers.d.ts +14 -1
- package/dist/utils/init-helpers.d.ts.map +1 -1
- package/dist/utils/init-helpers.js +37 -2
- package/dist/utils/init-helpers.js.map +1 -1
- package/dist/utils/normalize.test.d.ts +15 -0
- package/dist/utils/normalize.test.d.ts.map +1 -0
- package/dist/utils/normalize.test.js +101 -0
- package/dist/utils/normalize.test.js.map +1 -0
- package/dist/utils/update-copilot-files.d.ts +59 -0
- package/dist/utils/update-copilot-files.d.ts.map +1 -0
- package/dist/utils/update-copilot-files.js +183 -0
- package/dist/utils/update-copilot-files.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Unit Tests for normalizeMarkdown utility
|
|
6
|
+
*
|
|
7
|
+
* Context: MCP clients (GitHub Copilot ≥ v1.0.0, Claude Code, etc.) transmit
|
|
8
|
+
* multiline strings as literal escape sequences rather than real Unicode control
|
|
9
|
+
* characters. normalizeMarkdown converts these safely at the ingestion boundary.
|
|
10
|
+
*
|
|
11
|
+
* @see BUG-056
|
|
12
|
+
* @see TASK-270
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=normalize.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.test.d.ts","sourceRoot":"","sources":["../../src/utils/normalize.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Unit Tests for normalizeMarkdown utility
|
|
6
|
+
*
|
|
7
|
+
* Context: MCP clients (GitHub Copilot ≥ v1.0.0, Claude Code, etc.) transmit
|
|
8
|
+
* multiline strings as literal escape sequences rather than real Unicode control
|
|
9
|
+
* characters. normalizeMarkdown converts these safely at the ingestion boundary.
|
|
10
|
+
*
|
|
11
|
+
* @see BUG-056
|
|
12
|
+
* @see TASK-270
|
|
13
|
+
*/
|
|
14
|
+
import { describe, expect, it } from 'vitest';
|
|
15
|
+
import { normalizeMarkdown } from './index.js';
|
|
16
|
+
describe('normalizeMarkdown', () => {
|
|
17
|
+
// ── Core conversion ─────────────────────────────────────────────────────────
|
|
18
|
+
it('converts literal \\n sequences to real newlines', () => {
|
|
19
|
+
const input = 'line one\\nline two\\nline three';
|
|
20
|
+
const result = normalizeMarkdown(input);
|
|
21
|
+
expect(result).toBe('line one\nline two\nline three');
|
|
22
|
+
expect(result).toContain('\n');
|
|
23
|
+
expect(result).not.toContain('\\n');
|
|
24
|
+
});
|
|
25
|
+
it('converts literal \\t sequences to real tabs', () => {
|
|
26
|
+
const input = 'column1\\tcolumn2\\tcolumn3';
|
|
27
|
+
const result = normalizeMarkdown(input);
|
|
28
|
+
expect(result).toBe('column1\tcolumn2\tcolumn3');
|
|
29
|
+
expect(result).toContain('\t');
|
|
30
|
+
expect(result).not.toContain('\\t');
|
|
31
|
+
});
|
|
32
|
+
it('removes literal \\r sequences (stray CR from Windows \\r\\n literals)', () => {
|
|
33
|
+
const input = 'line one\\r\\nline two';
|
|
34
|
+
const result = normalizeMarkdown(input);
|
|
35
|
+
expect(result).toBe('line one\nline two');
|
|
36
|
+
expect(result).not.toContain('\\r');
|
|
37
|
+
expect(result).not.toContain('\r');
|
|
38
|
+
});
|
|
39
|
+
it('handles all escape sequences together', () => {
|
|
40
|
+
const input = 'Title\\n\\nParagraph one.\\n\\n- Item 1\\n- Item 2\\n\\n\\tIndented';
|
|
41
|
+
const result = normalizeMarkdown(input);
|
|
42
|
+
expect(result).toBe('Title\n\nParagraph one.\n\n- Item 1\n- Item 2\n\n\tIndented');
|
|
43
|
+
});
|
|
44
|
+
// ── Idempotency (fast path) ──────────────────────────────────────────────────
|
|
45
|
+
it('leaves strings with real newlines unchanged (fast path)', () => {
|
|
46
|
+
const input = 'line one\nline two\nline three';
|
|
47
|
+
const result = normalizeMarkdown(input);
|
|
48
|
+
expect(result).toBe(input);
|
|
49
|
+
});
|
|
50
|
+
it('is idempotent: calling twice on already-converted string returns same result', () => {
|
|
51
|
+
const original = 'line one\\nline two';
|
|
52
|
+
const once = normalizeMarkdown(original);
|
|
53
|
+
const twice = normalizeMarkdown(once);
|
|
54
|
+
expect(twice).toBe(once);
|
|
55
|
+
});
|
|
56
|
+
it('leaves strings with mixed real newlines and literal \\t unchanged (fast path)', () => {
|
|
57
|
+
const input = 'line one\nline two\\t still here';
|
|
58
|
+
const result = normalizeMarkdown(input);
|
|
59
|
+
// Real newline present → fast path, backslash-t preserved
|
|
60
|
+
expect(result).toBe(input);
|
|
61
|
+
});
|
|
62
|
+
// ── Edge cases ───────────────────────────────────────────────────────────────
|
|
63
|
+
it('returns empty string unchanged', () => {
|
|
64
|
+
expect(normalizeMarkdown('')).toBe('');
|
|
65
|
+
});
|
|
66
|
+
it('returns plain single-line string unchanged', () => {
|
|
67
|
+
const input = 'No escape sequences here.';
|
|
68
|
+
expect(normalizeMarkdown(input)).toBe(input);
|
|
69
|
+
});
|
|
70
|
+
it('handles markdown description with heading and list (typical MCP input)', () => {
|
|
71
|
+
// This is the real-world input that triggered BUG-056
|
|
72
|
+
const mcpInput = '## Implemented\\n\\n### Show-ServerLayoutEditor\\n- Build `nameToRoles` map before rendering table\\n- Rows with shared hostname → ForegroundColor Yellow + ⚠️ indicator\\n\\n### environment.ps1\\n- After saving: rebuild `$env.Nodes` PSCustomObject';
|
|
73
|
+
const result = normalizeMarkdown(mcpInput);
|
|
74
|
+
expect(result).toContain('## Implemented\n');
|
|
75
|
+
expect(result).toContain('### Show-ServerLayoutEditor\n');
|
|
76
|
+
expect(result).toContain('- Build `nameToRoles`');
|
|
77
|
+
expect(result).not.toContain('\\n');
|
|
78
|
+
});
|
|
79
|
+
it('handles default description template with real newlines (CLI usage)', () => {
|
|
80
|
+
// CLI users provide real newlines — must NOT be double-converted
|
|
81
|
+
const cliInput = '# My Story\n\n<!-- Add detailed description here -->\n';
|
|
82
|
+
const result = normalizeMarkdown(cliInput);
|
|
83
|
+
expect(result).toBe(cliInput);
|
|
84
|
+
});
|
|
85
|
+
it('handles string with only whitespace', () => {
|
|
86
|
+
expect(normalizeMarkdown(' ')).toBe(' ');
|
|
87
|
+
expect(normalizeMarkdown('\n')).toBe('\n'); // real newline → fast path
|
|
88
|
+
});
|
|
89
|
+
it('preserves Unicode characters correctly', () => {
|
|
90
|
+
const input = 'Emoji: ⚠️\\nArrow: →\\nUmlaut: äöü';
|
|
91
|
+
const result = normalizeMarkdown(input);
|
|
92
|
+
expect(result).toBe('Emoji: ⚠️\nArrow: →\nUmlaut: äöü');
|
|
93
|
+
});
|
|
94
|
+
// ── append_description use case ──────────────────────────────────────────────
|
|
95
|
+
it('normalizes text intended for append_description correctly', () => {
|
|
96
|
+
const appendContent = '\\n\\n## Added in v2\\n- New feature X\\n- Fixed issue Y';
|
|
97
|
+
const result = normalizeMarkdown(appendContent);
|
|
98
|
+
expect(result).toBe('\n\n## Added in v2\n- New feature X\n- Fixed issue Y');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=normalize.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.test.js","sourceRoot":"","sources":["../../src/utils/normalize.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* GitHub Copilot files update utilities
|
|
6
|
+
* Compares installed devsteps-managed .github files against the package source
|
|
7
|
+
* using SHA-256 hashes stored in HTML comments, then selectively updates changed
|
|
8
|
+
* files after creating a timestamped backup.
|
|
9
|
+
*/
|
|
10
|
+
export interface FileUpdateStatus {
|
|
11
|
+
file: string;
|
|
12
|
+
status: 'updated' | 'skipped' | 'added';
|
|
13
|
+
reason?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface UpdateCopilotFilesResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
updatedCount: number;
|
|
18
|
+
skippedCount: number;
|
|
19
|
+
addedCount: number;
|
|
20
|
+
backupDir: string;
|
|
21
|
+
files: FileUpdateStatus[];
|
|
22
|
+
message: string;
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface UpdateCopilotFilesOptions {
|
|
26
|
+
/** DevSteps package version (for comment annotation) */
|
|
27
|
+
packageVersion?: string;
|
|
28
|
+
/** Maximum backup rotations to keep (default: 5) */
|
|
29
|
+
maxBackups?: number;
|
|
30
|
+
/**
|
|
31
|
+
* If true, report what would change but do not write anything.
|
|
32
|
+
* No backup is created in dry-run mode.
|
|
33
|
+
*/
|
|
34
|
+
dryRun?: boolean;
|
|
35
|
+
/** If true, overwrite even when hashes match (force reinstall) */
|
|
36
|
+
force?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Update all devsteps-managed .github Copilot files in a target project.
|
|
40
|
+
*
|
|
41
|
+
* Algorithm per source file:
|
|
42
|
+
* 1. Compute sha256 of raw source content (before annotation).
|
|
43
|
+
* 2. If a corresponding file exists in the target:
|
|
44
|
+
* a. Extract the stored hash from its devsteps HTML comment.
|
|
45
|
+
* b. If hashes match (and `force` is not set): skip — no change needed.
|
|
46
|
+
* c. If hashes differ: mark as "update" candidate.
|
|
47
|
+
* 3. If no corresponding file exists: mark as "add" candidate.
|
|
48
|
+
* After collecting candidates:
|
|
49
|
+
* 4. If there are changes and not dryRun: create a backup first.
|
|
50
|
+
* Abort on backup failure (prevents partial states).
|
|
51
|
+
* 5. Write each candidate with a fresh `injectDevstepsComment`.
|
|
52
|
+
*
|
|
53
|
+
* @param sourceGithubDir Path to the package's bundled `.github` directory.
|
|
54
|
+
* @param targetGithubDir Path to the target project's `.github` directory.
|
|
55
|
+
* @param devstepsDir Path to the target project's `.devsteps` directory (for backups).
|
|
56
|
+
* @param options Optional settings.
|
|
57
|
+
*/
|
|
58
|
+
export declare function updateCopilotFiles(sourceGithubDir: string, targetGithubDir: string, devstepsDir: string, options?: UpdateCopilotFilesOptions): UpdateCopilotFilesResult;
|
|
59
|
+
//# sourceMappingURL=update-copilot-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-copilot-files.d.ts","sourceRoot":"","sources":["../../src/utils/update-copilot-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2BH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAaD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAChC,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,yBAAyB,GAClC,wBAAwB,CAqJ1B"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* GitHub Copilot files update utilities
|
|
6
|
+
* Compares installed devsteps-managed .github files against the package source
|
|
7
|
+
* using SHA-256 hashes stored in HTML comments, then selectively updates changed
|
|
8
|
+
* files after creating a timestamped backup.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from 'node:crypto';
|
|
11
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { backupGithubFiles } from './backup-github-files.js';
|
|
14
|
+
import { injectDevstepsComment } from './init-helpers.js';
|
|
15
|
+
/** Regex that matches `<!-- devsteps-managed: ... | hash: sha256:<hex> ... -->` */
|
|
16
|
+
const MANAGED_COMMENT_RE = /<!--\s*devsteps-managed:.*?hash:\s*sha256:([0-9a-f]{64}).*?-->/;
|
|
17
|
+
/**
|
|
18
|
+
* Extract the sha256 hash embedded in a devsteps-managed HTML comment.
|
|
19
|
+
* Returns null if the file is not managed or has no hash.
|
|
20
|
+
*/
|
|
21
|
+
function extractManagedHash(content) {
|
|
22
|
+
const match = content.match(MANAGED_COMMENT_RE);
|
|
23
|
+
return match ? match[1] : null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Compute sha256 of content (UTF-8) — same function used by injectDevstepsComment.
|
|
27
|
+
*/
|
|
28
|
+
function sha256(content) {
|
|
29
|
+
return createHash('sha256').update(content, 'utf8').digest('hex');
|
|
30
|
+
}
|
|
31
|
+
const SUBDIRS = [
|
|
32
|
+
{ sub: 'agents', suffix: '.agent.md' },
|
|
33
|
+
{ sub: 'instructions', suffix: '.instructions.md' },
|
|
34
|
+
{ sub: 'prompts', suffix: '.prompt.md' },
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Update all devsteps-managed .github Copilot files in a target project.
|
|
38
|
+
*
|
|
39
|
+
* Algorithm per source file:
|
|
40
|
+
* 1. Compute sha256 of raw source content (before annotation).
|
|
41
|
+
* 2. If a corresponding file exists in the target:
|
|
42
|
+
* a. Extract the stored hash from its devsteps HTML comment.
|
|
43
|
+
* b. If hashes match (and `force` is not set): skip — no change needed.
|
|
44
|
+
* c. If hashes differ: mark as "update" candidate.
|
|
45
|
+
* 3. If no corresponding file exists: mark as "add" candidate.
|
|
46
|
+
* After collecting candidates:
|
|
47
|
+
* 4. If there are changes and not dryRun: create a backup first.
|
|
48
|
+
* Abort on backup failure (prevents partial states).
|
|
49
|
+
* 5. Write each candidate with a fresh `injectDevstepsComment`.
|
|
50
|
+
*
|
|
51
|
+
* @param sourceGithubDir Path to the package's bundled `.github` directory.
|
|
52
|
+
* @param targetGithubDir Path to the target project's `.github` directory.
|
|
53
|
+
* @param devstepsDir Path to the target project's `.devsteps` directory (for backups).
|
|
54
|
+
* @param options Optional settings.
|
|
55
|
+
*/
|
|
56
|
+
export function updateCopilotFiles(sourceGithubDir, targetGithubDir, devstepsDir, options) {
|
|
57
|
+
const packageVersion = options?.packageVersion ?? 'unknown';
|
|
58
|
+
const dryRun = options?.dryRun ?? false;
|
|
59
|
+
const force = options?.force ?? false;
|
|
60
|
+
const maxBackups = options?.maxBackups ?? 5;
|
|
61
|
+
const fileStatuses = [];
|
|
62
|
+
const updateCandidates = [];
|
|
63
|
+
// ── Phase 1: Diff source vs. target ─────────────────────────────────────────
|
|
64
|
+
for (const { sub, suffix } of SUBDIRS) {
|
|
65
|
+
const sourceSubDir = join(sourceGithubDir, sub);
|
|
66
|
+
const targetSubDir = join(targetGithubDir, sub);
|
|
67
|
+
if (!existsSync(sourceSubDir))
|
|
68
|
+
continue;
|
|
69
|
+
const sourceFiles = readdirSync(sourceSubDir).filter((f) => f.startsWith('devsteps') && f.endsWith(suffix));
|
|
70
|
+
for (const file of sourceFiles) {
|
|
71
|
+
const sourceFile = join(sourceSubDir, file);
|
|
72
|
+
const targetFile = join(targetSubDir, file);
|
|
73
|
+
const rawContent = readFileSync(sourceFile, 'utf8');
|
|
74
|
+
const sourceHash = sha256(rawContent);
|
|
75
|
+
const rel = `${sub}/${file}`;
|
|
76
|
+
if (existsSync(targetFile)) {
|
|
77
|
+
const installed = readFileSync(targetFile, 'utf8');
|
|
78
|
+
const installedHash = extractManagedHash(installed);
|
|
79
|
+
if (!force && installedHash === sourceHash) {
|
|
80
|
+
fileStatuses.push({ file: rel, status: 'skipped', reason: 'hash-match' });
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const reasonSuffix = installedHash === null
|
|
84
|
+
? 'no-marker'
|
|
85
|
+
: force
|
|
86
|
+
? 'force'
|
|
87
|
+
: 'hash-mismatch';
|
|
88
|
+
updateCandidates.push({ sourceFile, targetFile, rawContent, hash: sourceHash, rel, status: 'updated' });
|
|
89
|
+
fileStatuses.push({ file: rel, status: 'updated', reason: reasonSuffix });
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
updateCandidates.push({ sourceFile, targetFile, rawContent, hash: sourceHash, rel, status: 'added' });
|
|
93
|
+
fileStatuses.push({ file: rel, status: 'added' });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const updatedCount = fileStatuses.filter((f) => f.status === 'updated').length;
|
|
98
|
+
const skippedCount = fileStatuses.filter((f) => f.status === 'skipped').length;
|
|
99
|
+
const addedCount = fileStatuses.filter((f) => f.status === 'added').length;
|
|
100
|
+
// ── Phase 2: If nothing to do, return early ──────────────────────────────────
|
|
101
|
+
if (updateCandidates.length === 0) {
|
|
102
|
+
return {
|
|
103
|
+
success: true,
|
|
104
|
+
updatedCount: 0,
|
|
105
|
+
skippedCount,
|
|
106
|
+
addedCount: 0,
|
|
107
|
+
backupDir: '',
|
|
108
|
+
files: fileStatuses,
|
|
109
|
+
message: `All ${skippedCount} files are up-to-date. No changes needed.`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (dryRun) {
|
|
113
|
+
const summary = [
|
|
114
|
+
updatedCount > 0 ? `${updatedCount} to update` : '',
|
|
115
|
+
addedCount > 0 ? `${addedCount} to add` : '',
|
|
116
|
+
skippedCount > 0 ? `${skippedCount} unchanged` : '',
|
|
117
|
+
]
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.join(', ');
|
|
120
|
+
return {
|
|
121
|
+
success: true,
|
|
122
|
+
updatedCount,
|
|
123
|
+
skippedCount,
|
|
124
|
+
addedCount,
|
|
125
|
+
backupDir: '',
|
|
126
|
+
files: fileStatuses,
|
|
127
|
+
message: `[dry-run] Would apply: ${summary}`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// ── Phase 3: Backup before writing ───────────────────────────────────────────
|
|
131
|
+
const backupResult = backupGithubFiles(targetGithubDir, devstepsDir, {
|
|
132
|
+
maxBackups,
|
|
133
|
+
packageVersion,
|
|
134
|
+
});
|
|
135
|
+
if (!backupResult.success) {
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
updatedCount: 0,
|
|
139
|
+
skippedCount,
|
|
140
|
+
addedCount: 0,
|
|
141
|
+
backupDir: backupResult.backupDir,
|
|
142
|
+
files: fileStatuses,
|
|
143
|
+
message: 'Backup failed — update aborted to prevent partial state.',
|
|
144
|
+
error: backupResult.error?.message ?? 'Unknown backup error',
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// ── Phase 4: Write updated files ─────────────────────────────────────────────
|
|
148
|
+
try {
|
|
149
|
+
for (const candidate of updateCandidates) {
|
|
150
|
+
const annotated = injectDevstepsComment(candidate.rawContent, candidate.hash, packageVersion);
|
|
151
|
+
writeFileSync(candidate.targetFile, annotated, 'utf8');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (writeError) {
|
|
155
|
+
return {
|
|
156
|
+
success: false,
|
|
157
|
+
updatedCount,
|
|
158
|
+
skippedCount,
|
|
159
|
+
addedCount,
|
|
160
|
+
backupDir: backupResult.backupDir,
|
|
161
|
+
files: fileStatuses,
|
|
162
|
+
message: `Write error after backup. Backup preserved at: ${backupResult.backupDir}`,
|
|
163
|
+
error: writeError instanceof Error ? writeError.message : String(writeError),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const summary = [
|
|
167
|
+
updatedCount > 0 ? `${updatedCount} updated` : '',
|
|
168
|
+
addedCount > 0 ? `${addedCount} added` : '',
|
|
169
|
+
skippedCount > 0 ? `${skippedCount} unchanged` : '',
|
|
170
|
+
]
|
|
171
|
+
.filter(Boolean)
|
|
172
|
+
.join(', ');
|
|
173
|
+
return {
|
|
174
|
+
success: true,
|
|
175
|
+
updatedCount,
|
|
176
|
+
skippedCount,
|
|
177
|
+
addedCount,
|
|
178
|
+
backupDir: backupResult.backupDir,
|
|
179
|
+
files: fileStatuses,
|
|
180
|
+
message: `Copilot files updated (${summary}).${backupResult.fileCount > 0 ? ` Backup: ${backupResult.backupDir}` : ''}`,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=update-copilot-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-copilot-files.js","sourceRoot":"","sources":["../../src/utils/update-copilot-files.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schnick371/devsteps-shared",
|
|
3
|
-
"version": "1.1.0-next.
|
|
3
|
+
"version": "1.1.0-next.4",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Never Code Alone. Shared types, schemas, and utilities for DevSteps task tracking.",
|
|
6
6
|
"author": "Thomas Hertel <thomas.hertel@devsteps.dev>",
|