mewkit 1.0.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/init.d.ts +7 -0
  3. package/dist/commands/init.d.ts.map +1 -0
  4. package/dist/commands/init.js +176 -0
  5. package/dist/commands/init.js.map +1 -0
  6. package/dist/commands/upgrade.d.ts +1 -2
  7. package/dist/commands/upgrade.d.ts.map +1 -1
  8. package/dist/commands/upgrade.js +119 -85
  9. package/dist/commands/upgrade.js.map +1 -1
  10. package/dist/core/compute-checksums.d.ts +25 -0
  11. package/dist/core/compute-checksums.d.ts.map +1 -0
  12. package/dist/core/compute-checksums.js +105 -0
  13. package/dist/core/compute-checksums.js.map +1 -0
  14. package/dist/core/core-logger.d.ts +9 -0
  15. package/dist/core/core-logger.d.ts.map +1 -0
  16. package/dist/core/core-logger.js +31 -0
  17. package/dist/core/core-logger.js.map +1 -0
  18. package/dist/core/github-releases.d.ts +30 -0
  19. package/dist/core/github-releases.d.ts.map +1 -0
  20. package/dist/core/github-releases.js +92 -0
  21. package/dist/core/github-releases.js.map +1 -0
  22. package/dist/core/index.d.ts +10 -0
  23. package/dist/core/index.d.ts.map +1 -0
  24. package/dist/core/index.js +10 -0
  25. package/dist/core/index.js.map +1 -0
  26. package/dist/core/merge-settings.d.ts +7 -0
  27. package/dist/core/merge-settings.d.ts.map +1 -0
  28. package/dist/core/merge-settings.js +125 -0
  29. package/dist/core/merge-settings.js.map +1 -0
  30. package/dist/core/smart-update-utils.d.ts +10 -0
  31. package/dist/core/smart-update-utils.d.ts.map +1 -0
  32. package/dist/core/smart-update-utils.js +62 -0
  33. package/dist/core/smart-update-utils.js.map +1 -0
  34. package/dist/core/smart-update.d.ts +18 -0
  35. package/dist/core/smart-update.d.ts.map +1 -0
  36. package/dist/core/smart-update.js +146 -0
  37. package/dist/core/smart-update.js.map +1 -0
  38. package/dist/core/substitute-placeholders.d.ts +10 -0
  39. package/dist/core/substitute-placeholders.d.ts.map +1 -0
  40. package/dist/core/substitute-placeholders.js +28 -0
  41. package/dist/core/substitute-placeholders.js.map +1 -0
  42. package/dist/core/validate-install.d.ts +6 -0
  43. package/dist/core/validate-install.d.ts.map +1 -0
  44. package/dist/core/validate-install.js +97 -0
  45. package/dist/core/validate-install.js.map +1 -0
  46. package/dist/index.js +11 -2
  47. package/dist/index.js.map +1 -1
  48. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-checksums.js","sourceRoot":"","sources":["../../src/core/compute-checksums.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare function setVerbose(v: boolean): void;
