@chiendt/ack-cli 1.3.0-dev.5 → 1.3.0-dev.6
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/cli-manifest.json +2 -2
- package/dist/index.js +321 -263
- package/package.json +1 -1
package/cli-manifest.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -63756,7 +63756,7 @@ var package_default;
|
|
|
63756
63756
|
var init_package = __esm(() => {
|
|
63757
63757
|
package_default = {
|
|
63758
63758
|
name: "@chiendt/ack-cli",
|
|
63759
|
-
version: "1.3.0-dev.
|
|
63759
|
+
version: "1.3.0-dev.6",
|
|
63760
63760
|
description: "ACK CLI - tool for bootstrapping and updating ACK kits (Claude Code agent kits)",
|
|
63761
63761
|
type: "module",
|
|
63762
63762
|
repository: {
|
|
@@ -72527,6 +72527,221 @@ var init_github_api_checker = __esm(() => {
|
|
|
72527
72527
|
init_types3();
|
|
72528
72528
|
});
|
|
72529
72529
|
|
|
72530
|
+
// src/domains/installation/npmrc-bootstrap.ts
|
|
72531
|
+
import { promises as fs10 } from "node:fs";
|
|
72532
|
+
import { dirname as dirname29 } from "node:path";
|
|
72533
|
+
function mergeNpmrcEntries(existing, entries) {
|
|
72534
|
+
const keys = new Set(Object.keys(entries));
|
|
72535
|
+
const seenKeys = new Set;
|
|
72536
|
+
const lines = existing.split(`
|
|
72537
|
+
`);
|
|
72538
|
+
const out = [];
|
|
72539
|
+
for (const line of lines) {
|
|
72540
|
+
const stripped = line.trim();
|
|
72541
|
+
if (stripped === "" || stripped.startsWith(";") || stripped.startsWith("#")) {
|
|
72542
|
+
out.push(line);
|
|
72543
|
+
continue;
|
|
72544
|
+
}
|
|
72545
|
+
const eq = line.indexOf("=");
|
|
72546
|
+
if (eq < 0) {
|
|
72547
|
+
out.push(line);
|
|
72548
|
+
continue;
|
|
72549
|
+
}
|
|
72550
|
+
const key = line.slice(0, eq).trim();
|
|
72551
|
+
if (keys.has(key)) {
|
|
72552
|
+
seenKeys.add(key);
|
|
72553
|
+
out.push(`${key}=${entries[key]}`);
|
|
72554
|
+
} else {
|
|
72555
|
+
out.push(line);
|
|
72556
|
+
}
|
|
72557
|
+
}
|
|
72558
|
+
const additions = [];
|
|
72559
|
+
for (const key of keys) {
|
|
72560
|
+
if (!seenKeys.has(key)) {
|
|
72561
|
+
additions.push(`${key}=${entries[key]}`);
|
|
72562
|
+
}
|
|
72563
|
+
}
|
|
72564
|
+
let result = out.join(`
|
|
72565
|
+
`);
|
|
72566
|
+
if (additions.length > 0) {
|
|
72567
|
+
if (result.length > 0 && !result.endsWith(`
|
|
72568
|
+
`))
|
|
72569
|
+
result += `
|
|
72570
|
+
`;
|
|
72571
|
+
result += `${additions.join(`
|
|
72572
|
+
`)}
|
|
72573
|
+
`;
|
|
72574
|
+
} else if (result.length > 0 && !result.endsWith(`
|
|
72575
|
+
`)) {
|
|
72576
|
+
result += `
|
|
72577
|
+
`;
|
|
72578
|
+
}
|
|
72579
|
+
return result;
|
|
72580
|
+
}
|
|
72581
|
+
async function writeNpmrc(path8, entries, opts = {}) {
|
|
72582
|
+
let existing = "";
|
|
72583
|
+
let hadFile = false;
|
|
72584
|
+
try {
|
|
72585
|
+
existing = await fs10.readFile(path8, "utf8");
|
|
72586
|
+
hadFile = true;
|
|
72587
|
+
} catch (err) {
|
|
72588
|
+
if (err.code !== "ENOENT")
|
|
72589
|
+
throw err;
|
|
72590
|
+
}
|
|
72591
|
+
const merged = mergeNpmrcEntries(existing, entries);
|
|
72592
|
+
if (merged === existing) {
|
|
72593
|
+
return { written: false, backupPath: null, finalPath: path8, noChange: true };
|
|
72594
|
+
}
|
|
72595
|
+
let backupPath = null;
|
|
72596
|
+
if (hadFile) {
|
|
72597
|
+
const now = opts.now?.() ?? new Date;
|
|
72598
|
+
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
72599
|
+
backupPath = `${path8}.bak.${stamp}`;
|
|
72600
|
+
await fs10.copyFile(path8, backupPath);
|
|
72601
|
+
}
|
|
72602
|
+
await fs10.mkdir(dirname29(path8), { recursive: true });
|
|
72603
|
+
const tmp = `${path8}.tmp.${process.pid}`;
|
|
72604
|
+
await fs10.writeFile(tmp, merged, { mode: 384 });
|
|
72605
|
+
await fs10.rename(tmp, path8);
|
|
72606
|
+
try {
|
|
72607
|
+
await fs10.chmod(path8, 384);
|
|
72608
|
+
} catch {}
|
|
72609
|
+
return { written: true, backupPath, finalPath: path8, noChange: false };
|
|
72610
|
+
}
|
|
72611
|
+
function buildGitHubPackagesEntries(pat) {
|
|
72612
|
+
const trimmed = pat.trim();
|
|
72613
|
+
return {
|
|
72614
|
+
[SCOPE_REGISTRY_KEY]: GITHUB_PACKAGES_REGISTRY_URL,
|
|
72615
|
+
[AUTH_TOKEN_KEY]: trimmed
|
|
72616
|
+
};
|
|
72617
|
+
}
|
|
72618
|
+
function isValidGitHubPat(value) {
|
|
72619
|
+
const v2 = value.trim();
|
|
72620
|
+
if (v2.length < 8)
|
|
72621
|
+
return false;
|
|
72622
|
+
if (/\s/.test(v2))
|
|
72623
|
+
return false;
|
|
72624
|
+
return /^(ghp_|github_pat_|ghs_|gho_|ghu_|ghr_)/.test(v2);
|
|
72625
|
+
}
|
|
72626
|
+
var GITHUB_PACKAGES_REGISTRY_URL = "https://npm.pkg.github.com", GITHUB_PACKAGES_SCOPE = "@chiendt1108", SCOPE_REGISTRY_KEY, AUTH_TOKEN_KEY = "//npm.pkg.github.com/:_authToken";
|
|
72627
|
+
var init_npmrc_bootstrap = __esm(() => {
|
|
72628
|
+
SCOPE_REGISTRY_KEY = `${GITHUB_PACKAGES_SCOPE}:registry`;
|
|
72629
|
+
});
|
|
72630
|
+
|
|
72631
|
+
// src/commands/fqc-qa/npmrc-setup-step.ts
|
|
72632
|
+
var exports_npmrc_setup_step = {};
|
|
72633
|
+
__export(exports_npmrc_setup_step, {
|
|
72634
|
+
runNpmrcSetupStep: () => runNpmrcSetupStep
|
|
72635
|
+
});
|
|
72636
|
+
import { existsSync as existsSync66, readFileSync as readFileSync20 } from "node:fs";
|
|
72637
|
+
import { homedir as homedir45 } from "node:os";
|
|
72638
|
+
import { join as join96 } from "node:path";
|
|
72639
|
+
function resolveTokenFromEnv() {
|
|
72640
|
+
const fromProcess = process.env[TOKEN_ENV_KEY];
|
|
72641
|
+
if (fromProcess && fromProcess.length > 0) {
|
|
72642
|
+
return { token: fromProcess, source: "env" };
|
|
72643
|
+
}
|
|
72644
|
+
const dotenvPath = join96(process.cwd(), ".env");
|
|
72645
|
+
if (!existsSync66(dotenvPath))
|
|
72646
|
+
return null;
|
|
72647
|
+
let contents;
|
|
72648
|
+
try {
|
|
72649
|
+
contents = readFileSync20(dotenvPath, "utf8");
|
|
72650
|
+
} catch {
|
|
72651
|
+
return null;
|
|
72652
|
+
}
|
|
72653
|
+
for (const rawLine of contents.split(`
|
|
72654
|
+
`)) {
|
|
72655
|
+
const line = rawLine.trim();
|
|
72656
|
+
if (line.length === 0 || line.startsWith("#"))
|
|
72657
|
+
continue;
|
|
72658
|
+
const eq = line.indexOf("=");
|
|
72659
|
+
if (eq < 0)
|
|
72660
|
+
continue;
|
|
72661
|
+
const key = line.slice(0, eq).trim();
|
|
72662
|
+
if (key !== TOKEN_ENV_KEY)
|
|
72663
|
+
continue;
|
|
72664
|
+
let value = line.slice(eq + 1).trim();
|
|
72665
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
72666
|
+
value = value.slice(1, -1);
|
|
72667
|
+
}
|
|
72668
|
+
if (value.length === 0)
|
|
72669
|
+
return null;
|
|
72670
|
+
return { token: value, source: "dotenv" };
|
|
72671
|
+
}
|
|
72672
|
+
return null;
|
|
72673
|
+
}
|
|
72674
|
+
async function writeNpmrcWithToken(pat, source) {
|
|
72675
|
+
const npmrcPath = join96(homedir45(), ".npmrc");
|
|
72676
|
+
try {
|
|
72677
|
+
const result = await writeNpmrc(npmrcPath, buildGitHubPackagesEntries(pat));
|
|
72678
|
+
if (result.noChange) {
|
|
72679
|
+
logger.info(import_picocolors19.default.dim("~/.npmrc already up to date"));
|
|
72680
|
+
return { status: "no-change", source };
|
|
72681
|
+
}
|
|
72682
|
+
logger.info(import_picocolors19.default.green(`Wrote GitHub Packages config → ${npmrcPath}`));
|
|
72683
|
+
if (result.backupPath)
|
|
72684
|
+
logger.info(import_picocolors19.default.dim(` backup: ${result.backupPath}`));
|
|
72685
|
+
return { status: "written", backupPath: result.backupPath, source };
|
|
72686
|
+
} catch (err) {
|
|
72687
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
72688
|
+
logger.error(`Failed to write ~/.npmrc: ${msg}`);
|
|
72689
|
+
return { status: "error", error: msg, source };
|
|
72690
|
+
}
|
|
72691
|
+
}
|
|
72692
|
+
async function runNpmrcSetupStep(opts = {}) {
|
|
72693
|
+
if (process.env.FQC_QA_SKIP_NPMRC === "1") {
|
|
72694
|
+
logger.info(import_picocolors19.default.dim("Skipping ~/.npmrc bootstrap (FQC_QA_SKIP_NPMRC=1)"));
|
|
72695
|
+
return { status: "skipped-env" };
|
|
72696
|
+
}
|
|
72697
|
+
const fromEnv = resolveTokenFromEnv();
|
|
72698
|
+
if (fromEnv) {
|
|
72699
|
+
if (!isValidGitHubPat(fromEnv.token)) {
|
|
72700
|
+
logger.info(import_picocolors19.default.yellow(`${TOKEN_ENV_KEY} (from ${fromEnv.source === "env" ? "process.env" : ".env"}) is not a valid GitHub PAT — falling back to interactive prompt.`));
|
|
72701
|
+
} else {
|
|
72702
|
+
logger.info(import_picocolors19.default.dim(`Using ${TOKEN_ENV_KEY} from ${fromEnv.source === "env" ? "process.env" : "<cwd>/.env"} — skipping prompt.`));
|
|
72703
|
+
return writeNpmrcWithToken(fromEnv.token, fromEnv.source);
|
|
72704
|
+
}
|
|
72705
|
+
}
|
|
72706
|
+
console.log("");
|
|
72707
|
+
le([
|
|
72708
|
+
"To resolve @chiendt1108/fqc-mcp-servers from GitHub Packages, ~/.npmrc",
|
|
72709
|
+
"needs a scope mapping and a GitHub PAT with the `read:packages` scope.",
|
|
72710
|
+
"Create one at: https://github.com/settings/tokens (classic) or",
|
|
72711
|
+
"https://github.com/settings/personal-access-tokens/new (fine-grained).",
|
|
72712
|
+
"",
|
|
72713
|
+
"Press Enter / Esc to skip — rerun later with `ack fqc-qa-setup --npmrc-only`."
|
|
72714
|
+
].join(`
|
|
72715
|
+
`), "GitHub Packages auth");
|
|
72716
|
+
if (opts.yes) {
|
|
72717
|
+
logger.info(import_picocolors19.default.yellow("--yes given — skipping interactive PAT prompt."));
|
|
72718
|
+
return { status: "skipped-cancel" };
|
|
72719
|
+
}
|
|
72720
|
+
const pat = await re({
|
|
72721
|
+
message: "GitHub Personal Access Token (read:packages):",
|
|
72722
|
+
validate: (value) => {
|
|
72723
|
+
if (!value)
|
|
72724
|
+
return;
|
|
72725
|
+
if (!isValidGitHubPat(value)) {
|
|
72726
|
+
return "Token must start with ghp_, github_pat_, ghs_, gho_, ghu_, or ghr_.";
|
|
72727
|
+
}
|
|
72728
|
+
return;
|
|
72729
|
+
}
|
|
72730
|
+
});
|
|
72731
|
+
if (lD(pat) || !pat) {
|
|
72732
|
+
logger.info(import_picocolors19.default.yellow("Skipped PAT entry. Rerun with `ack fqc-qa-setup --npmrc-only` when ready."));
|
|
72733
|
+
return { status: "skipped-cancel" };
|
|
72734
|
+
}
|
|
72735
|
+
return writeNpmrcWithToken(pat, "prompt");
|
|
72736
|
+
}
|
|
72737
|
+
var import_picocolors19, TOKEN_ENV_KEY = "FQC_GITHUB_PACKAGES_TOKEN";
|
|
72738
|
+
var init_npmrc_setup_step = __esm(() => {
|
|
72739
|
+
init_npmrc_bootstrap();
|
|
72740
|
+
init_logger();
|
|
72741
|
+
init_dist2();
|
|
72742
|
+
import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
72743
|
+
});
|
|
72744
|
+
|
|
72530
72745
|
// node_modules/picomatch/lib/constants.js
|
|
72531
72746
|
var require_constants3 = __commonJS((exports, module) => {
|
|
72532
72747
|
var WIN_SLASH = "\\\\/";
|
|
@@ -74482,7 +74697,7 @@ var init_opencode_installer = __esm(() => {
|
|
|
74482
74697
|
var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
|
|
74483
74698
|
|
|
74484
74699
|
// src/services/package-installer/install-error-handler.ts
|
|
74485
|
-
import { existsSync as
|
|
74700
|
+
import { existsSync as existsSync67, readFileSync as readFileSync21, unlinkSync as unlinkSync4 } from "node:fs";
|
|
74486
74701
|
import { join as join100 } from "node:path";
|
|
74487
74702
|
function parseNameReason(str2) {
|
|
74488
74703
|
const colonIndex = str2.indexOf(":");
|
|
@@ -74547,13 +74762,13 @@ function getSystemPackageCommands(summary, systemFailures) {
|
|
|
74547
74762
|
}
|
|
74548
74763
|
function displayInstallErrors(skillsDir) {
|
|
74549
74764
|
const summaryPath = join100(skillsDir, ".install-error-summary.json");
|
|
74550
|
-
if (!
|
|
74765
|
+
if (!existsSync67(summaryPath)) {
|
|
74551
74766
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
74552
74767
|
return;
|
|
74553
74768
|
}
|
|
74554
74769
|
let summary;
|
|
74555
74770
|
try {
|
|
74556
|
-
summary = JSON.parse(
|
|
74771
|
+
summary = JSON.parse(readFileSync21(summaryPath, "utf-8"));
|
|
74557
74772
|
} catch (parseError) {
|
|
74558
74773
|
logger.error("Failed to parse error summary. File may be corrupted.");
|
|
74559
74774
|
logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
@@ -74646,7 +74861,7 @@ async function checkNeedsSudoPackages() {
|
|
|
74646
74861
|
}
|
|
74647
74862
|
function hasInstallState(skillsDir) {
|
|
74648
74863
|
const stateFilePath = join100(skillsDir, ".install-state.json");
|
|
74649
|
-
return
|
|
74864
|
+
return existsSync67(stateFilePath);
|
|
74650
74865
|
}
|
|
74651
74866
|
var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS, WINDOWS_RSVG_COMMANDS;
|
|
74652
74867
|
var init_install_error_handler = __esm(() => {
|
|
@@ -74685,7 +74900,7 @@ async function installSkillsDependencies(skillsDir, options2 = {}) {
|
|
|
74685
74900
|
};
|
|
74686
74901
|
}
|
|
74687
74902
|
try {
|
|
74688
|
-
const { existsSync:
|
|
74903
|
+
const { existsSync: existsSync68 } = await import("node:fs");
|
|
74689
74904
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
74690
74905
|
const platform9 = process.platform;
|
|
74691
74906
|
const scriptName = platform9 === "win32" ? "install.ps1" : "install.sh";
|
|
@@ -74701,7 +74916,7 @@ async function installSkillsDependencies(skillsDir, options2 = {}) {
|
|
|
74701
74916
|
error: `Path validation failed: ${errorMessage}`
|
|
74702
74917
|
};
|
|
74703
74918
|
}
|
|
74704
|
-
if (!
|
|
74919
|
+
if (!existsSync68(scriptPath)) {
|
|
74705
74920
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
74706
74921
|
logger.info("");
|
|
74707
74922
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
@@ -74917,7 +75132,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
74917
75132
|
});
|
|
74918
75133
|
|
|
74919
75134
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
74920
|
-
import { existsSync as
|
|
75135
|
+
import { existsSync as existsSync68 } from "node:fs";
|
|
74921
75136
|
import { mkdir as mkdir24, readFile as readFile50, writeFile as writeFile25 } from "node:fs/promises";
|
|
74922
75137
|
import { dirname as dirname33, join as join102 } from "node:path";
|
|
74923
75138
|
async function readJsonFile(filePath) {
|
|
@@ -74935,7 +75150,7 @@ async function addGeminiToGitignore(projectDir) {
|
|
|
74935
75150
|
const geminiPattern = ".gemini/";
|
|
74936
75151
|
try {
|
|
74937
75152
|
let content = "";
|
|
74938
|
-
if (
|
|
75153
|
+
if (existsSync68(gitignorePath)) {
|
|
74939
75154
|
content = await readFile50(gitignorePath, "utf-8");
|
|
74940
75155
|
const lines = content.split(`
|
|
74941
75156
|
`).map((line) => line.trim()).filter((line) => !line.startsWith("#"));
|
|
@@ -74960,7 +75175,7 @@ ${geminiPattern}
|
|
|
74960
75175
|
}
|
|
74961
75176
|
async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
74962
75177
|
const linkDir = dirname33(geminiSettingsPath);
|
|
74963
|
-
if (!
|
|
75178
|
+
if (!existsSync68(linkDir)) {
|
|
74964
75179
|
await mkdir24(linkDir, { recursive: true });
|
|
74965
75180
|
logger.debug(`Created directory: ${linkDir}`);
|
|
74966
75181
|
}
|
|
@@ -75021,7 +75236,7 @@ var init_config_manager2 = __esm(() => {
|
|
|
75021
75236
|
});
|
|
75022
75237
|
|
|
75023
75238
|
// src/services/package-installer/gemini-mcp/validation.ts
|
|
75024
|
-
import { existsSync as
|
|
75239
|
+
import { existsSync as existsSync69, lstatSync, readlinkSync } from "node:fs";
|
|
75025
75240
|
import { homedir as homedir46 } from "node:os";
|
|
75026
75241
|
import { join as join103 } from "node:path";
|
|
75027
75242
|
function getGlobalMcpConfigPath() {
|
|
@@ -75032,12 +75247,12 @@ function getLocalMcpConfigPath(projectDir) {
|
|
|
75032
75247
|
}
|
|
75033
75248
|
function findMcpConfigPath(projectDir) {
|
|
75034
75249
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
75035
|
-
if (
|
|
75250
|
+
if (existsSync69(localPath)) {
|
|
75036
75251
|
logger.debug(`Found local MCP config: ${localPath}`);
|
|
75037
75252
|
return localPath;
|
|
75038
75253
|
}
|
|
75039
75254
|
const globalPath = getGlobalMcpConfigPath();
|
|
75040
|
-
if (
|
|
75255
|
+
if (existsSync69(globalPath)) {
|
|
75041
75256
|
logger.debug(`Found global MCP config: ${globalPath}`);
|
|
75042
75257
|
return globalPath;
|
|
75043
75258
|
}
|
|
@@ -75052,7 +75267,7 @@ function getGeminiSettingsPath(projectDir, isGlobal) {
|
|
|
75052
75267
|
}
|
|
75053
75268
|
function checkExistingGeminiConfig(projectDir, isGlobal = false) {
|
|
75054
75269
|
const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
|
|
75055
|
-
if (!
|
|
75270
|
+
if (!existsSync69(geminiSettingsPath)) {
|
|
75056
75271
|
return { exists: false, isSymlink: false, settingsPath: geminiSettingsPath };
|
|
75057
75272
|
}
|
|
75058
75273
|
try {
|
|
@@ -75076,12 +75291,12 @@ var init_validation = __esm(() => {
|
|
|
75076
75291
|
});
|
|
75077
75292
|
|
|
75078
75293
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
75079
|
-
import { existsSync as
|
|
75294
|
+
import { existsSync as existsSync70 } from "node:fs";
|
|
75080
75295
|
import { mkdir as mkdir25, symlink as symlink3 } from "node:fs/promises";
|
|
75081
75296
|
import { dirname as dirname34, join as join104 } from "node:path";
|
|
75082
75297
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
75083
75298
|
const linkDir = dirname34(linkPath);
|
|
75084
|
-
if (!
|
|
75299
|
+
if (!existsSync70(linkDir)) {
|
|
75085
75300
|
await mkdir25(linkDir, { recursive: true });
|
|
75086
75301
|
logger.debug(`Created directory: ${linkDir}`);
|
|
75087
75302
|
}
|
|
@@ -77504,7 +77719,7 @@ __export(exports_worktree_manager, {
|
|
|
77504
77719
|
createWorktree: () => createWorktree,
|
|
77505
77720
|
cleanupAllWorktrees: () => cleanupAllWorktrees
|
|
77506
77721
|
});
|
|
77507
|
-
import { existsSync as
|
|
77722
|
+
import { existsSync as existsSync79 } from "node:fs";
|
|
77508
77723
|
import { readFile as readFile70, writeFile as writeFile40 } from "node:fs/promises";
|
|
77509
77724
|
import { join as join162 } from "node:path";
|
|
77510
77725
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
@@ -77570,7 +77785,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
77570
77785
|
async function ensureGitignore(projectDir) {
|
|
77571
77786
|
const gitignorePath = join162(projectDir, ".gitignore");
|
|
77572
77787
|
try {
|
|
77573
|
-
const content =
|
|
77788
|
+
const content = existsSync79(gitignorePath) ? await readFile70(gitignorePath, "utf-8") : "";
|
|
77574
77789
|
if (!content.includes(".worktrees")) {
|
|
77575
77790
|
const newContent = content.endsWith(`
|
|
77576
77791
|
`) ? `${content}.worktrees/
|
|
@@ -77672,16 +77887,16 @@ var init_content_validator = __esm(() => {
|
|
|
77672
77887
|
|
|
77673
77888
|
// src/commands/content/phases/context-cache-manager.ts
|
|
77674
77889
|
import { createHash as createHash10 } from "node:crypto";
|
|
77675
|
-
import { existsSync as
|
|
77890
|
+
import { existsSync as existsSync85, mkdirSync as mkdirSync5, readFileSync as readFileSync22, readdirSync as readdirSync12, statSync as statSync15 } from "node:fs";
|
|
77676
77891
|
import { rename as rename17, writeFile as writeFile42 } from "node:fs/promises";
|
|
77677
77892
|
import { homedir as homedir56 } from "node:os";
|
|
77678
77893
|
import { basename as basename34, join as join169 } from "node:path";
|
|
77679
77894
|
function getCachedContext(repoPath) {
|
|
77680
77895
|
const cachePath = getCacheFilePath(repoPath);
|
|
77681
|
-
if (!
|
|
77896
|
+
if (!existsSync85(cachePath))
|
|
77682
77897
|
return null;
|
|
77683
77898
|
try {
|
|
77684
|
-
const raw =
|
|
77899
|
+
const raw = readFileSync22(cachePath, "utf-8");
|
|
77685
77900
|
const cache4 = JSON.parse(raw);
|
|
77686
77901
|
const age = Date.now() - new Date(cache4.createdAt).getTime();
|
|
77687
77902
|
if (age >= CACHE_TTL_MS5)
|
|
@@ -77695,7 +77910,7 @@ function getCachedContext(repoPath) {
|
|
|
77695
77910
|
}
|
|
77696
77911
|
}
|
|
77697
77912
|
async function saveCachedContext(repoPath, cache4) {
|
|
77698
|
-
if (!
|
|
77913
|
+
if (!existsSync85(CACHE_DIR)) {
|
|
77699
77914
|
mkdirSync5(CACHE_DIR, { recursive: true });
|
|
77700
77915
|
}
|
|
77701
77916
|
const cachePath = getCacheFilePath(repoPath);
|
|
@@ -77719,7 +77934,7 @@ function computeSourceHash(repoPath) {
|
|
|
77719
77934
|
function getDocSourcePaths(repoPath) {
|
|
77720
77935
|
const paths = [];
|
|
77721
77936
|
const docsDir = join169(repoPath, "docs");
|
|
77722
|
-
if (
|
|
77937
|
+
if (existsSync85(docsDir)) {
|
|
77723
77938
|
try {
|
|
77724
77939
|
const files = readdirSync12(docsDir);
|
|
77725
77940
|
for (const f4 of files) {
|
|
@@ -77729,10 +77944,10 @@ function getDocSourcePaths(repoPath) {
|
|
|
77729
77944
|
} catch {}
|
|
77730
77945
|
}
|
|
77731
77946
|
const readme = join169(repoPath, "README.md");
|
|
77732
|
-
if (
|
|
77947
|
+
if (existsSync85(readme))
|
|
77733
77948
|
paths.push(readme);
|
|
77734
77949
|
const stylesDir = join169(repoPath, "assets", "writing-styles");
|
|
77735
|
-
if (
|
|
77950
|
+
if (existsSync85(stylesDir)) {
|
|
77736
77951
|
try {
|
|
77737
77952
|
const files = readdirSync12(stylesDir);
|
|
77738
77953
|
for (const f4 of files) {
|
|
@@ -77929,7 +78144,7 @@ function extractContentFromResponse(response) {
|
|
|
77929
78144
|
|
|
77930
78145
|
// src/commands/content/phases/docs-summarizer.ts
|
|
77931
78146
|
import { execSync as execSync6 } from "node:child_process";
|
|
77932
|
-
import { existsSync as
|
|
78147
|
+
import { existsSync as existsSync86, readFileSync as readFileSync23, readdirSync as readdirSync13 } from "node:fs";
|
|
77933
78148
|
import { join as join170 } from "node:path";
|
|
77934
78149
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
77935
78150
|
const rawContent = collectRawDocs(repoPath);
|
|
@@ -77974,18 +78189,18 @@ async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
|
77974
78189
|
function collectRawDocs(repoPath) {
|
|
77975
78190
|
let totalChars = 0;
|
|
77976
78191
|
const readCapped = (filePath, maxChars) => {
|
|
77977
|
-
if (!
|
|
78192
|
+
if (!existsSync86(filePath))
|
|
77978
78193
|
return "";
|
|
77979
78194
|
if (totalChars >= MAX_RAW_CONTENT_CHARS)
|
|
77980
78195
|
return "";
|
|
77981
|
-
const content =
|
|
78196
|
+
const content = readFileSync23(filePath, "utf-8");
|
|
77982
78197
|
const capped = content.slice(0, Math.min(maxChars, MAX_RAW_CONTENT_CHARS - totalChars));
|
|
77983
78198
|
totalChars += capped.length;
|
|
77984
78199
|
return capped;
|
|
77985
78200
|
};
|
|
77986
78201
|
const docsContent = [];
|
|
77987
78202
|
const docsDir = join170(repoPath, "docs");
|
|
77988
|
-
if (
|
|
78203
|
+
if (existsSync86(docsDir)) {
|
|
77989
78204
|
try {
|
|
77990
78205
|
const files = readdirSync13(docsDir).filter((f4) => f4.endsWith(".md")).sort();
|
|
77991
78206
|
for (const f4 of files) {
|
|
@@ -78009,7 +78224,7 @@ ${content}`);
|
|
|
78009
78224
|
}
|
|
78010
78225
|
let styles3 = "";
|
|
78011
78226
|
const stylesDir = join170(repoPath, "assets", "writing-styles");
|
|
78012
|
-
if (
|
|
78227
|
+
if (existsSync86(stylesDir)) {
|
|
78013
78228
|
try {
|
|
78014
78229
|
const files = readdirSync13(stylesDir).slice(0, 3);
|
|
78015
78230
|
styles3 = files.map((f4) => readCapped(join170(stylesDir, f4), 1000)).filter(Boolean).join(`
|
|
@@ -78202,12 +78417,12 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
78202
78417
|
|
|
78203
78418
|
// src/commands/content/phases/photo-generator.ts
|
|
78204
78419
|
import { execSync as execSync7 } from "node:child_process";
|
|
78205
|
-
import { existsSync as
|
|
78420
|
+
import { existsSync as existsSync87, mkdirSync as mkdirSync6, readdirSync as readdirSync14 } from "node:fs";
|
|
78206
78421
|
import { homedir as homedir57 } from "node:os";
|
|
78207
78422
|
import { join as join171 } from "node:path";
|
|
78208
78423
|
async function generatePhoto(_content, context, config, platform14, contentId, contentLogger) {
|
|
78209
78424
|
const mediaDir = join171(config.contentDir.replace(/^~/, homedir57()), "media", String(contentId));
|
|
78210
|
-
if (!
|
|
78425
|
+
if (!existsSync87(mediaDir)) {
|
|
78211
78426
|
mkdirSync6(mediaDir, { recursive: true });
|
|
78212
78427
|
}
|
|
78213
78428
|
const prompt = buildPhotoPrompt(context, platform14);
|
|
@@ -78223,7 +78438,7 @@ async function generatePhoto(_content, context, config, platform14, contentId, c
|
|
|
78223
78438
|
const parsed = parseClaudeJsonOutput(result);
|
|
78224
78439
|
if (parsed && typeof parsed === "object" && "imagePath" in parsed) {
|
|
78225
78440
|
const imagePath = String(parsed.imagePath);
|
|
78226
|
-
if (
|
|
78441
|
+
if (existsSync87(imagePath)) {
|
|
78227
78442
|
return { path: imagePath, ...dimensions, format: "png" };
|
|
78228
78443
|
}
|
|
78229
78444
|
}
|
|
@@ -78319,7 +78534,7 @@ var init_content_creator = __esm(() => {
|
|
|
78319
78534
|
});
|
|
78320
78535
|
|
|
78321
78536
|
// src/commands/content/phases/content-logger.ts
|
|
78322
|
-
import { createWriteStream as createWriteStream4, existsSync as
|
|
78537
|
+
import { createWriteStream as createWriteStream4, existsSync as existsSync88, mkdirSync as mkdirSync7, statSync as statSync16 } from "node:fs";
|
|
78323
78538
|
import { homedir as homedir58 } from "node:os";
|
|
78324
78539
|
import { join as join172 } from "node:path";
|
|
78325
78540
|
|
|
@@ -78333,7 +78548,7 @@ class ContentLogger {
|
|
|
78333
78548
|
this.maxBytes = maxBytes;
|
|
78334
78549
|
}
|
|
78335
78550
|
init() {
|
|
78336
|
-
if (!
|
|
78551
|
+
if (!existsSync88(this.logDir)) {
|
|
78337
78552
|
mkdirSync7(this.logDir, { recursive: true });
|
|
78338
78553
|
}
|
|
78339
78554
|
this.rotateIfNeeded();
|
|
@@ -78426,7 +78641,7 @@ function openDatabase(dbPath) {
|
|
|
78426
78641
|
var init_sqlite_client = () => {};
|
|
78427
78642
|
|
|
78428
78643
|
// src/commands/content/phases/db-manager.ts
|
|
78429
|
-
import { existsSync as
|
|
78644
|
+
import { existsSync as existsSync89, mkdirSync as mkdirSync8 } from "node:fs";
|
|
78430
78645
|
import { dirname as dirname51 } from "node:path";
|
|
78431
78646
|
function initDatabase(dbPath) {
|
|
78432
78647
|
ensureParentDir(dbPath);
|
|
@@ -78449,7 +78664,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
78449
78664
|
}
|
|
78450
78665
|
function ensureParentDir(dbPath) {
|
|
78451
78666
|
const dir = dirname51(dbPath);
|
|
78452
|
-
if (dir && !
|
|
78667
|
+
if (dir && !existsSync89(dir)) {
|
|
78453
78668
|
mkdirSync8(dir, { recursive: true });
|
|
78454
78669
|
}
|
|
78455
78670
|
}
|
|
@@ -78614,7 +78829,7 @@ function isNoiseCommit(title, author) {
|
|
|
78614
78829
|
|
|
78615
78830
|
// src/commands/content/phases/change-detector.ts
|
|
78616
78831
|
import { execFileSync as execFileSync4, spawnSync as spawnSync9 } from "node:child_process";
|
|
78617
|
-
import { existsSync as
|
|
78832
|
+
import { existsSync as existsSync90, readFileSync as readFileSync24, readdirSync as readdirSync15, statSync as statSync17 } from "node:fs";
|
|
78618
78833
|
import { join as join173 } from "node:path";
|
|
78619
78834
|
function detectCommits(repo, since) {
|
|
78620
78835
|
try {
|
|
@@ -78747,7 +78962,7 @@ function detectTags(repo, since) {
|
|
|
78747
78962
|
}
|
|
78748
78963
|
function detectCompletedPlans(repo, since) {
|
|
78749
78964
|
const plansDir = join173(repo.path, "plans");
|
|
78750
|
-
if (!
|
|
78965
|
+
if (!existsSync90(plansDir))
|
|
78751
78966
|
return [];
|
|
78752
78967
|
const sinceMs = new Date(since).getTime();
|
|
78753
78968
|
const events = [];
|
|
@@ -78757,13 +78972,13 @@ function detectCompletedPlans(repo, since) {
|
|
|
78757
78972
|
if (!entry.isDirectory())
|
|
78758
78973
|
continue;
|
|
78759
78974
|
const planFile = join173(plansDir, entry.name, "plan.md");
|
|
78760
|
-
if (!
|
|
78975
|
+
if (!existsSync90(planFile))
|
|
78761
78976
|
continue;
|
|
78762
78977
|
try {
|
|
78763
78978
|
const stat26 = statSync17(planFile);
|
|
78764
78979
|
if (stat26.mtimeMs < sinceMs)
|
|
78765
78980
|
continue;
|
|
78766
|
-
const content =
|
|
78981
|
+
const content = readFileSync24(planFile, "utf-8");
|
|
78767
78982
|
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
78768
78983
|
if (!frontmatterMatch)
|
|
78769
78984
|
continue;
|
|
@@ -79795,7 +80010,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
79795
80010
|
});
|
|
79796
80011
|
|
|
79797
80012
|
// src/commands/content/phases/setup-wizard.ts
|
|
79798
|
-
import { existsSync as
|
|
80013
|
+
import { existsSync as existsSync91 } from "node:fs";
|
|
79799
80014
|
import { join as join176 } from "node:path";
|
|
79800
80015
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
79801
80016
|
console.log();
|
|
@@ -79864,8 +80079,8 @@ async function showRepoSummary(cwd2) {
|
|
|
79864
80079
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
79865
80080
|
const repos = discoverRepos2(cwd2);
|
|
79866
80081
|
for (const repo of repos) {
|
|
79867
|
-
const hasGuidelines =
|
|
79868
|
-
const hasStyles =
|
|
80082
|
+
const hasGuidelines = existsSync91(join176(repo.path, "docs", "brand-guidelines.md"));
|
|
80083
|
+
const hasStyles = existsSync91(join176(repo.path, "assets", "writing-styles"));
|
|
79869
80084
|
if (!hasGuidelines) {
|
|
79870
80085
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
79871
80086
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -79931,13 +80146,13 @@ var init_setup_wizard = __esm(() => {
|
|
|
79931
80146
|
});
|
|
79932
80147
|
|
|
79933
80148
|
// src/commands/content/content-review-commands.ts
|
|
79934
|
-
import { existsSync as
|
|
80149
|
+
import { existsSync as existsSync92 } from "node:fs";
|
|
79935
80150
|
import { homedir as homedir59 } from "node:os";
|
|
79936
80151
|
async function queueContent() {
|
|
79937
80152
|
const cwd2 = process.cwd();
|
|
79938
80153
|
const config = await loadContentConfig(cwd2);
|
|
79939
80154
|
const dbPath = config.dbPath.replace(/^~/, homedir59());
|
|
79940
|
-
if (!
|
|
80155
|
+
if (!existsSync92(dbPath)) {
|
|
79941
80156
|
logger.info("No content database found. Run 'ack content setup' first.");
|
|
79942
80157
|
return;
|
|
79943
80158
|
}
|
|
@@ -80005,15 +80220,15 @@ __export(exports_content_subcommands, {
|
|
|
80005
80220
|
logsContent: () => logsContent,
|
|
80006
80221
|
approveContentCmd: () => approveContentCmd
|
|
80007
80222
|
});
|
|
80008
|
-
import { existsSync as
|
|
80223
|
+
import { existsSync as existsSync93, readFileSync as readFileSync25, unlinkSync as unlinkSync7 } from "node:fs";
|
|
80009
80224
|
import { homedir as homedir60 } from "node:os";
|
|
80010
80225
|
import { join as join177 } from "node:path";
|
|
80011
80226
|
function isDaemonRunning() {
|
|
80012
80227
|
const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
80013
|
-
if (!
|
|
80228
|
+
if (!existsSync93(lockFile))
|
|
80014
80229
|
return { running: false, pid: null };
|
|
80015
80230
|
try {
|
|
80016
|
-
const pidStr =
|
|
80231
|
+
const pidStr = readFileSync25(lockFile, "utf-8").trim();
|
|
80017
80232
|
const pid = Number.parseInt(pidStr, 10);
|
|
80018
80233
|
if (Number.isNaN(pid)) {
|
|
80019
80234
|
unlinkSync7(lockFile);
|
|
@@ -80042,12 +80257,12 @@ async function startContent(options2) {
|
|
|
80042
80257
|
}
|
|
80043
80258
|
async function stopContent() {
|
|
80044
80259
|
const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
80045
|
-
if (!
|
|
80260
|
+
if (!existsSync93(lockFile)) {
|
|
80046
80261
|
logger.info("Content daemon is not running.");
|
|
80047
80262
|
return;
|
|
80048
80263
|
}
|
|
80049
80264
|
try {
|
|
80050
|
-
const pidStr =
|
|
80265
|
+
const pidStr = readFileSync25(lockFile, "utf-8").trim();
|
|
80051
80266
|
const pid = Number.parseInt(pidStr, 10);
|
|
80052
80267
|
if (!Number.isNaN(pid)) {
|
|
80053
80268
|
process.kill(pid, "SIGTERM");
|
|
@@ -80083,7 +80298,7 @@ async function logsContent(options2) {
|
|
|
80083
80298
|
const logDir = join177(homedir60(), ".ack", "logs");
|
|
80084
80299
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
80085
80300
|
const logPath = join177(logDir, `content-${dateStr}.log`);
|
|
80086
|
-
if (!
|
|
80301
|
+
if (!existsSync93(logPath)) {
|
|
80087
80302
|
logger.info("No content logs found for today.");
|
|
80088
80303
|
return;
|
|
80089
80304
|
}
|
|
@@ -80095,7 +80310,7 @@ async function logsContent(options2) {
|
|
|
80095
80310
|
process.exit(0);
|
|
80096
80311
|
});
|
|
80097
80312
|
} else {
|
|
80098
|
-
const content =
|
|
80313
|
+
const content = readFileSync25(logPath, "utf-8");
|
|
80099
80314
|
console.log(content);
|
|
80100
80315
|
}
|
|
80101
80316
|
}
|
|
@@ -80118,7 +80333,7 @@ var init_content_subcommands = __esm(() => {
|
|
|
80118
80333
|
});
|
|
80119
80334
|
|
|
80120
80335
|
// src/commands/content/content-command.ts
|
|
80121
|
-
import { existsSync as
|
|
80336
|
+
import { existsSync as existsSync94, mkdirSync as mkdirSync9, unlinkSync as unlinkSync8, writeFileSync as writeFileSync10 } from "node:fs";
|
|
80122
80337
|
import { homedir as homedir61 } from "node:os";
|
|
80123
80338
|
import { join as join178 } from "node:path";
|
|
80124
80339
|
async function contentCommand(options2) {
|
|
@@ -80149,7 +80364,7 @@ async function contentCommand(options2) {
|
|
|
80149
80364
|
}
|
|
80150
80365
|
contentLogger.info("Setup complete. Starting daemon...");
|
|
80151
80366
|
}
|
|
80152
|
-
if (!
|
|
80367
|
+
if (!existsSync94(LOCK_DIR2))
|
|
80153
80368
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
80154
80369
|
writeFileSync10(LOCK_FILE, String(process.pid), "utf-8");
|
|
80155
80370
|
const dbPath = config.dbPath.replace(/^~/, homedir61());
|
|
@@ -90791,114 +91006,12 @@ function buildCheckResult(result) {
|
|
|
90791
91006
|
};
|
|
90792
91007
|
}
|
|
90793
91008
|
// src/domains/health-checks/checkers/npmrc-github-packages-checker.ts
|
|
91009
|
+
init_npmrc_bootstrap();
|
|
91010
|
+
init_environment();
|
|
90794
91011
|
import { spawn as spawn4 } from "node:child_process";
|
|
90795
91012
|
import { promises as fs11 } from "node:fs";
|
|
90796
91013
|
import { homedir as homedir44 } from "node:os";
|
|
90797
91014
|
import { join as join89 } from "node:path";
|
|
90798
|
-
|
|
90799
|
-
// src/domains/installation/npmrc-bootstrap.ts
|
|
90800
|
-
import { promises as fs10 } from "node:fs";
|
|
90801
|
-
import { dirname as dirname29 } from "node:path";
|
|
90802
|
-
var GITHUB_PACKAGES_REGISTRY_URL = "https://npm.pkg.github.com";
|
|
90803
|
-
var GITHUB_PACKAGES_SCOPE = "@chiendt1108";
|
|
90804
|
-
var SCOPE_REGISTRY_KEY = `${GITHUB_PACKAGES_SCOPE}:registry`;
|
|
90805
|
-
var AUTH_TOKEN_KEY = "//npm.pkg.github.com/:_authToken";
|
|
90806
|
-
function mergeNpmrcEntries(existing, entries) {
|
|
90807
|
-
const keys = new Set(Object.keys(entries));
|
|
90808
|
-
const seenKeys = new Set;
|
|
90809
|
-
const lines = existing.split(`
|
|
90810
|
-
`);
|
|
90811
|
-
const out = [];
|
|
90812
|
-
for (const line of lines) {
|
|
90813
|
-
const stripped = line.trim();
|
|
90814
|
-
if (stripped === "" || stripped.startsWith(";") || stripped.startsWith("#")) {
|
|
90815
|
-
out.push(line);
|
|
90816
|
-
continue;
|
|
90817
|
-
}
|
|
90818
|
-
const eq = line.indexOf("=");
|
|
90819
|
-
if (eq < 0) {
|
|
90820
|
-
out.push(line);
|
|
90821
|
-
continue;
|
|
90822
|
-
}
|
|
90823
|
-
const key = line.slice(0, eq).trim();
|
|
90824
|
-
if (keys.has(key)) {
|
|
90825
|
-
seenKeys.add(key);
|
|
90826
|
-
out.push(`${key}=${entries[key]}`);
|
|
90827
|
-
} else {
|
|
90828
|
-
out.push(line);
|
|
90829
|
-
}
|
|
90830
|
-
}
|
|
90831
|
-
const additions = [];
|
|
90832
|
-
for (const key of keys) {
|
|
90833
|
-
if (!seenKeys.has(key)) {
|
|
90834
|
-
additions.push(`${key}=${entries[key]}`);
|
|
90835
|
-
}
|
|
90836
|
-
}
|
|
90837
|
-
let result = out.join(`
|
|
90838
|
-
`);
|
|
90839
|
-
if (additions.length > 0) {
|
|
90840
|
-
if (result.length > 0 && !result.endsWith(`
|
|
90841
|
-
`))
|
|
90842
|
-
result += `
|
|
90843
|
-
`;
|
|
90844
|
-
result += `${additions.join(`
|
|
90845
|
-
`)}
|
|
90846
|
-
`;
|
|
90847
|
-
} else if (result.length > 0 && !result.endsWith(`
|
|
90848
|
-
`)) {
|
|
90849
|
-
result += `
|
|
90850
|
-
`;
|
|
90851
|
-
}
|
|
90852
|
-
return result;
|
|
90853
|
-
}
|
|
90854
|
-
async function writeNpmrc(path8, entries, opts = {}) {
|
|
90855
|
-
let existing = "";
|
|
90856
|
-
let hadFile = false;
|
|
90857
|
-
try {
|
|
90858
|
-
existing = await fs10.readFile(path8, "utf8");
|
|
90859
|
-
hadFile = true;
|
|
90860
|
-
} catch (err) {
|
|
90861
|
-
if (err.code !== "ENOENT")
|
|
90862
|
-
throw err;
|
|
90863
|
-
}
|
|
90864
|
-
const merged = mergeNpmrcEntries(existing, entries);
|
|
90865
|
-
if (merged === existing) {
|
|
90866
|
-
return { written: false, backupPath: null, finalPath: path8, noChange: true };
|
|
90867
|
-
}
|
|
90868
|
-
let backupPath = null;
|
|
90869
|
-
if (hadFile) {
|
|
90870
|
-
const now = opts.now?.() ?? new Date;
|
|
90871
|
-
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
90872
|
-
backupPath = `${path8}.bak.${stamp}`;
|
|
90873
|
-
await fs10.copyFile(path8, backupPath);
|
|
90874
|
-
}
|
|
90875
|
-
await fs10.mkdir(dirname29(path8), { recursive: true });
|
|
90876
|
-
const tmp = `${path8}.tmp.${process.pid}`;
|
|
90877
|
-
await fs10.writeFile(tmp, merged, { mode: 384 });
|
|
90878
|
-
await fs10.rename(tmp, path8);
|
|
90879
|
-
try {
|
|
90880
|
-
await fs10.chmod(path8, 384);
|
|
90881
|
-
} catch {}
|
|
90882
|
-
return { written: true, backupPath, finalPath: path8, noChange: false };
|
|
90883
|
-
}
|
|
90884
|
-
function buildGitHubPackagesEntries(pat) {
|
|
90885
|
-
const trimmed = pat.trim();
|
|
90886
|
-
return {
|
|
90887
|
-
[SCOPE_REGISTRY_KEY]: GITHUB_PACKAGES_REGISTRY_URL,
|
|
90888
|
-
[AUTH_TOKEN_KEY]: trimmed
|
|
90889
|
-
};
|
|
90890
|
-
}
|
|
90891
|
-
function isValidGitHubPat(value) {
|
|
90892
|
-
const v2 = value.trim();
|
|
90893
|
-
if (v2.length < 8)
|
|
90894
|
-
return false;
|
|
90895
|
-
if (/\s/.test(v2))
|
|
90896
|
-
return false;
|
|
90897
|
-
return /^(ghp_|github_pat_|ghs_|gho_|ghu_|ghr_)/.test(v2);
|
|
90898
|
-
}
|
|
90899
|
-
|
|
90900
|
-
// src/domains/health-checks/checkers/npmrc-github-packages-checker.ts
|
|
90901
|
-
init_environment();
|
|
90902
91015
|
var SETUP_HINT = "Run: ack fqc-qa-setup to write GitHub Packages config to ~/.npmrc";
|
|
90903
91016
|
var PROBE_PACKAGE = "@chiendt1108/fqc-mcp-servers";
|
|
90904
91017
|
var PROBE_TIMEOUT_MS = 5000;
|
|
@@ -92174,67 +92287,8 @@ function countFailures(states) {
|
|
|
92174
92287
|
// src/commands/fqc-qa/fqc-qa-setup-command.ts
|
|
92175
92288
|
init_logger();
|
|
92176
92289
|
init_dist2();
|
|
92290
|
+
init_npmrc_setup_step();
|
|
92177
92291
|
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
92178
|
-
|
|
92179
|
-
// src/commands/fqc-qa/npmrc-setup-step.ts
|
|
92180
|
-
import { homedir as homedir45 } from "node:os";
|
|
92181
|
-
import { join as join96 } from "node:path";
|
|
92182
|
-
init_logger();
|
|
92183
|
-
init_dist2();
|
|
92184
|
-
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
92185
|
-
async function runNpmrcSetupStep(opts = {}) {
|
|
92186
|
-
if (process.env.FQC_QA_SKIP_NPMRC === "1") {
|
|
92187
|
-
logger.info(import_picocolors19.default.dim("Skipping ~/.npmrc bootstrap (FQC_QA_SKIP_NPMRC=1)"));
|
|
92188
|
-
return { status: "skipped-env" };
|
|
92189
|
-
}
|
|
92190
|
-
console.log("");
|
|
92191
|
-
le([
|
|
92192
|
-
"To resolve @chiendt1108/fqc-mcp-servers from GitHub Packages, ~/.npmrc",
|
|
92193
|
-
"needs a scope mapping and a GitHub PAT with the `read:packages` scope.",
|
|
92194
|
-
"Create one at: https://github.com/settings/tokens (classic) or",
|
|
92195
|
-
"https://github.com/settings/personal-access-tokens/new (fine-grained).",
|
|
92196
|
-
"",
|
|
92197
|
-
"Press Enter / Esc to skip — rerun later with `ack fqc-qa-setup --npmrc-only`."
|
|
92198
|
-
].join(`
|
|
92199
|
-
`), "GitHub Packages auth");
|
|
92200
|
-
if (opts.yes) {
|
|
92201
|
-
logger.info(import_picocolors19.default.yellow("--yes given — skipping interactive PAT prompt."));
|
|
92202
|
-
return { status: "skipped-cancel" };
|
|
92203
|
-
}
|
|
92204
|
-
const pat = await re({
|
|
92205
|
-
message: "GitHub Personal Access Token (read:packages):",
|
|
92206
|
-
validate: (value) => {
|
|
92207
|
-
if (!value)
|
|
92208
|
-
return;
|
|
92209
|
-
if (!isValidGitHubPat(value)) {
|
|
92210
|
-
return "Token must start with ghp_, github_pat_, ghs_, gho_, ghu_, or ghr_.";
|
|
92211
|
-
}
|
|
92212
|
-
return;
|
|
92213
|
-
}
|
|
92214
|
-
});
|
|
92215
|
-
if (lD(pat) || !pat) {
|
|
92216
|
-
logger.info(import_picocolors19.default.yellow("Skipped PAT entry. Rerun with `ack fqc-qa-setup --npmrc-only` when ready."));
|
|
92217
|
-
return { status: "skipped-cancel" };
|
|
92218
|
-
}
|
|
92219
|
-
const npmrcPath = join96(homedir45(), ".npmrc");
|
|
92220
|
-
try {
|
|
92221
|
-
const result = await writeNpmrc(npmrcPath, buildGitHubPackagesEntries(pat));
|
|
92222
|
-
if (result.noChange) {
|
|
92223
|
-
logger.info(import_picocolors19.default.dim("~/.npmrc already up to date"));
|
|
92224
|
-
return { status: "no-change" };
|
|
92225
|
-
}
|
|
92226
|
-
logger.info(import_picocolors19.default.green(`Wrote GitHub Packages config → ${npmrcPath}`));
|
|
92227
|
-
if (result.backupPath)
|
|
92228
|
-
logger.info(import_picocolors19.default.dim(` backup: ${result.backupPath}`));
|
|
92229
|
-
return { status: "written", backupPath: result.backupPath };
|
|
92230
|
-
} catch (err) {
|
|
92231
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
92232
|
-
logger.error(`Failed to write ~/.npmrc: ${msg}`);
|
|
92233
|
-
return { status: "error", error: msg };
|
|
92234
|
-
}
|
|
92235
|
-
}
|
|
92236
|
-
|
|
92237
|
-
// src/commands/fqc-qa/fqc-qa-setup-command.ts
|
|
92238
92292
|
async function fqcQaSetupCommand(opts) {
|
|
92239
92293
|
if (opts.npmrcOnly) {
|
|
92240
92294
|
await runNpmrcSetupStep({ yes: opts.yes });
|
|
@@ -99632,7 +99686,7 @@ async function handleDownload(ctx) {
|
|
|
99632
99686
|
import { join as join129 } from "node:path";
|
|
99633
99687
|
|
|
99634
99688
|
// src/domains/installation/deletion-handler.ts
|
|
99635
|
-
import { existsSync as
|
|
99689
|
+
import { existsSync as existsSync71, lstatSync as lstatSync3, readdirSync as readdirSync8, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync5 } from "node:fs";
|
|
99636
99690
|
import { dirname as dirname36, join as join115, relative as relative22, resolve as resolve41, sep as sep11 } from "node:path";
|
|
99637
99691
|
|
|
99638
99692
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
@@ -99823,7 +99877,7 @@ function shouldDeletePath(path10, metadata, kitType) {
|
|
|
99823
99877
|
}
|
|
99824
99878
|
function collectFilesRecursively(dir, baseDir) {
|
|
99825
99879
|
const results = [];
|
|
99826
|
-
if (!
|
|
99880
|
+
if (!existsSync71(dir))
|
|
99827
99881
|
return results;
|
|
99828
99882
|
try {
|
|
99829
99883
|
const entries = readdirSync8(dir, { withFileTypes: true });
|
|
@@ -99964,7 +100018,7 @@ async function handleDeletions(sourceMetadata, claudeDir3, kitType) {
|
|
|
99964
100018
|
logger.verbose(`Preserved user file: ${path10}`);
|
|
99965
100019
|
continue;
|
|
99966
100020
|
}
|
|
99967
|
-
if (
|
|
100021
|
+
if (existsSync71(fullPath)) {
|
|
99968
100022
|
try {
|
|
99969
100023
|
deletePath(fullPath, claudeDir3);
|
|
99970
100024
|
result.deletedPaths.push(path10);
|
|
@@ -101911,7 +101965,7 @@ import { dirname as dirname38, join as join118 } from "node:path";
|
|
|
101911
101965
|
|
|
101912
101966
|
// src/domains/config/installed-settings-tracker.ts
|
|
101913
101967
|
init_shared();
|
|
101914
|
-
import { existsSync as
|
|
101968
|
+
import { existsSync as existsSync72 } from "node:fs";
|
|
101915
101969
|
import { mkdir as mkdir31, readFile as readFile53, writeFile as writeFile27 } from "node:fs/promises";
|
|
101916
101970
|
import { dirname as dirname37, join as join117 } from "node:path";
|
|
101917
101971
|
var CK_JSON_FILE = ".ck.json";
|
|
@@ -101933,7 +101987,7 @@ class InstalledSettingsTracker {
|
|
|
101933
101987
|
}
|
|
101934
101988
|
async loadInstalledSettings() {
|
|
101935
101989
|
const ckJsonPath = this.getCkJsonPath();
|
|
101936
|
-
if (!
|
|
101990
|
+
if (!existsSync72(ckJsonPath)) {
|
|
101937
101991
|
return { hooks: [], mcpServers: [] };
|
|
101938
101992
|
}
|
|
101939
101993
|
try {
|
|
@@ -101953,7 +102007,7 @@ class InstalledSettingsTracker {
|
|
|
101953
102007
|
const ckJsonPath = this.getCkJsonPath();
|
|
101954
102008
|
try {
|
|
101955
102009
|
let data = {};
|
|
101956
|
-
if (
|
|
102010
|
+
if (existsSync72(ckJsonPath)) {
|
|
101957
102011
|
const content = await readFile53(ckJsonPath, "utf-8");
|
|
101958
102012
|
data = JSON.parse(content);
|
|
101959
102013
|
}
|
|
@@ -105609,6 +105663,10 @@ async function handlePostInstall(ctx) {
|
|
|
105609
105663
|
withSudo: ctx.options.withSudo
|
|
105610
105664
|
});
|
|
105611
105665
|
}
|
|
105666
|
+
if (ctx.kitType === "fqc-qa") {
|
|
105667
|
+
const { runNpmrcSetupStep: runNpmrcSetupStep2 } = await Promise.resolve().then(() => (init_npmrc_setup_step(), exports_npmrc_setup_step));
|
|
105668
|
+
await runNpmrcSetupStep2({ yes: ctx.isNonInteractive });
|
|
105669
|
+
}
|
|
105612
105670
|
if (!ctx.isNonInteractive) {
|
|
105613
105671
|
const { isGeminiInstalled: isGeminiInstalled2 } = await Promise.resolve().then(() => (init_package_installer(), exports_package_installer));
|
|
105614
105672
|
const { checkExistingGeminiConfig: checkExistingGeminiConfig2, findMcpConfigPath: findMcpConfigPath2, processGeminiMcpLinking: processGeminiMcpLinking2 } = await Promise.resolve().then(() => (init_gemini_mcp_linker(), exports_gemini_mcp_linker));
|
|
@@ -105828,7 +105886,7 @@ async function runPreflightChecks() {
|
|
|
105828
105886
|
|
|
105829
105887
|
// src/domains/installation/fresh-installer.ts
|
|
105830
105888
|
init_metadata_migration();
|
|
105831
|
-
import { existsSync as
|
|
105889
|
+
import { existsSync as existsSync73, readdirSync as readdirSync9, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync6 } from "node:fs";
|
|
105832
105890
|
import { basename as basename28, dirname as dirname40, join as join141, resolve as resolve45 } from "node:path";
|
|
105833
105891
|
init_logger();
|
|
105834
105892
|
init_safe_spinner();
|
|
@@ -105912,7 +105970,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
105912
105970
|
}
|
|
105913
105971
|
for (const file of filesToRemove) {
|
|
105914
105972
|
const fullPath = join141(claudeDir3, file.path);
|
|
105915
|
-
if (!
|
|
105973
|
+
if (!existsSync73(fullPath)) {
|
|
105916
105974
|
continue;
|
|
105917
105975
|
}
|
|
105918
105976
|
try {
|
|
@@ -105970,8 +106028,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
|
|
|
105970
106028
|
mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
|
|
105971
106029
|
};
|
|
105972
106030
|
}
|
|
105973
|
-
const deletePaths = ACK_SUBDIRECTORIES.filter((subdir) =>
|
|
105974
|
-
if (
|
|
106031
|
+
const deletePaths = ACK_SUBDIRECTORIES.filter((subdir) => existsSync73(join141(claudeDir3, subdir)));
|
|
106032
|
+
if (existsSync73(join141(claudeDir3, "metadata.json"))) {
|
|
105975
106033
|
deletePaths.push("metadata.json");
|
|
105976
106034
|
}
|
|
105977
106035
|
return {
|
|
@@ -107660,7 +107718,7 @@ async function initCommand(options2) {
|
|
|
107660
107718
|
// src/commands/migrate/migrate-command.ts
|
|
107661
107719
|
init_dist2();
|
|
107662
107720
|
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
107663
|
-
import { existsSync as
|
|
107721
|
+
import { existsSync as existsSync74 } from "node:fs";
|
|
107664
107722
|
import { readFile as readFile68, rm as rm20, unlink as unlink15 } from "node:fs/promises";
|
|
107665
107723
|
import { homedir as homedir54 } from "node:os";
|
|
107666
107724
|
import { basename as basename30, join as join152, resolve as resolve50 } from "node:path";
|
|
@@ -109303,7 +109361,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
109303
109361
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
109304
109362
|
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve50(action.targetPath));
|
|
109305
109363
|
try {
|
|
109306
|
-
if (!shouldPreserveTarget && action.targetPath &&
|
|
109364
|
+
if (!shouldPreserveTarget && action.targetPath && existsSync74(action.targetPath)) {
|
|
109307
109365
|
await rm20(action.targetPath, { recursive: true, force: true });
|
|
109308
109366
|
}
|
|
109309
109367
|
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
@@ -109335,7 +109393,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
109335
109393
|
if (!skillSourcePath)
|
|
109336
109394
|
return;
|
|
109337
109395
|
const sourceMetadataPath = join152(resolve50(skillSourcePath, ".."), "metadata.json");
|
|
109338
|
-
if (!
|
|
109396
|
+
if (!existsSync74(sourceMetadataPath))
|
|
109339
109397
|
return;
|
|
109340
109398
|
let sourceMetadata;
|
|
109341
109399
|
try {
|
|
@@ -109348,7 +109406,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
109348
109406
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
109349
109407
|
return;
|
|
109350
109408
|
const claudeDir3 = installGlobally ? join152(homedir54(), ".claude") : join152(process.cwd(), ".claude");
|
|
109351
|
-
if (!
|
|
109409
|
+
if (!existsSync74(claudeDir3))
|
|
109352
109410
|
return;
|
|
109353
109411
|
try {
|
|
109354
109412
|
const result = await handleDeletions(sourceMetadata, claudeDir3, inferKitTypeFromSourceMetadata(sourceMetadata));
|
|
@@ -109640,7 +109698,7 @@ async function migrateCommand(options2) {
|
|
|
109640
109698
|
const interactive = process.stdout.isTTY && !options2.yes;
|
|
109641
109699
|
const conflictActions = plan.actions.filter((a3) => a3.action === "conflict");
|
|
109642
109700
|
for (const action of conflictActions) {
|
|
109643
|
-
if (!action.diff && action.targetPath &&
|
|
109701
|
+
if (!action.diff && action.targetPath && existsSync74(action.targetPath)) {
|
|
109644
109702
|
try {
|
|
109645
109703
|
const targetContent = await readFile68(action.targetPath, "utf-8");
|
|
109646
109704
|
const sourceItem = effectiveAgents.find((a3) => a3.name === action.item) || effectiveCommands.find((c2) => c2.name === action.item) || (effectiveConfigItem?.name === action.item ? effectiveConfigItem : null) || effectiveRuleItems.find((r2) => r2.name === action.item) || effectiveHookItems.find((h2) => h2.name === action.item);
|
|
@@ -109956,7 +110014,7 @@ async function migrateCommand(options2) {
|
|
|
109956
110014
|
async function rollbackResults(results) {
|
|
109957
110015
|
const rolledBackPaths = new Set;
|
|
109958
110016
|
for (const result of results) {
|
|
109959
|
-
if (!result.path || !
|
|
110017
|
+
if (!result.path || !existsSync74(result.path))
|
|
109960
110018
|
continue;
|
|
109961
110019
|
try {
|
|
109962
110020
|
if (result.overwritten)
|
|
@@ -110523,7 +110581,7 @@ Please use only one download method.`);
|
|
|
110523
110581
|
}
|
|
110524
110582
|
// src/commands/plan/plan-command.ts
|
|
110525
110583
|
init_output_manager();
|
|
110526
|
-
import { existsSync as
|
|
110584
|
+
import { existsSync as existsSync77, statSync as statSync13 } from "node:fs";
|
|
110527
110585
|
import { dirname as dirname48, isAbsolute as isAbsolute13, join as join157, parse as parse3, resolve as resolve55 } from "node:path";
|
|
110528
110586
|
|
|
110529
110587
|
// src/commands/plan/plan-read-handlers.ts
|
|
@@ -110533,14 +110591,14 @@ init_plans_registry();
|
|
|
110533
110591
|
init_logger();
|
|
110534
110592
|
init_output_manager();
|
|
110535
110593
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
110536
|
-
import { existsSync as
|
|
110594
|
+
import { existsSync as existsSync76, statSync as statSync12 } from "node:fs";
|
|
110537
110595
|
import { basename as basename31, dirname as dirname46, join as join156, relative as relative32, resolve as resolve53 } from "node:path";
|
|
110538
110596
|
|
|
110539
110597
|
// src/commands/plan/plan-dependencies.ts
|
|
110540
110598
|
init_config();
|
|
110541
110599
|
init_plan_parser();
|
|
110542
110600
|
init_plans_registry();
|
|
110543
|
-
import { existsSync as
|
|
110601
|
+
import { existsSync as existsSync75 } from "node:fs";
|
|
110544
110602
|
import { dirname as dirname45, join as join155 } from "node:path";
|
|
110545
110603
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
110546
110604
|
if (references.length === 0)
|
|
@@ -110563,7 +110621,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
110563
110621
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
110564
110622
|
const planFile = join155(scopeRoot, planId, "plan.md");
|
|
110565
110623
|
const isSelfReference = planFile === currentPlanFile;
|
|
110566
|
-
if (!
|
|
110624
|
+
if (!existsSync75(planFile)) {
|
|
110567
110625
|
return {
|
|
110568
110626
|
reference,
|
|
110569
110627
|
scope,
|
|
@@ -110703,7 +110761,7 @@ async function handleStatus(target, options2) {
|
|
|
110703
110761
|
}
|
|
110704
110762
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
110705
110763
|
const t = effectiveTarget ? resolve53(effectiveTarget) : null;
|
|
110706
|
-
const plansDir = t &&
|
|
110764
|
+
const plansDir = t && existsSync76(t) && statSync12(t).isDirectory() && !existsSync76(join156(t, "plan.md")) ? t : null;
|
|
110707
110765
|
if (plansDir) {
|
|
110708
110766
|
const planFiles = scanPlanDir(plansDir);
|
|
110709
110767
|
if (planFiles.length === 0) {
|
|
@@ -111107,19 +111165,19 @@ function resolveTargetPath(target, baseDir) {
|
|
|
111107
111165
|
return resolve55(target);
|
|
111108
111166
|
}
|
|
111109
111167
|
const cwdCandidate = resolve55(target);
|
|
111110
|
-
if (
|
|
111168
|
+
if (existsSync77(cwdCandidate)) {
|
|
111111
111169
|
return cwdCandidate;
|
|
111112
111170
|
}
|
|
111113
111171
|
return resolve55(baseDir, target);
|
|
111114
111172
|
}
|
|
111115
111173
|
function resolvePlanFile(target, baseDir) {
|
|
111116
111174
|
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve55(baseDir) : process.cwd();
|
|
111117
|
-
if (
|
|
111175
|
+
if (existsSync77(t)) {
|
|
111118
111176
|
const stat24 = statSync13(t);
|
|
111119
111177
|
if (stat24.isFile())
|
|
111120
111178
|
return t;
|
|
111121
111179
|
const candidate = join157(t, "plan.md");
|
|
111122
|
-
if (
|
|
111180
|
+
if (existsSync77(candidate))
|
|
111123
111181
|
return candidate;
|
|
111124
111182
|
}
|
|
111125
111183
|
if (!target && !baseDir) {
|
|
@@ -111127,7 +111185,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
111127
111185
|
const root = parse3(dir).root;
|
|
111128
111186
|
while (dir !== root) {
|
|
111129
111187
|
const candidate = join157(dir, "plan.md");
|
|
111130
|
-
if (
|
|
111188
|
+
if (existsSync77(candidate))
|
|
111131
111189
|
return candidate;
|
|
111132
111190
|
dir = dirname48(dir);
|
|
111133
111191
|
}
|
|
@@ -111177,7 +111235,7 @@ async function planCommand(action, target, options2) {
|
|
|
111177
111235
|
let resolvedTarget = target;
|
|
111178
111236
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
111179
111237
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
111180
|
-
const existsOnDisk = !looksLikePath &&
|
|
111238
|
+
const existsOnDisk = !looksLikePath && existsSync77(resolve55(resolvedAction));
|
|
111181
111239
|
if (looksLikePath || existsOnDisk) {
|
|
111182
111240
|
resolvedTarget = resolvedAction;
|
|
111183
111241
|
resolvedAction = undefined;
|
|
@@ -111219,13 +111277,13 @@ init_ack_data2();
|
|
|
111219
111277
|
init_logger();
|
|
111220
111278
|
init_safe_prompts();
|
|
111221
111279
|
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
111222
|
-
import { existsSync as
|
|
111280
|
+
import { existsSync as existsSync78 } from "node:fs";
|
|
111223
111281
|
import { resolve as resolve56 } from "node:path";
|
|
111224
111282
|
async function handleAdd(projectPath, options2) {
|
|
111225
111283
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
111226
111284
|
intro("Add Project");
|
|
111227
111285
|
const absolutePath = resolve56(projectPath);
|
|
111228
|
-
if (!
|
|
111286
|
+
if (!existsSync78(absolutePath)) {
|
|
111229
111287
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
111230
111288
|
process.exitCode = 1;
|
|
111231
111289
|
return;
|
|
@@ -113080,7 +113138,7 @@ ${import_picocolors45.default.bold(import_picocolors45.default.cyan(result.kitCo
|
|
|
113080
113138
|
|
|
113081
113139
|
// src/commands/watch/watch-command.ts
|
|
113082
113140
|
init_logger();
|
|
113083
|
-
import { existsSync as
|
|
113141
|
+
import { existsSync as existsSync84 } from "node:fs";
|
|
113084
113142
|
import { rm as rm21 } from "node:fs/promises";
|
|
113085
113143
|
import { join as join168 } from "node:path";
|
|
113086
113144
|
var import_picocolors46 = __toESM(require_picocolors(), 1);
|
|
@@ -114379,14 +114437,14 @@ function cleanExpiredIssues(state, ttlDays) {
|
|
|
114379
114437
|
init_ck_config_manager();
|
|
114380
114438
|
init_file_io();
|
|
114381
114439
|
init_logger();
|
|
114382
|
-
import { existsSync as
|
|
114440
|
+
import { existsSync as existsSync80 } from "node:fs";
|
|
114383
114441
|
import { mkdir as mkdir41, readFile as readFile71 } from "node:fs/promises";
|
|
114384
114442
|
import { dirname as dirname50 } from "node:path";
|
|
114385
114443
|
var PROCESSED_ISSUES_CAP = 500;
|
|
114386
114444
|
async function readCkJson(projectDir) {
|
|
114387
114445
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
114388
114446
|
try {
|
|
114389
|
-
if (!
|
|
114447
|
+
if (!existsSync80(configPath))
|
|
114390
114448
|
return {};
|
|
114391
114449
|
const content = await readFile71(configPath, "utf-8");
|
|
114392
114450
|
return JSON.parse(content);
|
|
@@ -114412,7 +114470,7 @@ async function loadWatchState(projectDir) {
|
|
|
114412
114470
|
async function saveWatchState(projectDir, state) {
|
|
114413
114471
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
114414
114472
|
const configDir = dirname50(configPath);
|
|
114415
|
-
if (!
|
|
114473
|
+
if (!existsSync80(configDir)) {
|
|
114416
114474
|
await mkdir41(configDir, { recursive: true });
|
|
114417
114475
|
}
|
|
114418
114476
|
const raw = await readCkJson(projectDir);
|
|
@@ -114539,7 +114597,7 @@ async function processImplementationQueue(state, config, setup, options2, watchL
|
|
|
114539
114597
|
// src/commands/watch/phases/repo-scanner.ts
|
|
114540
114598
|
init_logger();
|
|
114541
114599
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
114542
|
-
import { existsSync as
|
|
114600
|
+
import { existsSync as existsSync81 } from "node:fs";
|
|
114543
114601
|
import { readdir as readdir47, stat as stat25 } from "node:fs/promises";
|
|
114544
114602
|
import { join as join165 } from "node:path";
|
|
114545
114603
|
async function scanForRepos(parentDir) {
|
|
@@ -114553,7 +114611,7 @@ async function scanForRepos(parentDir) {
|
|
|
114553
114611
|
if (!entryStat.isDirectory())
|
|
114554
114612
|
continue;
|
|
114555
114613
|
const gitDir = join165(fullPath, ".git");
|
|
114556
|
-
if (!
|
|
114614
|
+
if (!existsSync81(gitDir))
|
|
114557
114615
|
continue;
|
|
114558
114616
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
114559
114617
|
encoding: "utf-8",
|
|
@@ -114577,7 +114635,7 @@ async function scanForRepos(parentDir) {
|
|
|
114577
114635
|
// src/commands/watch/phases/setup-validator.ts
|
|
114578
114636
|
init_logger();
|
|
114579
114637
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
114580
|
-
import { existsSync as
|
|
114638
|
+
import { existsSync as existsSync82 } from "node:fs";
|
|
114581
114639
|
import { homedir as homedir55 } from "node:os";
|
|
114582
114640
|
import { join as join166 } from "node:path";
|
|
114583
114641
|
async function validateSetup(cwd2) {
|
|
@@ -114611,7 +114669,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
114611
114669
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
114612
114670
|
}
|
|
114613
114671
|
const skillsPath = join166(homedir55(), ".claude", "skills");
|
|
114614
|
-
const skillsAvailable =
|
|
114672
|
+
const skillsAvailable = existsSync82(skillsPath);
|
|
114615
114673
|
if (!skillsAvailable) {
|
|
114616
114674
|
logger.warning(`AckKit Engineer skills not found at ${skillsPath}`);
|
|
114617
114675
|
}
|
|
@@ -114627,7 +114685,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
114627
114685
|
init_logger();
|
|
114628
114686
|
init_path_resolver();
|
|
114629
114687
|
import { createWriteStream as createWriteStream3, statSync as statSync14 } from "node:fs";
|
|
114630
|
-
import { existsSync as
|
|
114688
|
+
import { existsSync as existsSync83 } from "node:fs";
|
|
114631
114689
|
import { mkdir as mkdir42, rename as rename16 } from "node:fs/promises";
|
|
114632
114690
|
import { join as join167 } from "node:path";
|
|
114633
114691
|
|
|
@@ -114642,7 +114700,7 @@ class WatchLogger {
|
|
|
114642
114700
|
}
|
|
114643
114701
|
async init() {
|
|
114644
114702
|
try {
|
|
114645
|
-
if (!
|
|
114703
|
+
if (!existsSync83(this.logDir)) {
|
|
114646
114704
|
await mkdir42(this.logDir, { recursive: true });
|
|
114647
114705
|
}
|
|
114648
114706
|
const dateStr = formatDate(new Date);
|
|
@@ -114828,7 +114886,7 @@ async function watchCommand(options2) {
|
|
|
114828
114886
|
}
|
|
114829
114887
|
async function discoverRepos(options2, watchLog) {
|
|
114830
114888
|
const cwd2 = process.cwd();
|
|
114831
|
-
const isGitRepo =
|
|
114889
|
+
const isGitRepo = existsSync84(join168(cwd2, ".git"));
|
|
114832
114890
|
if (options2.force) {
|
|
114833
114891
|
await forceRemoveLock(watchLog);
|
|
114834
114892
|
}
|
|
@@ -115131,7 +115189,7 @@ init_logger();
|
|
|
115131
115189
|
init_path_resolver();
|
|
115132
115190
|
init_types3();
|
|
115133
115191
|
init_types3();
|
|
115134
|
-
import { existsSync as
|
|
115192
|
+
import { existsSync as existsSync95, readFileSync as readFileSync26 } from "node:fs";
|
|
115135
115193
|
import { join as join179 } from "node:path";
|
|
115136
115194
|
var packageVersion2 = package_default.version;
|
|
115137
115195
|
function formatInstalledKits(metadata) {
|
|
@@ -115201,9 +115259,9 @@ async function displayVersion() {
|
|
|
115201
115259
|
const prefix = PathResolver.getPathPrefix(false);
|
|
115202
115260
|
const localMetadataPath = prefix ? join179(process.cwd(), prefix, "metadata.json") : join179(process.cwd(), "metadata.json");
|
|
115203
115261
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
115204
|
-
if (!isLocalSameAsGlobal &&
|
|
115262
|
+
if (!isLocalSameAsGlobal && existsSync95(localMetadataPath)) {
|
|
115205
115263
|
try {
|
|
115206
|
-
const rawMetadata = JSON.parse(
|
|
115264
|
+
const rawMetadata = JSON.parse(readFileSync26(localMetadataPath, "utf-8"));
|
|
115207
115265
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
115208
115266
|
const kitsDisplay = formatInstalledKits(metadata);
|
|
115209
115267
|
if (kitsDisplay) {
|
|
@@ -115215,9 +115273,9 @@ async function displayVersion() {
|
|
|
115215
115273
|
logger.verbose("Failed to parse local metadata.json", { error });
|
|
115216
115274
|
}
|
|
115217
115275
|
}
|
|
115218
|
-
if (
|
|
115276
|
+
if (existsSync95(globalMetadataPath)) {
|
|
115219
115277
|
try {
|
|
115220
|
-
const rawMetadata = JSON.parse(
|
|
115278
|
+
const rawMetadata = JSON.parse(readFileSync26(globalMetadataPath, "utf-8"));
|
|
115221
115279
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
115222
115280
|
const kitsDisplay = formatInstalledKits(metadata);
|
|
115223
115281
|
if (kitsDisplay) {
|