truecourse 0.5.2 → 0.5.3
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.mjs +57 -37
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -4080,7 +4080,7 @@ __export(helpers_exports, {
|
|
|
4080
4080
|
writeConfig: () => writeConfig
|
|
4081
4081
|
});
|
|
4082
4082
|
import { exec as exec2 } from "node:child_process";
|
|
4083
|
-
import { cpSync, existsSync } from "node:fs";
|
|
4083
|
+
import { cpSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
4084
4084
|
import fs3 from "node:fs";
|
|
4085
4085
|
import os2 from "node:os";
|
|
4086
4086
|
import path3 from "node:path";
|
|
@@ -4319,12 +4319,6 @@ function openInBrowser(url) {
|
|
|
4319
4319
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
4320
4320
|
exec2(`${cmd} ${url}`);
|
|
4321
4321
|
}
|
|
4322
|
-
function skillDestPath(repoPath) {
|
|
4323
|
-
return resolve(repoPath, ".claude", "skills", "truecourse");
|
|
4324
|
-
}
|
|
4325
|
-
function hasInstalledSkills(repoPath) {
|
|
4326
|
-
return existsSync(skillDestPath(repoPath));
|
|
4327
|
-
}
|
|
4328
4322
|
function isInteractive() {
|
|
4329
4323
|
return !!process.stdin.isTTY;
|
|
4330
4324
|
}
|
|
@@ -4336,35 +4330,61 @@ Running non-interactively with no answer. ${flagGuidance}`
|
|
|
4336
4330
|
);
|
|
4337
4331
|
process.exit(1);
|
|
4338
4332
|
}
|
|
4339
|
-
function
|
|
4333
|
+
function resolveSkillsSrcDir() {
|
|
4340
4334
|
const __dirname4 = dirname(fileURLToPath(import.meta.url));
|
|
4341
|
-
const
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4335
|
+
const candidate = resolve(__dirname4, "skills", "truecourse");
|
|
4336
|
+
return existsSync(candidate) ? candidate : null;
|
|
4337
|
+
}
|
|
4338
|
+
function skillDestDir(repoPath) {
|
|
4339
|
+
return resolve(repoPath, ".claude", "skills", "truecourse");
|
|
4340
|
+
}
|
|
4341
|
+
function listSkillDirs(root) {
|
|
4342
|
+
if (!existsSync(root)) return [];
|
|
4343
|
+
return readdirSync(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
4344
|
+
}
|
|
4345
|
+
function computeMissingSkills(repoPath) {
|
|
4346
|
+
const src = resolveSkillsSrcDir();
|
|
4347
|
+
if (!src) return [];
|
|
4348
|
+
const shipped = new Set(listSkillDirs(src));
|
|
4349
|
+
const installed = new Set(listSkillDirs(skillDestDir(repoPath)));
|
|
4350
|
+
return [...shipped].filter((name) => !installed.has(name));
|
|
4351
|
+
}
|
|
4352
|
+
function hasInstalledSkills(repoPath) {
|
|
4353
|
+
return computeMissingSkills(repoPath).length === 0;
|
|
4354
|
+
}
|
|
4355
|
+
function copySkills(repoPath, skillNames) {
|
|
4356
|
+
const src = resolveSkillsSrcDir();
|
|
4357
|
+
if (!src) {
|
|
4345
4358
|
O2.warn("Skills directory not found in package \u2014 skipping.");
|
|
4346
4359
|
return;
|
|
4347
4360
|
}
|
|
4348
|
-
const
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4361
|
+
const destParent = skillDestDir(repoPath);
|
|
4362
|
+
mkdirSync(destParent, { recursive: true });
|
|
4363
|
+
for (const name of skillNames) {
|
|
4364
|
+
const skillSrc = resolve(src, name);
|
|
4365
|
+
const skillDest = resolve(destParent, name);
|
|
4366
|
+
if (existsSync(skillDest)) continue;
|
|
4367
|
+
cpSync(skillSrc, skillDest, { recursive: true });
|
|
4368
|
+
}
|
|
4369
|
+
O2.success(
|
|
4370
|
+
`Installed ${skillNames.length} Claude Code skill${skillNames.length === 1 ? "" : "s"}:`
|
|
4371
|
+
);
|
|
4372
|
+
for (const name of skillNames) O2.message(` - ${name}`);
|
|
4354
4373
|
}
|
|
4355
4374
|
async function promptInstallSkills(repoPath, { install } = {}) {
|
|
4356
|
-
|
|
4375
|
+
const missing = computeMissingSkills(repoPath);
|
|
4376
|
+
if (missing.length === 0) return;
|
|
4357
4377
|
if (install === true) {
|
|
4358
|
-
|
|
4378
|
+
copySkills(repoPath, missing);
|
|
4359
4379
|
return;
|
|
4360
4380
|
}
|
|
4361
4381
|
if (install === false) return;
|
|
4362
4382
|
if (!isInteractive()) return;
|
|
4363
|
-
const
|
|
4364
|
-
|
|
4365
|
-
});
|
|
4383
|
+
const isUpgrade = existsSync(skillDestDir(repoPath));
|
|
4384
|
+
const message = isUpgrade ? `New Claude Code skill${missing.length === 1 ? "" : "s"} available: ${missing.join(", ")}. Install?` : "Would you like to install Claude Code skills?";
|
|
4385
|
+
const answer = await ot2({ message });
|
|
4366
4386
|
if (q(answer) || !answer) return;
|
|
4367
|
-
|
|
4387
|
+
copySkills(repoPath, missing);
|
|
4368
4388
|
}
|
|
4369
4389
|
var DEFAULT_PORT, DEFAULT_CONFIG;
|
|
4370
4390
|
var init_helpers = __esm({
|
|
@@ -10563,7 +10583,7 @@ var init_language_config = __esm({
|
|
|
10563
10583
|
});
|
|
10564
10584
|
|
|
10565
10585
|
// packages/analyzer/dist/file-discovery.js
|
|
10566
|
-
import { existsSync as existsSync2, readFileSync, readdirSync, statSync } from "fs";
|
|
10586
|
+
import { existsSync as existsSync2, readFileSync, readdirSync as readdirSync2, statSync } from "fs";
|
|
10567
10587
|
import { join, relative, resolve as resolve2 } from "path";
|
|
10568
10588
|
function findAllGitignores(startDir) {
|
|
10569
10589
|
const gitignores = [];
|
|
@@ -10606,7 +10626,7 @@ function discoverFiles(dir) {
|
|
|
10606
10626
|
const { ig, rootDir } = loadIgnorePatterns(dir);
|
|
10607
10627
|
function traverse(currentPath) {
|
|
10608
10628
|
try {
|
|
10609
|
-
const entries =
|
|
10629
|
+
const entries = readdirSync2(currentPath).sort();
|
|
10610
10630
|
for (const entry of entries) {
|
|
10611
10631
|
const fullPath = join(currentPath, entry);
|
|
10612
10632
|
const relativePath = relative(rootDir, fullPath);
|
|
@@ -10894,7 +10914,7 @@ var init_service_patterns = __esm({
|
|
|
10894
10914
|
// packages/analyzer/dist/ts-compiler.js
|
|
10895
10915
|
import * as ts from "typescript";
|
|
10896
10916
|
import { dirname as dirname2, join as join2 } from "path";
|
|
10897
|
-
import { existsSync as existsSync3, readdirSync as
|
|
10917
|
+
import { existsSync as existsSync3, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
|
|
10898
10918
|
function buildScopedCompilerOptions(rootPath) {
|
|
10899
10919
|
const result = [];
|
|
10900
10920
|
const candidates = [join2(rootPath, "tsconfig.json")];
|
|
@@ -10903,7 +10923,7 @@ function buildScopedCompilerOptions(rootPath) {
|
|
|
10903
10923
|
if (!existsSync3(dirPath) || !statSync2(dirPath).isDirectory())
|
|
10904
10924
|
continue;
|
|
10905
10925
|
try {
|
|
10906
|
-
for (const entry of
|
|
10926
|
+
for (const entry of readdirSync3(dirPath).sort()) {
|
|
10907
10927
|
candidates.push(join2(dirPath, entry, "tsconfig.json"));
|
|
10908
10928
|
}
|
|
10909
10929
|
} catch {
|
|
@@ -13533,7 +13553,7 @@ var init_registry2 = __esm({
|
|
|
13533
13553
|
|
|
13534
13554
|
// packages/analyzer/dist/dependency-graph.js
|
|
13535
13555
|
import { resolve as resolve4, dirname as dirname4, join as join3 } from "path";
|
|
13536
|
-
import { existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as
|
|
13556
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as readdirSync4, realpathSync, statSync as statSync3 } from "fs";
|
|
13537
13557
|
function resolveRelativeFallback(importSource, containingFile, analyzedFiles, extensions, indexFiles) {
|
|
13538
13558
|
const fromDir = dirname4(containingFile);
|
|
13539
13559
|
const basePath = resolve4(fromDir, importSource);
|
|
@@ -13561,7 +13581,7 @@ function buildWorkspacePackageMap(rootPath) {
|
|
|
13561
13581
|
if (!existsSync4(dirPath) || !statSync3(dirPath).isDirectory())
|
|
13562
13582
|
continue;
|
|
13563
13583
|
try {
|
|
13564
|
-
for (const entry of
|
|
13584
|
+
for (const entry of readdirSync4(dirPath).sort()) {
|
|
13565
13585
|
const pkgDir = join3(dirPath, entry);
|
|
13566
13586
|
const pkgJsonPath = join3(pkgDir, "package.json");
|
|
13567
13587
|
if (!existsSync4(pkgJsonPath))
|
|
@@ -16249,7 +16269,7 @@ var init_registry3 = __esm({
|
|
|
16249
16269
|
});
|
|
16250
16270
|
|
|
16251
16271
|
// packages/analyzer/dist/service-detector.js
|
|
16252
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5, readdirSync as
|
|
16272
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
16253
16273
|
import { join as join6, basename, dirname as dirname5 } from "path";
|
|
16254
16274
|
function detectServices(rootPath, allFiles) {
|
|
16255
16275
|
const monorepoServices = detectMonorepoServices(rootPath, allFiles);
|
|
@@ -16294,7 +16314,7 @@ function detectMonorepoServices(rootPath, allFiles) {
|
|
|
16294
16314
|
if (!existsSync7(dirPath))
|
|
16295
16315
|
continue;
|
|
16296
16316
|
try {
|
|
16297
|
-
const entries =
|
|
16317
|
+
const entries = readdirSync5(dirPath).sort();
|
|
16298
16318
|
for (const entry of entries) {
|
|
16299
16319
|
const servicePath = join6(dirPath, entry);
|
|
16300
16320
|
const stats = statSync4(servicePath);
|
|
@@ -17050,7 +17070,7 @@ var init_registry4 = __esm({
|
|
|
17050
17070
|
});
|
|
17051
17071
|
|
|
17052
17072
|
// packages/analyzer/dist/database-detector.js
|
|
17053
|
-
import { existsSync as existsSync8, readFileSync as readFileSync6, readdirSync as
|
|
17073
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, readdirSync as readdirSync6 } from "fs";
|
|
17054
17074
|
import { join as join7, resolve as resolve5 } from "path";
|
|
17055
17075
|
function detectDatabases(rootPath, analyses, services) {
|
|
17056
17076
|
const detections = [];
|
|
@@ -17219,7 +17239,7 @@ function parseDockerCompose(rootPath) {
|
|
|
17219
17239
|
function findFiles(dir, fileName, ignoreDirs) {
|
|
17220
17240
|
const results = [];
|
|
17221
17241
|
try {
|
|
17222
|
-
const entries =
|
|
17242
|
+
const entries = readdirSync6(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
17223
17243
|
for (const entry of entries) {
|
|
17224
17244
|
if (ignoreDirs.includes(entry.name))
|
|
17225
17245
|
continue;
|
|
@@ -123658,7 +123678,7 @@ var init_schemas2 = __esm({
|
|
|
123658
123678
|
|
|
123659
123679
|
// apps/server/dist/services/llm/cli-provider.js
|
|
123660
123680
|
import { spawn as spawn3 } from "node:child_process";
|
|
123661
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
123681
|
+
import { mkdirSync as mkdirSync2, writeFileSync } from "node:fs";
|
|
123662
123682
|
import { join as join8 } from "node:path";
|
|
123663
123683
|
import { tmpdir } from "node:os";
|
|
123664
123684
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
@@ -123721,7 +123741,7 @@ var init_cli_provider = __esm({
|
|
|
123721
123741
|
constructor() {
|
|
123722
123742
|
if (process.env.TRUECOURSE_CLI_DEBUG) {
|
|
123723
123743
|
this.debugDir = join8(tmpdir(), "truecourse-cli-debug");
|
|
123724
|
-
|
|
123744
|
+
mkdirSync2(this.debugDir, { recursive: true });
|
|
123725
123745
|
log.info(`[CLI] Debug output: ${this.debugDir}`);
|
|
123726
123746
|
}
|
|
123727
123747
|
}
|
|
@@ -130710,7 +130730,7 @@ async function runHooksRun() {
|
|
|
130710
130730
|
|
|
130711
130731
|
// tools/cli/src/index.ts
|
|
130712
130732
|
var program2 = new Command();
|
|
130713
|
-
program2.name("truecourse").version("0.5.
|
|
130733
|
+
program2.name("truecourse").version("0.5.3").description("TrueCourse CLI \u2014 analyze your repository and open the dashboard");
|
|
130714
130734
|
var dashboardCmd = program2.command("dashboard").description("Start the TrueCourse dashboard and open it in your browser").option("--reconfigure", "Re-prompt for console vs background service mode").option("--service", "Run as a background service (skips mode prompt)").option("--console", "Run in this terminal (skips mode prompt)").action(async (options) => {
|
|
130715
130735
|
if (options.service && options.console) {
|
|
130716
130736
|
console.error("error: --service and --console are mutually exclusive");
|