2
+ export declare function info(msg: string): void;
3
+ export declare function success(msg: string): void;
4
+ export declare function warn(msg: string): void;
5
+ export declare function error(msg: string): void;
6
+ export declare function debug(msg: string): void;
7
+ /** No-op: structured data is not used in mewkit's console-based output */
8
+ export declare function setData(_key: string, _value: unknown): void;
9
+ //# sourceMappingURL=core-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-logger.d.ts","sourceRoot":"","sources":["../../src/core/core-logger.ts"],"names":[],"mappings":"AAQA,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAE3C;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvC;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAIvC;AAED,0EAA0E;AAC1E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAE3D"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Thin logger shim for core modules ported from create-meowkit.
3
+ * Maps the logger API to console calls — mewkit uses console directly.
4
+ */
5
+ import pc from "picocolors";
6
+ let verbose = false;
7
+ export function setVerbose(v) {
8
+ verbose = v;
9
+ }
10
+ export function info(msg) {
11
+ console.log(msg);
12
+ }
13
+ export function success(msg) {
14
+ console.log(`${pc.green("✓")} ${msg}`);
15
+ }
16
+ export function warn(msg) {
17
+ console.warn(pc.yellow(`⚠ ${msg}`));
18
+ }
19
+ export function error(msg) {
20
+ console.error(pc.red(`✗ ${msg}`));
21
+ }
22
+ export function debug(msg) {
23
+ if (verbose) {
24
+ console.log(pc.dim(`[debug] ${msg}`));
25
+ }
26
+ }
27
+ /** No-op: structured data is not used in mewkit's console-based output */
28
+ export function setData(_key, _value) {
29
+ // No-op in mewkit context
30
+ }
31
+ //# sourceMappingURL=core-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-logger.js","sourceRoot":"","sources":["../../src/core/core-logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,MAAM,UAAU,UAAU,CAAC,CAAU;IACnC,OAAO,GAAG,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,MAAe;IACnD,0BAA0B;AAC5B,CAAC"}
@@ -0,0 +1,30 @@
1
+ export interface ReleaseInfo {
2
+ tag: string;
3
+ version: string;
4
+ isBeta: boolean;
5
+ downloadUrl: string;
6
+ publishedAt: string;
7
+ }
8
+ /**
9
+ * Fetch available releases from GitHub API.
10
+ * Returns stable and beta releases, sorted by newest first.
11
+ */
12
+ export declare function fetchReleases(): Promise<ReleaseInfo[]>;
13
+ /**
14
+ * Get the latest stable release.
15
+ */
16
+ export declare function getLatestStable(): Promise<ReleaseInfo | null>;
17
+ /**
18
+ * Get the latest beta release.
19
+ */
20
+ export declare function getLatestBeta(): Promise<ReleaseInfo | null>;
21
+ /**
22
+ * Download a release zip and extract to a temp directory.
23
+ * Returns the path to the extracted directory.
24
+ */
25
+ export declare function downloadRelease(release: ReleaseInfo): Promise<string>;
26
+ /**
27
+ * Clean up a downloaded release temp directory.
28
+ */
29
+ export declare function cleanupDownload(tempDir: string): void;
30
+ //# sourceMappingURL=github-releases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-releases.d.ts","sourceRoot":"","sources":["../../src/core/github-releases.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CA6B5D;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAGnE;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAGjE;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA+B3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAMrD"}
@@ -0,0 +1,92 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { tmpdir } from "node:os";
4
+ import { execSync } from "node:child_process";
5
+ import * as log from "./core-logger.js";
6
+ /** GitHub repository for MeowKit releases */
7
+ const GITHUB_OWNER = "ngocsangyem";
8
+ const GITHUB_REPO = "MeowKit";
9
+ /**
10
+ * Fetch available releases from GitHub API.
11
+ * Returns stable and beta releases, sorted by newest first.
12
+ */
13
+ export async function fetchReleases() {
14
+ const url = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases`;
15
+ const response = await fetch(url, {
16
+ headers: {
17
+ Accept: "application/vnd.github.v3+json",
18
+ "User-Agent": "create-meowkit",
19
+ },
20
+ });
21
+ if (!response.ok) {
22
+ throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
23
+ }
24
+ const releases = (await response.json());
25
+ return releases
26
+ .filter((r) => !r.draft)
27
+ .map((r) => {
28
+ // Find the release zip asset
29
+ const zipAsset = r.assets.find((a) => a.name.endsWith(".zip"));
30
+ return {
31
+ tag: r.tag_name,
32
+ version: r.tag_name.replace(/^v/, ""),
33
+ isBeta: r.prerelease,
34
+ downloadUrl: zipAsset?.browser_download_url ?? "",
35
+ publishedAt: r.published_at,
36
+ };
37
+ })
38
+ .filter((r) => r.downloadUrl !== "");
39
+ }
40
+ /**
41
+ * Get the latest stable release.
42
+ */
43
+ export async function getLatestStable() {
44
+ const releases = await fetchReleases();
45
+ return releases.find((r) => !r.isBeta) ?? null;
46
+ }
47
+ /**
48
+ * Get the latest beta release.
49
+ */
50
+ export async function getLatestBeta() {
51
+ const releases = await fetchReleases();
52
+ return releases.find((r) => r.isBeta) ?? null;
53
+ }
54
+ /**
55
+ * Download a release zip and extract to a temp directory.
56
+ * Returns the path to the extracted directory.
57
+ */
58
+ export async function downloadRelease(release) {
59
+ const tempDir = join(tmpdir(), `meowkit-release-${release.version}-${Date.now()}`);
60
+ mkdirSync(tempDir, { recursive: true });
61
+ const zipPath = join(tempDir, "release.zip");
62
+ log.debug(`Downloading ${release.downloadUrl}`);
63
+ // Download the zip
64
+ const response = await fetch(release.downloadUrl, {
65
+ headers: { "User-Agent": "create-meowkit" },
66
+ redirect: "follow",
67
+ });
68
+ if (!response.ok) {
69
+ throw new Error(`Download failed: ${response.status} ${response.statusText}`);
70
+ }
71
+ const buffer = Buffer.from(await response.arrayBuffer());
72
+ writeFileSync(zipPath, buffer);
73
+ log.debug(`Downloaded ${buffer.length} bytes to ${zipPath}`);
74
+ // Extract the zip
75
+ const extractDir = join(tempDir, "extracted");
76
+ mkdirSync(extractDir, { recursive: true });
77
+ execSync(`unzip -q "${zipPath}" -d "${extractDir}"`, { stdio: "pipe" });
78
+ log.debug(`Extracted to ${extractDir}`);
79
+ return extractDir;
80
+ }
81
+ /**
82
+ * Clean up a downloaded release temp directory.
83
+ */
84
+ export function cleanupDownload(tempDir) {
85
+ try {
86
+ execSync(`rm -rf "${tempDir}"`, { stdio: "pipe" });
87
+ }
88
+ catch {
89
+ // Best effort cleanup
90
+ }
91
+ }
92
+ //# sourceMappingURL=github-releases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-releases.js","sourceRoot":"","sources":["../../src/core/github-releases.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /** Core modules ported from create-meowkit — shared by init and upgrade commands */
2
+ export * from "./github-releases.js";
3
+ export * from "./compute-checksums.js";
4
+ export * from "./merge-settings.js";
5
+ export * from "./substitute-placeholders.js";
6
+ export * from "./validate-install.js";
7
+ export * from "./smart-update.js";
8
+ export * from "./smart-update-utils.js";
9
+ export * from "./core-logger.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /** Core modules ported from create-meowkit — shared by init and upgrade commands */
2
+ export * from "./github-releases.js";
3
+ export * from "./compute-checksums.js";
4
+ export * from "./merge-settings.js";
5
+ export * from "./substitute-placeholders.js";
6
+ export * from "./validate-install.js";
7
+ export * from "./smart-update.js";
8
+ export * from "./smart-update-utils.js";
9
+ export * from "./core-logger.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Merge template settings.json into existing user settings.json.
3
+ * Strategy: append-only — add new hooks/permissions, never modify existing.
4
+ * Returns true if merge succeeded, false if skipped or failed.
5
+ */
6
+ export declare function mergeSettingsFile(templatePath: string, destPath: string, dryRun: boolean): boolean;
7
+ //# sourceMappingURL=merge-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-settings.d.ts","sourceRoot":"","sources":["../../src/core/merge-settings.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GACd,OAAO,CAsDT"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Append-only merge for .claude/settings.json.
3
+ * Adds new MeowKit hooks/permissions without modifying existing user entries.
4
+ * Backs up before merge, restores on failure.
5
+ */
6
+ import { readFileSync, writeFileSync, copyFileSync, existsSync, mkdirSync } from "node:fs";
7
+ import { dirname } from "node:path";
8
+ import * as log from "./core-logger.js";
9
+ /**
10
+ * Merge template settings.json into existing user settings.json.
11
+ * Strategy: append-only — add new hooks/permissions, never modify existing.
12
+ * Returns true if merge succeeded, false if skipped or failed.
13
+ */
14
+ export function mergeSettingsFile(templatePath, destPath, dryRun) {
15
+ if (!existsSync(templatePath)) {
16
+ log.debug("Template settings.json not found, skipping merge");
17
+ return false;
18
+ }
19
+ // If dest doesn't exist, just copy
20
+ if (!existsSync(destPath)) {
21
+ if (!dryRun) {
22
+ mkdirSync(dirname(destPath), { recursive: true });
23
+ copyFileSync(templatePath, destPath);
24
+ }
25
+ log.debug("settings.json: fresh copy (no existing file)");
26
+ return true;
27
+ }
28
+ if (dryRun) {
29
+ log.debug("settings.json: would merge (dry-run)");
30
+ return true;
31
+ }
32
+ // Read both files
33
+ let userSettings;
34
+ let templateSettings;
35
+ try {
36
+ userSettings = JSON.parse(readFileSync(destPath, "utf-8"));
37
+ }
38
+ catch {
39
+ log.warn("settings.json: invalid JSON in existing file, skipping merge");
40
+ return false;
41
+ }
42
+ try {
43
+ templateSettings = JSON.parse(readFileSync(templatePath, "utf-8"));
44
+ }
45
+ catch {
46
+ log.warn("settings.json: invalid JSON in template, skipping merge");
47
+ return false;
48
+ }
49
+ // Backup before merge
50
+ const backupPath = destPath + ".bak";
51
+ copyFileSync(destPath, backupPath);
52
+ try {
53
+ const merged = appendOnlyMerge(userSettings, templateSettings);
54
+ writeFileSync(destPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
55
+ log.debug("settings.json: merged successfully");
56
+ return true;
57
+ }
58
+ catch (err) {
59
+ // Restore backup on failure
60
+ copyFileSync(backupPath, destPath);
61
+ log.warn(`settings.json merge failed, restored backup: ${err instanceof Error ? err.message : String(err)}`);
62
+ return false;
63
+ }
64
+ }
65
+ /** Append-only merge: add new template entries to user settings without modifying existing */
66
+ function appendOnlyMerge(user, template) {
67
+ const result = { ...user };
68
+ // Merge hooks: add new hook matchers that don't exist in user's config
69
+ if (template.hooks) {
70
+ if (!result.hooks)
71
+ result.hooks = {};
72
+ for (const [event, templateMatchers] of Object.entries(template.hooks)) {
73
+ if (!result.hooks[event]) {
74
+ // Entire hook event is new — add it
75
+ result.hooks[event] = templateMatchers;
76
+ continue;
77
+ }
78
+ // Event exists — add only matchers with commands not already present
79
+ const userMatchers = result.hooks[event];
80
+ const userCommands = extractCommandStrings(userMatchers);
81
+ for (const templateMatcher of templateMatchers) {
82
+ const newHooks = templateMatcher.hooks.filter((h) => !userCommands.has(normalizeCommand(h.command)));
83
+ if (newHooks.length > 0) {
84
+ // Find existing matcher with same matcher pattern, or create new
85
+ const existingMatcher = userMatchers.find((m) => (m.matcher ?? "") === (templateMatcher.matcher ?? ""));
86
+ if (existingMatcher) {
87
+ existingMatcher.hooks.push(...newHooks);
88
+ }
89
+ else {
90
+ userMatchers.push({ ...templateMatcher, hooks: newHooks });
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ // Merge permissions.allow: union of arrays
97
+ if (template.permissions?.allow) {
98
+ if (!result.permissions)
99
+ result.permissions = {};
100
+ if (!result.permissions.allow)
101
+ result.permissions.allow = [];
102
+ const existingSet = new Set(result.permissions.allow);
103
+ for (const perm of template.permissions.allow) {
104
+ if (!existingSet.has(perm)) {
105
+ result.permissions.allow.push(perm);
106
+ }
107
+ }
108
+ }
109
+ return result;
110
+ }
111
+ /** Extract all command strings from hook matchers for deduplication */
112
+ function extractCommandStrings(matchers) {
113
+ const commands = new Set();
114
+ for (const matcher of matchers) {
115
+ for (const hook of matcher.hooks) {
116
+ commands.add(normalizeCommand(hook.command));
117
+ }
118
+ }
119
+ return commands;
120
+ }
121
+ /** Normalize command string for comparison (trim whitespace, collapse spaces) */
122
+ function normalizeCommand(cmd) {
123
+ return cmd.trim().replace(/\s+/g, " ");
124
+ }
125
+ //# sourceMappingURL=merge-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-settings.js","sourceRoot":"","sources":["../../src/core/merge-settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /** Parse .meowkitignore once, return a matcher function */
2
+ export declare function loadIgnorePatterns(targetDir: string): (relPath: string) => boolean;
3
+ /** Recursively collect files from a directory */
4
+ export declare function walkDir(dir: string, base: string): Array<{
5
+ relPath: string;
6
+ srcPath: string;
7
+ }>;
8
+ /** Copy a single file, creating parent dirs. Sets executable for hooks/scripts. */
9
+ export declare function copyFile(src: string, dest: string, dryRun: boolean): void;
10
+ //# sourceMappingURL=smart-update-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-update-utils.d.ts","sourceRoot":"","sources":["../../src/core/smart-update-utils.ts"],"names":[],"mappings":"AASA,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAmBlF;AAED,iDAAiD;AACjD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAoB9F;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAWzE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Helper utilities for smart-update: file copying, .meowkitignore parsing, directory walking.
3
+ */
4
+ import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, copyFileSync, chmodSync, } from "node:fs";
5
+ import { join, relative, dirname, basename } from "node:path";
6
+ /** Parse .meowkitignore once, return a matcher function */
7
+ export function loadIgnorePatterns(targetDir) {
8
+ const ignorePath = join(targetDir, ".meowkitignore");
9
+ if (!existsSync(ignorePath))
10
+ return () => false;
11
+ const patterns = readFileSync(ignorePath, "utf-8")
12
+ .split("\n")
13
+ .map((l) => l.trim())
14
+ .filter((l) => l && !l.startsWith("#"));
15
+ if (patterns.length === 0)
16
+ return () => false;
17
+ return (relPath) => {
18
+ for (const p of patterns) {
19
+ if (relPath === p)
20
+ return true;
21
+ if (p.endsWith("/") && relPath.startsWith(p))
22
+ return true;
23
+ if (relPath.startsWith(p + "/"))
24
+ return true;
25
+ }
26
+ return false;
27
+ };
28
+ }
29
+ /** Recursively collect files from a directory */
30
+ export function walkDir(dir, base) {
31
+ const results = [];
32
+ const SKIP = new Set(["__pycache__", "node_modules", ".DS_Store"]);
33
+ for (const entry of readdirSync(dir)) {
34
+ if (SKIP.has(entry) ||
35
+ entry.endsWith(".pyc") ||
36
+ entry.endsWith("_INDEX.md") ||
37
+ entry === "SKILLS_ATTRIBUTION.md")
38
+ continue;
39
+ const full = join(dir, entry);
40
+ const stat = statSync(full);
41
+ if (stat.isDirectory()) {
42
+ results.push(...walkDir(full, base));
43
+ }
44
+ else {
45
+ results.push({ relPath: relative(base, full), srcPath: full });
46
+ }
47
+ }
48
+ return results;
49
+ }
50
+ /** Copy a single file, creating parent dirs. Sets executable for hooks/scripts. */
51
+ export function copyFile(src, dest, dryRun) {
52
+ if (dryRun)
53
+ return;
54
+ mkdirSync(dirname(dest), { recursive: true });
55
+ copyFileSync(src, dest);
56
+ const parent = dirname(dest).split("/").pop() ?? "";
57
+ const ext = basename(dest).includes(".") ? "." + basename(dest).split(".").pop() : "";
58
+ if (ext === ".sh" || parent === "hooks" || parent === "bin") {
59
+ chmodSync(dest, 0o755);
60
+ }
61
+ }
62
+ //# sourceMappingURL=smart-update-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-update-utils.js","sourceRoot":"","sources":["../../src/core/smart-update-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { UserConfig } from "./substitute-placeholders.js";
2
+ export interface UpdateStats {
3
+ updated: number;
4
+ skipped: number;
5
+ added: number;
6
+ userModified: string[];
7
+ }
8
+ /**
9
+ * Smart update from a downloaded release directory.
10
+ *
11
+ * @param config - User configuration (description, API keys, etc.)
12
+ * @param sourceDir - Path to extracted release (contains .claude/, tasks/, CLAUDE.md)
13
+ * @param targetDir - User's project directory
14
+ * @param dryRun - Preview only, no writes
15
+ * @param force - Overwrite all files, ignore user modifications
16
+ */
17
+ export declare function smartUpdate(config: UserConfig, sourceDir: string, targetDir: string, dryRun: boolean, force?: boolean): Promise<UpdateStats>;
18
+ //# sourceMappingURL=smart-update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-update.d.ts","sourceRoot":"","sources":["../../src/core/smart-update.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAW/D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,KAAK,UAAQ,GACZ,OAAO,CAAC,WAAW,CAAC,CA8JtB"}
@@ -0,0 +1,146 @@
1
+ import { existsSync, writeFileSync, mkdirSync, } from "node:fs";
2
+ import { join } from "node:path";
3
+ import * as log from "./core-logger.js";
4
+ import { processTemplate } from "./substitute-placeholders.js";
5
+ import { mergeSettingsFile } from "./merge-settings.js";
6
+ import { readManifest, buildManifest, writeManifest, hashFile, classifyLayer, } from "./compute-checksums.js";
7
+ import { loadIgnorePatterns, walkDir, copyFile } from "./smart-update-utils.js";
8
+ /**
9
+ * Smart update from a downloaded release directory.
10
+ *
11
+ * @param config - User configuration (description, API keys, etc.)
12
+ * @param sourceDir - Path to extracted release (contains .claude/, tasks/, CLAUDE.md)
13
+ * @param targetDir - User's project directory
14
+ * @param dryRun - Preview only, no writes
15
+ * @param force - Overwrite all files, ignore user modifications
16
+ */
17
+ export async function smartUpdate(config, sourceDir, targetDir, dryRun, force = false) {
18
+ const oldManifest = force ? null : readManifest(join(targetDir, ".claude"));
19
+ const stats = { updated: 0, skipped: 0, added: 0, userModified: [] };
20
+ if (!oldManifest && existsSync(join(targetDir, ".claude"))) {
21
+ log.warn("No manifest found — will treat all existing files as unmodified.");
22
+ }
23
+ const oldChecksums = oldManifest?.checksums ?? {};
24
+ const isIgnored = loadIgnorePatterns(targetDir);
25
+ // Source .claude/ from downloaded release
26
+ const claudeSrc = join(sourceDir, ".claude");
27
+ if (!existsSync(claudeSrc)) {
28
+ log.error(`Release .claude/ not found at: ${claudeSrc}`);
29
+ process.exit(1);
30
+ }
31
+ // Walk .claude/ files from release
32
+ const claudeFiles = walkDir(claudeSrc, claudeSrc)
33
+ .map((f) => ({ ...f, relPath: `.claude/${f.relPath}` }));
34
+ for (const { relPath, srcPath } of claudeFiles) {
35
+ const destPath = join(targetDir, relPath);
36
+ const layer = classifyLayer(relPath);
37
+ if (isIgnored(relPath)) {
38
+ log.debug(`Ignored (protected): ${relPath}`);
39
+ stats.skipped++;
40
+ continue;
41
+ }
42
+ // settings.json uses append-only merge
43
+ if (relPath === ".claude/settings.json") {
44
+ mergeSettingsFile(srcPath, destPath, dryRun);
45
+ stats.updated++;
46
+ continue;
47
+ }
48
+ // User layer: never overwrite
49
+ if (layer === "user") {
50
+ if (existsSync(destPath)) {
51
+ log.debug(`Skipped (user layer): ${relPath}`);
52
+ stats.skipped++;
53
+ }
54
+ else {
55
+ copyFile(srcPath, destPath, dryRun);
56
+ stats.added++;
57
+ }
58
+ continue;
59
+ }
60
+ // New file → always add
61
+ if (!existsSync(destPath)) {
62
+ copyFile(srcPath, destPath, dryRun);
63
+ log.debug(`Added (new): ${relPath}`);
64
+ stats.added++;
65
+ continue;
66
+ }
67
+ // File exists — check if user modified it
68
+ const currentHash = hashFile(destPath);
69
+ const manifestEntry = oldChecksums[relPath];
70
+ if (manifestEntry && currentHash !== manifestEntry.sha256) {
71
+ log.debug(`Skipped (user-modified): ${relPath}`);
72
+ stats.userModified.push(relPath);
73
+ stats.skipped++;
74
+ continue;
75
+ }
76
+ // Safe to overwrite
77
+ copyFile(srcPath, destPath, dryRun);
78
+ stats.updated++;
79
+ }
80
+ // Copy tasks/ from release
81
+ const tasksSrc = join(sourceDir, "tasks");
82
+ if (existsSync(tasksSrc)) {
83
+ const taskFiles = walkDir(tasksSrc, tasksSrc)
84
+ .map((f) => ({ ...f, relPath: `tasks/${f.relPath}` }));
85
+ for (const { relPath, srcPath: tSrc } of taskFiles) {
86
+ const tDest = join(targetDir, relPath);
87
+ if (!existsSync(tDest)) {
88
+ copyFile(tSrc, tDest, dryRun);
89
+ stats.added++;
90
+ }
91
+ }
92
+ if (!dryRun) {
93
+ for (const dir of ["tasks/active", "tasks/completed", "tasks/backlog", "tasks/guidelines"]) {
94
+ mkdirSync(join(targetDir, dir), { recursive: true });
95
+ }
96
+ }
97
+ }
98
+ const claudeDir = join(targetDir, ".claude");
99
+ // CLAUDE.md at project root
100
+ const claudeMdSrc = join(sourceDir, "CLAUDE.md");
101
+ const claudeMdDest = join(targetDir, "CLAUDE.md");
102
+ if (existsSync(claudeMdSrc) && !existsSync(claudeMdDest)) {
103
+ processTemplate(claudeMdSrc, claudeMdDest, config, dryRun);
104
+ stats.added++;
105
+ }
106
+ // meowkit.config.json template (generated, not from release)
107
+ const configDest = join(claudeDir, "meowkit.config.json");
108
+ if (!existsSync(configDest)) {
109
+ if (!dryRun) {
110
+ mkdirSync(claudeDir, { recursive: true });
111
+ const configContent = JSON.stringify({
112
+ $schema: "https://meowkit.dev/schema/config.json",
113
+ version: "1.0.0",
114
+ project: { description: config.description || "" },
115
+ features: { costTracking: config.enableCostTracking, memory: config.enableMemory },
116
+ }, null, 2);
117
+ writeFileSync(configDest, configContent + "\n", "utf-8");
118
+ }
119
+ stats.added++;
120
+ }
121
+ // Write .env if Gemini API key provided
122
+ if (config.geminiApiKey && !existsSync(join(claudeDir, ".env"))) {
123
+ if (!dryRun) {
124
+ writeFileSync(join(claudeDir, ".env"), `# MeowKit environment variables\nGEMINI_API_KEY=${config.geminiApiKey}\n`, "utf-8");
125
+ }
126
+ stats.added++;
127
+ }
128
+ // Ensure memory + logs dirs exist
129
+ if (!dryRun) {
130
+ mkdirSync(join(targetDir, ".claude", "memory"), { recursive: true });
131
+ mkdirSync(join(targetDir, ".claude", "logs"), { recursive: true });
132
+ }
133
+ // Write manifest
134
+ if (!dryRun) {
135
+ const newManifest = buildManifest(claudeDir);
136
+ writeManifest(claudeDir, newManifest);
137
+ }
138
+ log.setData("update", {
139
+ updated: stats.updated,
140
+ skipped: stats.skipped,
141
+ added: stats.added,
142
+ userModified: stats.userModified,
143
+ });
144
+ return stats;
145
+ }
146
+ //# sourceMappingURL=smart-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-update.js","sourceRoot":"","sources":["../../src/core/smart-update.ts"],"names":[],"mappings":"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"}