@staff0rd/assist 0.657.1 → 0.659.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.
- package/README.md +3 -1
- package/dist/commands/sessions/web/bundle.js +391 -391
- package/dist/index.js +472 -327
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.659.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -561,6 +561,23 @@ function stripLegacyConfigKeys(config) {
|
|
|
561
561
|
// src/shared/types.ts
|
|
562
562
|
import { z as z3 } from "zod";
|
|
563
563
|
|
|
564
|
+
// src/shared/adviceFragmentNames.ts
|
|
565
|
+
var adviceFragmentNames = [
|
|
566
|
+
"assist-global",
|
|
567
|
+
"backlog-ids",
|
|
568
|
+
"backlog-prs",
|
|
569
|
+
"code-comments",
|
|
570
|
+
"drafting-messages",
|
|
571
|
+
"editing-files",
|
|
572
|
+
"filename-convention",
|
|
573
|
+
"jira-context",
|
|
574
|
+
"jira-smart-links",
|
|
575
|
+
"markdown",
|
|
576
|
+
"refactor",
|
|
577
|
+
"settings-json",
|
|
578
|
+
"verify"
|
|
579
|
+
];
|
|
580
|
+
|
|
564
581
|
// src/shared/runConfigSchema.ts
|
|
565
582
|
import { z } from "zod";
|
|
566
583
|
var runParamSchema = z.strictObject({
|
|
@@ -619,8 +636,8 @@ var DEFAULT_BACKUP_DIR = "~/.assist/backups";
|
|
|
619
636
|
var DEFAULT_CLONE_DIR = "~/git";
|
|
620
637
|
var assistConfigShape = {
|
|
621
638
|
advice: z3.strictObject({
|
|
622
|
-
include: z3.array(z3.
|
|
623
|
-
exclude: z3.array(z3.
|
|
639
|
+
include: z3.array(z3.enum(adviceFragmentNames)).default([]),
|
|
640
|
+
exclude: z3.array(z3.enum(adviceFragmentNames)).default([]),
|
|
624
641
|
extra: z3.string().optional(),
|
|
625
642
|
verify: z3.string().optional()
|
|
626
643
|
}).optional(),
|
|
@@ -2013,7 +2030,96 @@ function lint(options2 = {}) {
|
|
|
2013
2030
|
|
|
2014
2031
|
// src/commands/new/registerNew/newCli/index.ts
|
|
2015
2032
|
import { execSync as execSync12 } from "child_process";
|
|
2016
|
-
import { basename as
|
|
2033
|
+
import { basename as basename4, resolve as resolve6 } from "path";
|
|
2034
|
+
|
|
2035
|
+
// src/commands/advise/loadAdviceFragments.ts
|
|
2036
|
+
import { readdirSync, readFileSync as readFileSync10 } from "fs";
|
|
2037
|
+
import { basename as basename2, join as join10 } from "path";
|
|
2038
|
+
|
|
2039
|
+
// src/commands/advise/adviceDir.ts
|
|
2040
|
+
import { existsSync as existsSync13 } from "fs";
|
|
2041
|
+
import { dirname as dirname10, join as join9 } from "path";
|
|
2042
|
+
import { fileURLToPath } from "url";
|
|
2043
|
+
function adviceDir() {
|
|
2044
|
+
let current = dirname10(fileURLToPath(import.meta.url));
|
|
2045
|
+
while (current !== dirname10(current)) {
|
|
2046
|
+
const candidate = join9(current, "claude", "advice");
|
|
2047
|
+
if (existsSync13(candidate)) return candidate;
|
|
2048
|
+
current = dirname10(current);
|
|
2049
|
+
}
|
|
2050
|
+
throw new Error("Could not locate the shipped claude/advice directory");
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
// src/commands/advise/parseAdviceFragment.ts
|
|
2054
|
+
import { parse as parseYaml2 } from "yaml";
|
|
2055
|
+
var frontmatter = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
2056
|
+
function parseAdviceFragment(name, content) {
|
|
2057
|
+
const match = frontmatter.exec(content);
|
|
2058
|
+
if (!match) throw new Error(`Advice fragment ${name} has no frontmatter`);
|
|
2059
|
+
const meta = parseYaml2(match[1]) ?? {};
|
|
2060
|
+
const title = meta.title;
|
|
2061
|
+
const when = meta.when;
|
|
2062
|
+
if (typeof title !== "string" || typeof when !== "string")
|
|
2063
|
+
throw new Error(
|
|
2064
|
+
`Advice fragment ${name} needs a title and a when condition`
|
|
2065
|
+
);
|
|
2066
|
+
return {
|
|
2067
|
+
name,
|
|
2068
|
+
title,
|
|
2069
|
+
when,
|
|
2070
|
+
body: content.slice(match[0].length).trim()
|
|
2071
|
+
};
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
// src/commands/advise/loadAdviceFragments.ts
|
|
2075
|
+
function loadAdviceFragments(dir = adviceDir()) {
|
|
2076
|
+
return readdirSync(dir).filter((file) => file.endsWith(".md")).sort().map(
|
|
2077
|
+
(file) => parseAdviceFragment(
|
|
2078
|
+
basename2(file, ".md"),
|
|
2079
|
+
readFileSync10(join10(dir, file), "utf8")
|
|
2080
|
+
)
|
|
2081
|
+
);
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
// src/commands/verify/reportVerifyProblems.ts
|
|
2085
|
+
function verifySection(label2, entries) {
|
|
2086
|
+
if (entries.length === 0) return void 0;
|
|
2087
|
+
const list5 = entries.sort().map((entry) => ` ${entry}`).join("\n");
|
|
2088
|
+
return `${label2}:
|
|
2089
|
+
${list5}`;
|
|
2090
|
+
}
|
|
2091
|
+
function reportVerifyProblems(problems, success) {
|
|
2092
|
+
const found = problems.filter(
|
|
2093
|
+
(problem) => problem !== void 0
|
|
2094
|
+
);
|
|
2095
|
+
if (found.length > 0) {
|
|
2096
|
+
console.log(found.join("\n\n"));
|
|
2097
|
+
process.exit(1);
|
|
2098
|
+
}
|
|
2099
|
+
console.log(success);
|
|
2100
|
+
process.exit(0);
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
// src/commands/verify/adviceFragments.ts
|
|
2104
|
+
function adviceFragments() {
|
|
2105
|
+
const shipped = new Set(
|
|
2106
|
+
loadAdviceFragments().map((fragment) => fragment.name)
|
|
2107
|
+
);
|
|
2108
|
+
const declared = new Set(adviceFragmentNames);
|
|
2109
|
+
reportVerifyProblems(
|
|
2110
|
+
[
|
|
2111
|
+
verifySection(
|
|
2112
|
+
"Shipped in claude/advice but missing from adviceFragmentNames (add them, or advice.include/exclude cannot name them)",
|
|
2113
|
+
[...shipped].filter((name) => !declared.has(name))
|
|
2114
|
+
),
|
|
2115
|
+
verifySection(
|
|
2116
|
+
"Listed in adviceFragmentNames but no longer shipped in claude/advice (remove them)",
|
|
2117
|
+
[...declared].filter((name) => !shipped.has(name))
|
|
2118
|
+
)
|
|
2119
|
+
],
|
|
2120
|
+
`All ${shipped.size} advice fragments are named in adviceFragmentNames.`
|
|
2121
|
+
);
|
|
2122
|
+
}
|
|
2017
2123
|
|
|
2018
2124
|
// src/commands/verify/blockCodeComments/findComments.ts
|
|
2019
2125
|
import { execSync as execSync4 } from "child_process";
|
|
@@ -2960,12 +3066,12 @@ var adviceConfigHelp = [
|
|
|
2960
3066
|
{
|
|
2961
3067
|
key: "advice.include",
|
|
2962
3068
|
setter: 'assist config set advice.include "refactor"',
|
|
2963
|
-
note: "fragment names included whatever their condition says"
|
|
3069
|
+
note: "fragment names included whatever their condition says; 'assist advise --explain' lists every name"
|
|
2964
3070
|
},
|
|
2965
3071
|
{
|
|
2966
3072
|
key: "advice.exclude",
|
|
2967
3073
|
setter: 'assist config set advice.exclude "jira-context"',
|
|
2968
|
-
note: "fragment names dropped even when their condition matches"
|
|
3074
|
+
note: "fragment names dropped even when their condition matches; 'assist advise --explain' lists every name"
|
|
2969
3075
|
},
|
|
2970
3076
|
{
|
|
2971
3077
|
key: "advice.extra",
|
|
@@ -3573,57 +3679,46 @@ var pendingConfigDocumentation = /* @__PURE__ */ new Set([
|
|
|
3573
3679
|
]);
|
|
3574
3680
|
|
|
3575
3681
|
// src/commands/verify/configKeys.ts
|
|
3576
|
-
function section(label2, keys) {
|
|
3577
|
-
if (keys.length === 0) return void 0;
|
|
3578
|
-
const list5 = keys.sort().map((key) => ` ${key}`).join("\n");
|
|
3579
|
-
return `${label2}:
|
|
3580
|
-
${list5}`;
|
|
3581
|
-
}
|
|
3582
3682
|
function configKeys() {
|
|
3583
3683
|
const schemaKeys = new Set(enumerateConfigLeafKeys(assistConfigSchema));
|
|
3584
3684
|
const documented = getDocumentedConfigKeys();
|
|
3585
3685
|
const pending = pendingConfigDocumentation;
|
|
3586
3686
|
const aggregated = new Set(configHelpEntries.map((entry) => entry.key));
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3687
|
+
reportVerifyProblems(
|
|
3688
|
+
[
|
|
3689
|
+
verifySection(
|
|
3690
|
+
"Config keys documented by no command (surface them with configHelp)",
|
|
3691
|
+
[...schemaKeys].filter(
|
|
3692
|
+
(key) => !documented.has(key) && !pending.has(key)
|
|
3693
|
+
)
|
|
3694
|
+
),
|
|
3695
|
+
verifySection(
|
|
3696
|
+
"Documented config keys not present in assistConfigSchema",
|
|
3697
|
+
[...documented].filter((key) => !schemaKeys.has(key))
|
|
3698
|
+
),
|
|
3699
|
+
verifySection(
|
|
3700
|
+
"Keys now documented but still in pendingConfigDocumentation (remove them)",
|
|
3701
|
+
[...pending].filter((key) => documented.has(key))
|
|
3702
|
+
),
|
|
3703
|
+
verifySection(
|
|
3704
|
+
"pendingConfigDocumentation lists keys not in assistConfigSchema (remove them)",
|
|
3705
|
+
[...pending].filter((key) => !schemaKeys.has(key))
|
|
3706
|
+
),
|
|
3707
|
+
verifySection(
|
|
3708
|
+
"Keys documented by a command but missing from configHelpEntries (add their module to src/commands/configHelpEntries.ts)",
|
|
3709
|
+
[...documented].filter((key) => !aggregated.has(key))
|
|
3710
|
+
),
|
|
3711
|
+
verifySection(
|
|
3712
|
+
"configHelpEntries lists keys no command documents (remove them)",
|
|
3713
|
+
[...aggregated].filter((key) => !documented.has(key))
|
|
3592
3714
|
)
|
|
3593
|
-
|
|
3594
|
-
section(
|
|
3595
|
-
"Documented config keys not present in assistConfigSchema",
|
|
3596
|
-
[...documented].filter((key) => !schemaKeys.has(key))
|
|
3597
|
-
),
|
|
3598
|
-
section(
|
|
3599
|
-
"Keys now documented but still in pendingConfigDocumentation (remove them)",
|
|
3600
|
-
[...pending].filter((key) => documented.has(key))
|
|
3601
|
-
),
|
|
3602
|
-
section(
|
|
3603
|
-
"pendingConfigDocumentation lists keys not in assistConfigSchema (remove them)",
|
|
3604
|
-
[...pending].filter((key) => !schemaKeys.has(key))
|
|
3605
|
-
),
|
|
3606
|
-
section(
|
|
3607
|
-
"Keys documented by a command but missing from configHelpEntries (add their module to src/commands/configHelpEntries.ts)",
|
|
3608
|
-
[...documented].filter((key) => !aggregated.has(key))
|
|
3609
|
-
),
|
|
3610
|
-
section(
|
|
3611
|
-
"configHelpEntries lists keys no command documents (remove them)",
|
|
3612
|
-
[...aggregated].filter((key) => !documented.has(key))
|
|
3613
|
-
)
|
|
3614
|
-
].filter((problem) => problem !== void 0);
|
|
3615
|
-
if (problems.length > 0) {
|
|
3616
|
-
console.log(problems.join("\n\n"));
|
|
3617
|
-
process.exit(1);
|
|
3618
|
-
}
|
|
3619
|
-
console.log(
|
|
3715
|
+
],
|
|
3620
3716
|
`All ${schemaKeys.size} config keys are surfaced in --help or pending documentation.`
|
|
3621
3717
|
);
|
|
3622
|
-
process.exit(0);
|
|
3623
3718
|
}
|
|
3624
3719
|
|
|
3625
3720
|
// src/commands/verify/forbiddenStrings/index.ts
|
|
3626
|
-
import { existsSync as
|
|
3721
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
|
|
3627
3722
|
|
|
3628
3723
|
// src/commands/verify/forbiddenStrings/findForbiddenStrings.ts
|
|
3629
3724
|
import { minimatch as minimatch2 } from "minimatch";
|
|
@@ -3664,13 +3759,13 @@ function forbiddenStrings() {
|
|
|
3664
3759
|
const cache5 = /* @__PURE__ */ new Map();
|
|
3665
3760
|
const readJson = (file) => {
|
|
3666
3761
|
if (cache5.has(file)) return cache5.get(file);
|
|
3667
|
-
if (!
|
|
3762
|
+
if (!existsSync14(file)) {
|
|
3668
3763
|
console.log(`Forbidden-strings file not found: ${file}`);
|
|
3669
3764
|
process.exit(1);
|
|
3670
3765
|
}
|
|
3671
3766
|
let parsed;
|
|
3672
3767
|
try {
|
|
3673
|
-
parsed = JSON.parse(
|
|
3768
|
+
parsed = JSON.parse(readFileSync11(file, "utf8"));
|
|
3674
3769
|
} catch (error) {
|
|
3675
3770
|
console.log(`Could not parse ${file}: ${error.message}`);
|
|
3676
3771
|
process.exit(1);
|
|
@@ -3743,7 +3838,7 @@ Total: ${lines2.length} hardcoded color(s)`);
|
|
|
3743
3838
|
import * as path20 from "path";
|
|
3744
3839
|
|
|
3745
3840
|
// src/shared/resolveRunConfigs.ts
|
|
3746
|
-
import { dirname as
|
|
3841
|
+
import { dirname as dirname11, relative, resolve as resolve4 } from "path";
|
|
3747
3842
|
|
|
3748
3843
|
// src/shared/assertNoDuplicateRunNames.ts
|
|
3749
3844
|
function findDuplicateNames(configs) {
|
|
@@ -3765,14 +3860,14 @@ function assertNoDuplicateRunNames(configs) {
|
|
|
3765
3860
|
}
|
|
3766
3861
|
|
|
3767
3862
|
// src/shared/findLinkedConfigPath.ts
|
|
3768
|
-
import { existsSync as
|
|
3769
|
-
import { join as
|
|
3863
|
+
import { existsSync as existsSync15 } from "fs";
|
|
3864
|
+
import { join as join11, resolve as resolve2 } from "path";
|
|
3770
3865
|
function findLinkedConfigPath(linkPath, fromDir) {
|
|
3771
3866
|
const resolved = resolve2(fromDir, linkPath);
|
|
3772
|
-
const claudePath =
|
|
3773
|
-
if (
|
|
3774
|
-
const rootPath =
|
|
3775
|
-
if (
|
|
3867
|
+
const claudePath = join11(resolved, ".claude", "assist.yml");
|
|
3868
|
+
if (existsSync15(claudePath)) return claudePath;
|
|
3869
|
+
const rootPath = join11(resolved, "assist.yml");
|
|
3870
|
+
if (existsSync15(rootPath)) return rootPath;
|
|
3776
3871
|
throw new Error(`No assist.yml found in linked project: ${resolved}`);
|
|
3777
3872
|
}
|
|
3778
3873
|
|
|
@@ -3814,7 +3909,7 @@ function loadAndResolveLink(linkPath, configDir, ctx) {
|
|
|
3814
3909
|
const entries = loadLinkedEntries(configPath, ctx.visited);
|
|
3815
3910
|
const defaultCwd = relativeToRoot(ctx, resolve4(configDir, linkPath));
|
|
3816
3911
|
return setDefaultCwd(
|
|
3817
|
-
resolveRecursive(entries,
|
|
3912
|
+
resolveRecursive(entries, dirname11(configPath), ctx),
|
|
3818
3913
|
defaultCwd
|
|
3819
3914
|
);
|
|
3820
3915
|
}
|
|
@@ -3841,12 +3936,12 @@ function resolveLocalCwd(config, configDir, ctx) {
|
|
|
3841
3936
|
}
|
|
3842
3937
|
|
|
3843
3938
|
// src/shared/findRepoRoot.ts
|
|
3844
|
-
import { existsSync as
|
|
3939
|
+
import { existsSync as existsSync16 } from "fs";
|
|
3845
3940
|
import path19 from "path";
|
|
3846
3941
|
function findRepoRoot(dir) {
|
|
3847
3942
|
let current = dir;
|
|
3848
3943
|
while (current !== path19.dirname(current)) {
|
|
3849
|
-
if (
|
|
3944
|
+
if (existsSync16(path19.join(current, ".git"))) {
|
|
3850
3945
|
return current;
|
|
3851
3946
|
}
|
|
3852
3947
|
current = path19.dirname(current);
|
|
@@ -3917,9 +4012,9 @@ function list() {
|
|
|
3917
4012
|
}
|
|
3918
4013
|
|
|
3919
4014
|
// src/commands/verify/migrations/index.ts
|
|
3920
|
-
import { readFileSync as
|
|
4015
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
3921
4016
|
import path21 from "path";
|
|
3922
|
-
import { fileURLToPath } from "url";
|
|
4017
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3923
4018
|
|
|
3924
4019
|
// src/shared/db/migrations/migration0001Baseline.ts
|
|
3925
4020
|
var sql = `
|
|
@@ -4267,15 +4362,15 @@ function checkSequential(migrations3, files) {
|
|
|
4267
4362
|
}
|
|
4268
4363
|
|
|
4269
4364
|
// src/commands/verify/migrations/listMigrationFiles.ts
|
|
4270
|
-
import { readdirSync } from "fs";
|
|
4365
|
+
import { readdirSync as readdirSync2 } from "fs";
|
|
4271
4366
|
var MIGRATION_FILE2 = /^migration\d+[A-Za-z0-9]*\.ts$/;
|
|
4272
4367
|
function listMigrationFiles(dir) {
|
|
4273
|
-
return
|
|
4368
|
+
return readdirSync2(dir).filter((file) => MIGRATION_FILE2.test(file));
|
|
4274
4369
|
}
|
|
4275
4370
|
|
|
4276
4371
|
// src/commands/verify/migrations/readBaselineMigrations.ts
|
|
4277
4372
|
import { execSync as execSync6 } from "child_process";
|
|
4278
|
-
import { basename as
|
|
4373
|
+
import { basename as basename3 } from "path";
|
|
4279
4374
|
var MIGRATION_FILE3 = /^migration\d+[A-Za-z0-9]*\.ts$/;
|
|
4280
4375
|
function readBaselineMigrations(repoRelativeDir, ref) {
|
|
4281
4376
|
const baseline = /* @__PURE__ */ new Map();
|
|
@@ -4288,7 +4383,7 @@ function readBaselineMigrations(repoRelativeDir, ref) {
|
|
|
4288
4383
|
} catch {
|
|
4289
4384
|
return baseline;
|
|
4290
4385
|
}
|
|
4291
|
-
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path91) => MIGRATION_FILE3.test(
|
|
4386
|
+
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path91) => MIGRATION_FILE3.test(basename3(path91)));
|
|
4292
4387
|
for (const path91 of paths) {
|
|
4293
4388
|
try {
|
|
4294
4389
|
const content = execSync6(`git show "${ref}:${path91}"`, {
|
|
@@ -4296,7 +4391,7 @@ function readBaselineMigrations(repoRelativeDir, ref) {
|
|
|
4296
4391
|
maxBuffer: 16 * 1024 * 1024,
|
|
4297
4392
|
stdio: ["pipe", "pipe", "pipe"]
|
|
4298
4393
|
});
|
|
4299
|
-
baseline.set(
|
|
4394
|
+
baseline.set(basename3(path91), content);
|
|
4300
4395
|
} catch {
|
|
4301
4396
|
}
|
|
4302
4397
|
}
|
|
@@ -4338,7 +4433,7 @@ function resolveBaselineRef() {
|
|
|
4338
4433
|
var REPO_RELATIVE_DIR = "src/shared/db/migrations";
|
|
4339
4434
|
function migrationsDir() {
|
|
4340
4435
|
return path21.resolve(
|
|
4341
|
-
path21.dirname(
|
|
4436
|
+
path21.dirname(fileURLToPath2(import.meta.url)),
|
|
4342
4437
|
"../../../shared/db/migrations"
|
|
4343
4438
|
);
|
|
4344
4439
|
}
|
|
@@ -4356,7 +4451,7 @@ function migrations2() {
|
|
|
4356
4451
|
if (ref) {
|
|
4357
4452
|
const baseline = readBaselineMigrations(REPO_RELATIVE_DIR, ref);
|
|
4358
4453
|
const current = new Map(
|
|
4359
|
-
files.map((file) => [file,
|
|
4454
|
+
files.map((file) => [file, readFileSync12(path21.join(dir, file), "utf8")])
|
|
4360
4455
|
);
|
|
4361
4456
|
for (const finding of checkAppendOnly(baseline, current)) {
|
|
4362
4457
|
problems.push(
|
|
@@ -4415,15 +4510,15 @@ import * as net from "net";
|
|
|
4415
4510
|
|
|
4416
4511
|
// src/commands/sessions/daemon/daemonPaths.ts
|
|
4417
4512
|
import { homedir as homedir2 } from "os";
|
|
4418
|
-
import { join as
|
|
4419
|
-
var DAEMON_DIR =
|
|
4513
|
+
import { join as join12 } from "path";
|
|
4514
|
+
var DAEMON_DIR = join12(homedir2(), ".assist", "daemon");
|
|
4420
4515
|
var daemonPaths = {
|
|
4421
4516
|
dir: DAEMON_DIR,
|
|
4422
|
-
socket: process.platform === "win32" ? String.raw`\\.\pipe\assist-sessions-daemon` :
|
|
4423
|
-
log:
|
|
4424
|
-
pid:
|
|
4425
|
-
spawnLock:
|
|
4426
|
-
hooksSettings:
|
|
4517
|
+
socket: process.platform === "win32" ? String.raw`\\.\pipe\assist-sessions-daemon` : join12(DAEMON_DIR, "daemon.sock"),
|
|
4518
|
+
log: join12(DAEMON_DIR, "daemon.log"),
|
|
4519
|
+
pid: join12(DAEMON_DIR, "daemon.pid"),
|
|
4520
|
+
spawnLock: join12(DAEMON_DIR, "spawn.lock"),
|
|
4521
|
+
hooksSettings: join12(DAEMON_DIR, "hooks-settings.json")
|
|
4427
4522
|
};
|
|
4428
4523
|
|
|
4429
4524
|
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
@@ -4731,7 +4826,7 @@ program.parse();
|
|
|
4731
4826
|
|
|
4732
4827
|
// src/commands/new/registerNew/newCli/index.ts
|
|
4733
4828
|
async function newCli() {
|
|
4734
|
-
const name =
|
|
4829
|
+
const name = basename4(resolve6("."));
|
|
4735
4830
|
initGit();
|
|
4736
4831
|
initPackageJson(name);
|
|
4737
4832
|
console.log("Installing dependencies...");
|
|
@@ -4746,7 +4841,7 @@ async function newCli() {
|
|
|
4746
4841
|
|
|
4747
4842
|
// src/commands/new/registerNew/newProject.ts
|
|
4748
4843
|
import { execSync as execSync14 } from "child_process";
|
|
4749
|
-
import { existsSync as
|
|
4844
|
+
import { existsSync as existsSync18, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "fs";
|
|
4750
4845
|
|
|
4751
4846
|
// src/commands/deploy/init/index.ts
|
|
4752
4847
|
import { execSync as execSync13 } from "child_process";
|
|
@@ -4754,33 +4849,33 @@ import chalk27 from "chalk";
|
|
|
4754
4849
|
import enquirer3 from "enquirer";
|
|
4755
4850
|
|
|
4756
4851
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
4757
|
-
import { existsSync as
|
|
4758
|
-
import { dirname as
|
|
4759
|
-
import { fileURLToPath as
|
|
4852
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync3, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
|
|
4853
|
+
import { dirname as dirname13, join as join13 } from "path";
|
|
4854
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4760
4855
|
import chalk26 from "chalk";
|
|
4761
4856
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
4762
|
-
var __dirname2 =
|
|
4857
|
+
var __dirname2 = dirname13(fileURLToPath3(import.meta.url));
|
|
4763
4858
|
function getExistingSiteId() {
|
|
4764
|
-
if (!
|
|
4859
|
+
if (!existsSync17(WORKFLOW_PATH)) {
|
|
4765
4860
|
return null;
|
|
4766
4861
|
}
|
|
4767
|
-
const content =
|
|
4862
|
+
const content = readFileSync13(WORKFLOW_PATH, "utf8");
|
|
4768
4863
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
4769
4864
|
return match ? match[1] : null;
|
|
4770
4865
|
}
|
|
4771
4866
|
function getTemplateContent(siteId) {
|
|
4772
|
-
const templatePath =
|
|
4773
|
-
const template =
|
|
4867
|
+
const templatePath = join13(__dirname2, "commands/deploy/build.yml");
|
|
4868
|
+
const template = readFileSync13(templatePath, "utf8");
|
|
4774
4869
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
4775
4870
|
}
|
|
4776
4871
|
async function updateWorkflow(siteId) {
|
|
4777
4872
|
const newContent = getTemplateContent(siteId);
|
|
4778
4873
|
const workflowDir = ".github/workflows";
|
|
4779
|
-
if (!
|
|
4874
|
+
if (!existsSync17(workflowDir)) {
|
|
4780
4875
|
mkdirSync3(workflowDir, { recursive: true });
|
|
4781
4876
|
}
|
|
4782
|
-
if (
|
|
4783
|
-
const oldContent =
|
|
4877
|
+
if (existsSync17(WORKFLOW_PATH)) {
|
|
4878
|
+
const oldContent = readFileSync13(WORKFLOW_PATH, "utf8");
|
|
4784
4879
|
if (oldContent === newContent) {
|
|
4785
4880
|
console.log(chalk26.green("build.yml is already up to date"));
|
|
4786
4881
|
return;
|
|
@@ -4874,11 +4969,11 @@ async function newProject() {
|
|
|
4874
4969
|
}
|
|
4875
4970
|
function addViteBaseConfig() {
|
|
4876
4971
|
const viteConfigPath = "vite.config.ts";
|
|
4877
|
-
if (!
|
|
4972
|
+
if (!existsSync18(viteConfigPath)) {
|
|
4878
4973
|
console.log("No vite.config.ts found, skipping base config");
|
|
4879
4974
|
return;
|
|
4880
4975
|
}
|
|
4881
|
-
const content =
|
|
4976
|
+
const content = readFileSync14(viteConfigPath, "utf8");
|
|
4882
4977
|
if (content.includes("base:")) {
|
|
4883
4978
|
console.log("vite.config.ts already has base config");
|
|
4884
4979
|
return;
|
|
@@ -5019,28 +5114,45 @@ async function notify() {
|
|
|
5019
5114
|
console.log(`Notification sent: ${notification_type} for ${projectName}`);
|
|
5020
5115
|
}
|
|
5021
5116
|
|
|
5022
|
-
// src/
|
|
5117
|
+
// src/lib/renderLineChart.ts
|
|
5118
|
+
import * as fs16 from "fs";
|
|
5119
|
+
import * as tty from "tty";
|
|
5023
5120
|
import blessed from "blessed";
|
|
5024
5121
|
import contrib from "blessed-contrib";
|
|
5025
|
-
|
|
5122
|
+
var keyboardInput = () => {
|
|
5123
|
+
if (process.stdin.isTTY) return void 0;
|
|
5124
|
+
try {
|
|
5125
|
+
return new tty.ReadStream(fs16.openSync("/dev/tty", "r"));
|
|
5126
|
+
} catch {
|
|
5127
|
+
return void 0;
|
|
5128
|
+
}
|
|
5129
|
+
};
|
|
5130
|
+
function renderLineChart({
|
|
5131
|
+
title,
|
|
5132
|
+
label: label2,
|
|
5133
|
+
seriesTitle,
|
|
5134
|
+
labels,
|
|
5135
|
+
values,
|
|
5136
|
+
wholeNumbersOnly = false
|
|
5137
|
+
}) {
|
|
5138
|
+
const input = keyboardInput();
|
|
5026
5139
|
const screen = blessed.screen({
|
|
5027
5140
|
smartCSR: true,
|
|
5028
|
-
title
|
|
5141
|
+
title,
|
|
5142
|
+
input
|
|
5029
5143
|
});
|
|
5030
5144
|
const grid = new contrib.grid({ rows: 1, cols: 1, screen });
|
|
5031
|
-
const labels = data.map((d) => d.date.slice(5));
|
|
5032
|
-
const values = data.map((d) => d.count);
|
|
5033
5145
|
const line = grid.set(0, 0, 1, 1, contrib.line, {
|
|
5034
|
-
label: `
|
|
5146
|
+
label: ` ${label2} (press q to close) `,
|
|
5035
5147
|
showLegend: true,
|
|
5036
|
-
legend: { width: 12 },
|
|
5148
|
+
legend: { width: Math.max(12, seriesTitle.length + 2) },
|
|
5037
5149
|
xLabelPadding: 3,
|
|
5038
5150
|
xPadding: 5,
|
|
5039
|
-
wholeNumbersOnly
|
|
5151
|
+
wholeNumbersOnly
|
|
5040
5152
|
});
|
|
5041
5153
|
line.setData([
|
|
5042
5154
|
{
|
|
5043
|
-
title:
|
|
5155
|
+
title: seriesTitle,
|
|
5044
5156
|
x: labels,
|
|
5045
5157
|
y: values,
|
|
5046
5158
|
style: { line: "green" }
|
|
@@ -5048,6 +5160,7 @@ function activityChart(data, range) {
|
|
|
5048
5160
|
]);
|
|
5049
5161
|
screen.key(["q", "C-c", "escape"], () => {
|
|
5050
5162
|
screen.destroy();
|
|
5163
|
+
input?.destroy();
|
|
5051
5164
|
});
|
|
5052
5165
|
screen.render();
|
|
5053
5166
|
}
|
|
@@ -5107,7 +5220,14 @@ async function activity(options2) {
|
|
|
5107
5220
|
}
|
|
5108
5221
|
const weeklyData = [...weekly.entries()].map(([date, count8]) => ({ date, count: count8 })).sort((a, b) => a.date.localeCompare(b.date));
|
|
5109
5222
|
const until = data[data.length - 1].date;
|
|
5110
|
-
|
|
5223
|
+
renderLineChart({
|
|
5224
|
+
title: "Commit Activity",
|
|
5225
|
+
label: `Commits per week \xB7 ${since} \u2192 ${until}`,
|
|
5226
|
+
seriesTitle: "Commits",
|
|
5227
|
+
labels: weeklyData.map((d) => d.date.slice(5)),
|
|
5228
|
+
values: weeklyData.map((d) => d.count),
|
|
5229
|
+
wholeNumbersOnly: true
|
|
5230
|
+
});
|
|
5111
5231
|
}
|
|
5112
5232
|
|
|
5113
5233
|
// src/commands/registerActivity.ts
|
|
@@ -5126,55 +5246,6 @@ function adviceContextFor(cwd) {
|
|
|
5126
5246
|
};
|
|
5127
5247
|
}
|
|
5128
5248
|
|
|
5129
|
-
// src/commands/advise/loadAdviceFragments.ts
|
|
5130
|
-
import { readdirSync as readdirSync2, readFileSync as readFileSync14 } from "fs";
|
|
5131
|
-
import { basename as basename4, join as join13 } from "path";
|
|
5132
|
-
|
|
5133
|
-
// src/commands/advise/adviceDir.ts
|
|
5134
|
-
import { existsSync as existsSync18 } from "fs";
|
|
5135
|
-
import { dirname as dirname13, join as join12 } from "path";
|
|
5136
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
5137
|
-
function adviceDir() {
|
|
5138
|
-
let current = dirname13(fileURLToPath3(import.meta.url));
|
|
5139
|
-
while (current !== dirname13(current)) {
|
|
5140
|
-
const candidate = join12(current, "claude", "advice");
|
|
5141
|
-
if (existsSync18(candidate)) return candidate;
|
|
5142
|
-
current = dirname13(current);
|
|
5143
|
-
}
|
|
5144
|
-
throw new Error("Could not locate the shipped claude/advice directory");
|
|
5145
|
-
}
|
|
5146
|
-
|
|
5147
|
-
// src/commands/advise/parseAdviceFragment.ts
|
|
5148
|
-
import { parse as parseYaml2 } from "yaml";
|
|
5149
|
-
var frontmatter = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
5150
|
-
function parseAdviceFragment(name, content) {
|
|
5151
|
-
const match = frontmatter.exec(content);
|
|
5152
|
-
if (!match) throw new Error(`Advice fragment ${name} has no frontmatter`);
|
|
5153
|
-
const meta = parseYaml2(match[1]) ?? {};
|
|
5154
|
-
const title = meta.title;
|
|
5155
|
-
const when = meta.when;
|
|
5156
|
-
if (typeof title !== "string" || typeof when !== "string")
|
|
5157
|
-
throw new Error(
|
|
5158
|
-
`Advice fragment ${name} needs a title and a when condition`
|
|
5159
|
-
);
|
|
5160
|
-
return {
|
|
5161
|
-
name,
|
|
5162
|
-
title,
|
|
5163
|
-
when,
|
|
5164
|
-
body: content.slice(match[0].length).trim()
|
|
5165
|
-
};
|
|
5166
|
-
}
|
|
5167
|
-
|
|
5168
|
-
// src/commands/advise/loadAdviceFragments.ts
|
|
5169
|
-
function loadAdviceFragments(dir = adviceDir()) {
|
|
5170
|
-
return readdirSync2(dir).filter((file) => file.endsWith(".md")).sort().map(
|
|
5171
|
-
(file) => parseAdviceFragment(
|
|
5172
|
-
basename4(file, ".md"),
|
|
5173
|
-
readFileSync14(join13(dir, file), "utf8")
|
|
5174
|
-
)
|
|
5175
|
-
);
|
|
5176
|
-
}
|
|
5177
|
-
|
|
5178
5249
|
// src/commands/advise/verifyRunCommandNames.ts
|
|
5179
5250
|
function verifyRunCommandNames({
|
|
5180
5251
|
config,
|
|
@@ -5243,9 +5314,11 @@ var adviceConditions = {
|
|
|
5243
5314
|
// src/commands/advise/selectAdvice.ts
|
|
5244
5315
|
function decide(fragment, context) {
|
|
5245
5316
|
const advice = context.config.advice;
|
|
5246
|
-
|
|
5317
|
+
const exclude = advice?.exclude ?? [];
|
|
5318
|
+
const include = advice?.include ?? [];
|
|
5319
|
+
if (exclude.includes(fragment.name))
|
|
5247
5320
|
return { fragment, included: false, reason: "excluded by advice.exclude" };
|
|
5248
|
-
if (
|
|
5321
|
+
if (include.includes(fragment.name))
|
|
5249
5322
|
return { fragment, included: true, reason: "included by advice.include" };
|
|
5250
5323
|
const condition = adviceConditions[fragment.when];
|
|
5251
5324
|
if (!condition)
|
|
@@ -6337,6 +6410,72 @@ function registerBackup(program2) {
|
|
|
6337
6410
|
configHelp(backupCommand, backupConfigHelp);
|
|
6338
6411
|
}
|
|
6339
6412
|
|
|
6413
|
+
// src/commands/chart/parseChartSeries.ts
|
|
6414
|
+
function parseChartSeries(lines2) {
|
|
6415
|
+
const points = [];
|
|
6416
|
+
for (const line of lines2) {
|
|
6417
|
+
const trimmed = line.trim();
|
|
6418
|
+
if (trimmed === "") continue;
|
|
6419
|
+
const parts = trimmed.split(/[,\t ]+/).filter((part) => part !== "");
|
|
6420
|
+
if (parts.length < 2) {
|
|
6421
|
+
throw new Error(`Expected a label and a value, got: ${trimmed}`);
|
|
6422
|
+
}
|
|
6423
|
+
const label2 = parts.slice(0, -1).join(" ");
|
|
6424
|
+
const raw = parts[parts.length - 1];
|
|
6425
|
+
const value = Number(raw);
|
|
6426
|
+
if (!Number.isFinite(value)) {
|
|
6427
|
+
throw new Error(`Value "${raw}" is not numeric, on line: ${trimmed}`);
|
|
6428
|
+
}
|
|
6429
|
+
points.push({ label: label2, value });
|
|
6430
|
+
}
|
|
6431
|
+
return points;
|
|
6432
|
+
}
|
|
6433
|
+
|
|
6434
|
+
// src/commands/chart/readStdinLines.ts
|
|
6435
|
+
import * as readline2 from "readline";
|
|
6436
|
+
async function readStdinLines() {
|
|
6437
|
+
const rl = readline2.createInterface({
|
|
6438
|
+
input: process.stdin,
|
|
6439
|
+
terminal: false
|
|
6440
|
+
});
|
|
6441
|
+
const lines2 = [];
|
|
6442
|
+
for await (const line of rl) {
|
|
6443
|
+
lines2.push(line);
|
|
6444
|
+
}
|
|
6445
|
+
return lines2;
|
|
6446
|
+
}
|
|
6447
|
+
|
|
6448
|
+
// src/commands/chart.ts
|
|
6449
|
+
async function chart(options2) {
|
|
6450
|
+
const lines2 = await readStdinLines();
|
|
6451
|
+
let points;
|
|
6452
|
+
try {
|
|
6453
|
+
points = parseChartSeries(lines2);
|
|
6454
|
+
} catch (error) {
|
|
6455
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
6456
|
+
process.exit(1);
|
|
6457
|
+
}
|
|
6458
|
+
if (points.length < 2) {
|
|
6459
|
+
console.log("Not enough data points to chart.");
|
|
6460
|
+
return;
|
|
6461
|
+
}
|
|
6462
|
+
const title = options2.title ?? "Chart";
|
|
6463
|
+
renderLineChart({
|
|
6464
|
+
title,
|
|
6465
|
+
label: title,
|
|
6466
|
+
seriesTitle: title,
|
|
6467
|
+
labels: points.map((p) => p.label),
|
|
6468
|
+
values: points.map((p) => p.value)
|
|
6469
|
+
});
|
|
6470
|
+
}
|
|
6471
|
+
|
|
6472
|
+
// src/commands/registerChart.ts
|
|
6473
|
+
function registerChart(program2) {
|
|
6474
|
+
program2.command("chart").description(
|
|
6475
|
+
"Chart a label/value series read from stdin, one pair per line (comma, tab or whitespace separated)"
|
|
6476
|
+
).option("--title <title>", "Chart title").action(chart);
|
|
6477
|
+
}
|
|
6478
|
+
|
|
6340
6479
|
// src/commands/backlog/next.ts
|
|
6341
6480
|
import chalk47 from "chalk";
|
|
6342
6481
|
import enquirer5 from "enquirer";
|
|
@@ -8631,12 +8770,12 @@ import chalk44 from "chalk";
|
|
|
8631
8770
|
import * as path29 from "path";
|
|
8632
8771
|
|
|
8633
8772
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
8634
|
-
import * as
|
|
8773
|
+
import * as fs21 from "fs";
|
|
8635
8774
|
import * as os3 from "os";
|
|
8636
8775
|
import * as path28 from "path";
|
|
8637
8776
|
|
|
8638
8777
|
// src/commands/sessions/shared/codex/discoverCodexRolloutPaths.ts
|
|
8639
|
-
import * as
|
|
8778
|
+
import * as fs17 from "fs";
|
|
8640
8779
|
import * as path25 from "path";
|
|
8641
8780
|
|
|
8642
8781
|
// src/commands/sessions/shared/codex/codexSessionsDir.ts
|
|
@@ -8661,7 +8800,7 @@ async function discoverCodexRolloutPaths() {
|
|
|
8661
8800
|
async function collect(dir, depth) {
|
|
8662
8801
|
let entries;
|
|
8663
8802
|
try {
|
|
8664
|
-
entries = await
|
|
8803
|
+
entries = await fs17.promises.readdir(dir, { withFileTypes: true });
|
|
8665
8804
|
} catch {
|
|
8666
8805
|
return [];
|
|
8667
8806
|
}
|
|
@@ -8677,7 +8816,7 @@ async function collectEntry(dir, entry, depth) {
|
|
|
8677
8816
|
}
|
|
8678
8817
|
|
|
8679
8818
|
// src/commands/sessions/shared/codex/parseCodexSessionFile.ts
|
|
8680
|
-
import * as
|
|
8819
|
+
import * as fs19 from "fs";
|
|
8681
8820
|
import * as path26 from "path";
|
|
8682
8821
|
|
|
8683
8822
|
// src/commands/sessions/shared/backlogRunMarkers.ts
|
|
@@ -8769,12 +8908,12 @@ function firstUserMessage(entry) {
|
|
|
8769
8908
|
}
|
|
8770
8909
|
|
|
8771
8910
|
// src/commands/sessions/shared/codex/readCodexHeadLines.ts
|
|
8772
|
-
import * as
|
|
8773
|
-
import * as
|
|
8911
|
+
import * as fs18 from "fs";
|
|
8912
|
+
import * as readline3 from "readline";
|
|
8774
8913
|
var DEFAULT_MAX_LINES = 80;
|
|
8775
8914
|
async function readCodexHeadLines(filePath, maxLines = DEFAULT_MAX_LINES) {
|
|
8776
|
-
const stream =
|
|
8777
|
-
const reader =
|
|
8915
|
+
const stream = fs18.createReadStream(filePath, { encoding: "utf8" });
|
|
8916
|
+
const reader = readline3.createInterface({ input: stream });
|
|
8778
8917
|
const lines2 = [];
|
|
8779
8918
|
try {
|
|
8780
8919
|
for await (const line of reader) {
|
|
@@ -8812,7 +8951,7 @@ async function parseCodexSessionFile(filePath) {
|
|
|
8812
8951
|
}
|
|
8813
8952
|
}
|
|
8814
8953
|
async function mtime(filePath) {
|
|
8815
|
-
return (await
|
|
8954
|
+
return (await fs19.promises.stat(filePath)).mtime.toISOString();
|
|
8816
8955
|
}
|
|
8817
8956
|
|
|
8818
8957
|
// src/commands/sessions/shared/codex/discoverCodexSessions.ts
|
|
@@ -8823,7 +8962,7 @@ async function discoverCodexSessions() {
|
|
|
8823
8962
|
}
|
|
8824
8963
|
|
|
8825
8964
|
// src/commands/sessions/shared/parseSessionFile.ts
|
|
8826
|
-
import * as
|
|
8965
|
+
import * as fs20 from "fs";
|
|
8827
8966
|
|
|
8828
8967
|
// src/commands/sessions/shared/extractSessionMeta.ts
|
|
8829
8968
|
function extractSessionMeta(lines2) {
|
|
@@ -8894,10 +9033,10 @@ function dirNameToProject(filePath) {
|
|
|
8894
9033
|
async function parseSessionFile(filePath, origin = "wsl") {
|
|
8895
9034
|
let handle;
|
|
8896
9035
|
try {
|
|
8897
|
-
handle = await
|
|
9036
|
+
handle = await fs20.promises.open(filePath, "r");
|
|
8898
9037
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
8899
9038
|
if (!meta.sessionId) return null;
|
|
8900
|
-
const timestamp6 = meta.timestamp || (await
|
|
9039
|
+
const timestamp6 = meta.timestamp || (await fs20.promises.stat(filePath)).mtime.toISOString();
|
|
8901
9040
|
return {
|
|
8902
9041
|
sessionId: meta.sessionId,
|
|
8903
9042
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
@@ -8934,7 +9073,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
8934
9073
|
sessionRoots().map(async ({ dir, origin }) => {
|
|
8935
9074
|
let projectDirs;
|
|
8936
9075
|
try {
|
|
8937
|
-
projectDirs = await
|
|
9076
|
+
projectDirs = await fs21.promises.readdir(dir);
|
|
8938
9077
|
} catch {
|
|
8939
9078
|
return;
|
|
8940
9079
|
}
|
|
@@ -8943,7 +9082,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
8943
9082
|
const dirPath = path28.join(dir, dirName);
|
|
8944
9083
|
let entries;
|
|
8945
9084
|
try {
|
|
8946
|
-
entries = await
|
|
9085
|
+
entries = await fs21.promises.readdir(dirPath);
|
|
8947
9086
|
} catch {
|
|
8948
9087
|
return;
|
|
8949
9088
|
}
|
|
@@ -9824,7 +9963,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
9824
9963
|
import {
|
|
9825
9964
|
closeSync,
|
|
9826
9965
|
mkdirSync as mkdirSync10,
|
|
9827
|
-
openSync,
|
|
9966
|
+
openSync as openSync2,
|
|
9828
9967
|
statSync as statSync2,
|
|
9829
9968
|
unlinkSync as unlinkSync5,
|
|
9830
9969
|
writeSync
|
|
@@ -9864,7 +10003,7 @@ function acquireSpawnLock() {
|
|
|
9864
10003
|
}
|
|
9865
10004
|
function tryCreateLock() {
|
|
9866
10005
|
try {
|
|
9867
|
-
const fd =
|
|
10006
|
+
const fd = openSync2(daemonPaths.spawnLock, "wx");
|
|
9868
10007
|
writeSync(fd, String(process.pid));
|
|
9869
10008
|
closeSync(fd);
|
|
9870
10009
|
return true;
|
|
@@ -9886,7 +10025,7 @@ function releaseSpawnLock() {
|
|
|
9886
10025
|
}
|
|
9887
10026
|
}
|
|
9888
10027
|
function spawnDaemon(reason4) {
|
|
9889
|
-
const log2 =
|
|
10028
|
+
const log2 = openSync2(daemonPaths.log, "a");
|
|
9890
10029
|
const child = spawn4(process.execPath, [process.argv[1], "daemon", "run"], {
|
|
9891
10030
|
detached: true,
|
|
9892
10031
|
windowsHide: true,
|
|
@@ -13544,7 +13683,7 @@ var handleRequest = createFallbackHandler(
|
|
|
13544
13683
|
);
|
|
13545
13684
|
|
|
13546
13685
|
// src/commands/sessions/web/handleSocket.ts
|
|
13547
|
-
import { createInterface as
|
|
13686
|
+
import { createInterface as createInterface4 } from "readline";
|
|
13548
13687
|
var CWD_DEFAULTED_TYPES = /* @__PURE__ */ new Set(["create", "create-run", "create-assist"]);
|
|
13549
13688
|
function handleSocket(ws, ctx) {
|
|
13550
13689
|
const connection = openDaemonConnection(ws, ctx);
|
|
@@ -13572,7 +13711,7 @@ async function openDaemonConnection(ws, ctx) {
|
|
|
13572
13711
|
}
|
|
13573
13712
|
}
|
|
13574
13713
|
function relayDaemonLines(conn, ws, repoCwd) {
|
|
13575
|
-
const lines2 =
|
|
13714
|
+
const lines2 = createInterface4({ input: conn });
|
|
13576
13715
|
lines2.on("error", () => {
|
|
13577
13716
|
});
|
|
13578
13717
|
lines2.on("line", (line) => {
|
|
@@ -13836,7 +13975,7 @@ function installRestartMenu(options2 = {}) {
|
|
|
13836
13975
|
}
|
|
13837
13976
|
|
|
13838
13977
|
// src/commands/sessions/web/streamDaemonLogs.ts
|
|
13839
|
-
import { createInterface as
|
|
13978
|
+
import { createInterface as createInterface5 } from "readline";
|
|
13840
13979
|
var RECONNECT_MS = 3e3;
|
|
13841
13980
|
function streamDaemonLogs() {
|
|
13842
13981
|
void connect2();
|
|
@@ -13855,7 +13994,7 @@ async function connect2() {
|
|
|
13855
13994
|
}
|
|
13856
13995
|
}
|
|
13857
13996
|
function wire(socket) {
|
|
13858
|
-
const lines2 =
|
|
13997
|
+
const lines2 = createInterface5({ input: socket });
|
|
13859
13998
|
lines2.on("error", () => {
|
|
13860
13999
|
});
|
|
13861
14000
|
lines2.on("line", emit);
|
|
@@ -13927,20 +14066,20 @@ async function web2(options2) {
|
|
|
13927
14066
|
import chalk64 from "chalk";
|
|
13928
14067
|
|
|
13929
14068
|
// src/commands/sessions/shared/resolveSessionTranscript.ts
|
|
13930
|
-
import * as
|
|
14069
|
+
import * as fs23 from "fs";
|
|
13931
14070
|
import * as path35 from "path";
|
|
13932
14071
|
|
|
13933
14072
|
// src/commands/sessions/summarise/readTranscriptHead.ts
|
|
13934
|
-
import * as
|
|
14073
|
+
import * as fs22 from "fs";
|
|
13935
14074
|
function readTranscriptHead(filePath, maxBytes = 65536) {
|
|
13936
14075
|
try {
|
|
13937
|
-
const fd =
|
|
14076
|
+
const fd = fs22.openSync(filePath, "r");
|
|
13938
14077
|
try {
|
|
13939
14078
|
const buf = Buffer.alloc(maxBytes);
|
|
13940
|
-
const bytesRead =
|
|
14079
|
+
const bytesRead = fs22.readSync(fd, buf, 0, buf.length, 0);
|
|
13941
14080
|
return buf.toString("utf8", 0, bytesRead);
|
|
13942
14081
|
} finally {
|
|
13943
|
-
|
|
14082
|
+
fs22.closeSync(fd);
|
|
13944
14083
|
}
|
|
13945
14084
|
} catch {
|
|
13946
14085
|
return void 0;
|
|
@@ -13969,13 +14108,13 @@ function resolveSessionTranscript(sessionId, projectsRoot = claudeProjectsRoot()
|
|
|
13969
14108
|
function findTranscriptFile(sessionId, projectsRoot) {
|
|
13970
14109
|
let projectDirs;
|
|
13971
14110
|
try {
|
|
13972
|
-
projectDirs =
|
|
14111
|
+
projectDirs = fs23.readdirSync(projectsRoot);
|
|
13973
14112
|
} catch {
|
|
13974
14113
|
return void 0;
|
|
13975
14114
|
}
|
|
13976
14115
|
for (const dir of projectDirs) {
|
|
13977
14116
|
const candidate = path35.join(projectsRoot, dir, `${sessionId}.jsonl`);
|
|
13978
|
-
if (
|
|
14117
|
+
if (fs23.existsSync(candidate)) return candidate;
|
|
13979
14118
|
}
|
|
13980
14119
|
return void 0;
|
|
13981
14120
|
}
|
|
@@ -14025,7 +14164,7 @@ async function addActivity(id, kind, ref, options2) {
|
|
|
14025
14164
|
import chalk65 from "chalk";
|
|
14026
14165
|
|
|
14027
14166
|
// src/commands/sessions/shared/resolveCurrentSessionId.ts
|
|
14028
|
-
import * as
|
|
14167
|
+
import * as fs24 from "fs";
|
|
14029
14168
|
import * as path36 from "path";
|
|
14030
14169
|
var SESSION_ID_ENV = "CLAUDE_CODE_SESSION_ID";
|
|
14031
14170
|
function resolveCurrentSessionId(options2 = {}) {
|
|
@@ -14040,7 +14179,7 @@ function resolveCurrentSessionId(options2 = {}) {
|
|
|
14040
14179
|
function newestTranscriptId(dir) {
|
|
14041
14180
|
let entries;
|
|
14042
14181
|
try {
|
|
14043
|
-
entries =
|
|
14182
|
+
entries = fs24.readdirSync(dir);
|
|
14044
14183
|
} catch {
|
|
14045
14184
|
return void 0;
|
|
14046
14185
|
}
|
|
@@ -14056,7 +14195,7 @@ function newestTranscriptId(dir) {
|
|
|
14056
14195
|
}
|
|
14057
14196
|
function modifiedAtOf(filePath) {
|
|
14058
14197
|
try {
|
|
14059
|
-
return
|
|
14198
|
+
return fs24.statSync(filePath).mtimeMs;
|
|
14060
14199
|
} catch {
|
|
14061
14200
|
return void 0;
|
|
14062
14201
|
}
|
|
@@ -16709,13 +16848,13 @@ function phaseNotes(entry, position) {
|
|
|
16709
16848
|
}
|
|
16710
16849
|
function renderDiffPhase(entry, idx) {
|
|
16711
16850
|
const notes = phaseNotes(entry, idx + 1);
|
|
16712
|
-
const
|
|
16851
|
+
const section2 = renderPhaseSection(
|
|
16713
16852
|
{ ...entry.phase, name: `${entry.phase.name} (${notes.join(", ")})` },
|
|
16714
16853
|
idx
|
|
16715
16854
|
);
|
|
16716
|
-
if (!entry.previousTasks) return
|
|
16855
|
+
if (!entry.previousTasks) return section2;
|
|
16717
16856
|
return [
|
|
16718
|
-
|
|
16857
|
+
section2,
|
|
16719
16858
|
"**Previously:**",
|
|
16720
16859
|
entry.previousTasks.map((task) => `- ${task}`).join("\n")
|
|
16721
16860
|
].join("\n\n");
|
|
@@ -19022,13 +19161,13 @@ import chalk133 from "chalk";
|
|
|
19022
19161
|
import chalk126 from "chalk";
|
|
19023
19162
|
|
|
19024
19163
|
// src/commands/complexity/shared/index.ts
|
|
19025
|
-
import
|
|
19164
|
+
import fs26 from "fs";
|
|
19026
19165
|
import path38 from "path";
|
|
19027
19166
|
import chalk125 from "chalk";
|
|
19028
19167
|
import ts5 from "typescript";
|
|
19029
19168
|
|
|
19030
19169
|
// src/commands/complexity/findSourceFiles.ts
|
|
19031
|
-
import
|
|
19170
|
+
import fs25 from "fs";
|
|
19032
19171
|
import path37 from "path";
|
|
19033
19172
|
import { minimatch as minimatch5 } from "minimatch";
|
|
19034
19173
|
function applyIgnoreGlobs(files, extraIgnore = []) {
|
|
@@ -19037,11 +19176,11 @@ function applyIgnoreGlobs(files, extraIgnore = []) {
|
|
|
19037
19176
|
return files.filter((f) => !ignore3.some((glob) => minimatch5(f, glob)));
|
|
19038
19177
|
}
|
|
19039
19178
|
function walk2(dir, results) {
|
|
19040
|
-
if (!
|
|
19179
|
+
if (!fs25.existsSync(dir)) {
|
|
19041
19180
|
return;
|
|
19042
19181
|
}
|
|
19043
19182
|
const extensions = [".ts", ".tsx"];
|
|
19044
|
-
const entries =
|
|
19183
|
+
const entries = fs25.readdirSync(dir, { withFileTypes: true });
|
|
19045
19184
|
for (const entry of entries) {
|
|
19046
19185
|
const fullPath = path37.join(dir, entry.name);
|
|
19047
19186
|
if (entry.isDirectory()) {
|
|
@@ -19062,10 +19201,10 @@ function findSourceFiles2(pattern2, baseDir = ".", extraIgnore = []) {
|
|
|
19062
19201
|
extraIgnore
|
|
19063
19202
|
);
|
|
19064
19203
|
}
|
|
19065
|
-
if (
|
|
19204
|
+
if (fs25.existsSync(pattern2) && fs25.statSync(pattern2).isFile()) {
|
|
19066
19205
|
return [pattern2];
|
|
19067
19206
|
}
|
|
19068
|
-
if (
|
|
19207
|
+
if (fs25.existsSync(pattern2) && fs25.statSync(pattern2).isDirectory()) {
|
|
19069
19208
|
walk2(pattern2, results);
|
|
19070
19209
|
return applyIgnoreGlobs(results, extraIgnore);
|
|
19071
19210
|
}
|
|
@@ -19263,7 +19402,7 @@ function countSloc(content) {
|
|
|
19263
19402
|
|
|
19264
19403
|
// src/commands/complexity/shared/index.ts
|
|
19265
19404
|
function createSourceFromFile(filePath) {
|
|
19266
|
-
const content =
|
|
19405
|
+
const content = fs26.readFileSync(filePath, "utf8");
|
|
19267
19406
|
return ts5.createSourceFile(
|
|
19268
19407
|
path38.basename(filePath),
|
|
19269
19408
|
content,
|
|
@@ -19375,7 +19514,7 @@ function aggregateResults(fileMetrics) {
|
|
|
19375
19514
|
}
|
|
19376
19515
|
|
|
19377
19516
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
19378
|
-
import
|
|
19517
|
+
import fs27 from "fs";
|
|
19379
19518
|
|
|
19380
19519
|
// src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
|
|
19381
19520
|
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
@@ -19390,7 +19529,7 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
|
|
|
19390
19529
|
function collectFileMetrics(files) {
|
|
19391
19530
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
19392
19531
|
for (const file of files) {
|
|
19393
|
-
const content =
|
|
19532
|
+
const content = fs27.readFileSync(file, "utf8");
|
|
19394
19533
|
fileMetrics.set(file, {
|
|
19395
19534
|
sloc: countSloc(content),
|
|
19396
19535
|
functions: [],
|
|
@@ -19551,14 +19690,14 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
19551
19690
|
}
|
|
19552
19691
|
|
|
19553
19692
|
// src/commands/complexity/sloc.ts
|
|
19554
|
-
import
|
|
19693
|
+
import fs28 from "fs";
|
|
19555
19694
|
import chalk132 from "chalk";
|
|
19556
19695
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
19557
19696
|
withSourceFiles(pattern2, (files) => {
|
|
19558
19697
|
const results = [];
|
|
19559
19698
|
let hasViolation = false;
|
|
19560
19699
|
for (const file of files) {
|
|
19561
|
-
const content =
|
|
19700
|
+
const content = fs28.readFileSync(file, "utf8");
|
|
19562
19701
|
const lines2 = countSloc(content);
|
|
19563
19702
|
results.push({ file, lines: lines2 });
|
|
19564
19703
|
if (options2.threshold !== void 0 && lines2 > options2.threshold) {
|
|
@@ -20807,7 +20946,7 @@ function registerDevlog(program2) {
|
|
|
20807
20946
|
}
|
|
20808
20947
|
|
|
20809
20948
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
20810
|
-
import { closeSync as closeSync3, openSync as
|
|
20949
|
+
import { closeSync as closeSync3, openSync as openSync4, readdirSync as readdirSync8 } from "fs";
|
|
20811
20950
|
import { join as join56 } from "path";
|
|
20812
20951
|
import chalk154 from "chalk";
|
|
20813
20952
|
var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "packages"]);
|
|
@@ -20822,7 +20961,7 @@ function isLockedDll(debugDir) {
|
|
|
20822
20961
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
20823
20962
|
const dllPath = join56(debugDir, file);
|
|
20824
20963
|
try {
|
|
20825
|
-
const fd =
|
|
20964
|
+
const fd = openSync4(dllPath, "r+");
|
|
20826
20965
|
closeSync3(fd);
|
|
20827
20966
|
} catch {
|
|
20828
20967
|
return dllPath;
|
|
@@ -21417,7 +21556,7 @@ function registerDotnet(program2) {
|
|
|
21417
21556
|
}
|
|
21418
21557
|
|
|
21419
21558
|
// src/commands/editHook/index.ts
|
|
21420
|
-
import
|
|
21559
|
+
import fs29 from "fs";
|
|
21421
21560
|
|
|
21422
21561
|
// src/commands/editHook/introducedComments.ts
|
|
21423
21562
|
function introducedComments(added, removed) {
|
|
@@ -21664,7 +21803,7 @@ function tryParseInput2(raw) {
|
|
|
21664
21803
|
function readExisting(filePath) {
|
|
21665
21804
|
if (!filePath) return void 0;
|
|
21666
21805
|
try {
|
|
21667
|
-
return
|
|
21806
|
+
return fs29.readFileSync(filePath, "utf8");
|
|
21668
21807
|
} catch {
|
|
21669
21808
|
return void 0;
|
|
21670
21809
|
}
|
|
@@ -26228,9 +26367,9 @@ function parsePrBody(body) {
|
|
|
26228
26367
|
return sections;
|
|
26229
26368
|
}
|
|
26230
26369
|
function serializePrBody(sections) {
|
|
26231
|
-
return sections.map((
|
|
26370
|
+
return sections.map((section2) => `## ${section2.heading}
|
|
26232
26371
|
|
|
26233
|
-
${
|
|
26372
|
+
${section2.content}`).join("\n\n");
|
|
26234
26373
|
}
|
|
26235
26374
|
|
|
26236
26375
|
// src/commands/prs/editPrBody.ts
|
|
@@ -26279,11 +26418,11 @@ function findWallOfText(body) {
|
|
|
26279
26418
|
}
|
|
26280
26419
|
function splitParagraphs(body) {
|
|
26281
26420
|
const paragraphs = [];
|
|
26282
|
-
let
|
|
26421
|
+
let section2 = "(intro)";
|
|
26283
26422
|
let lines2 = [];
|
|
26284
26423
|
const flush = () => {
|
|
26285
26424
|
if (lines2.length > 0) {
|
|
26286
|
-
paragraphs.push({ section:
|
|
26425
|
+
paragraphs.push({ section: section2, lines: lines2 });
|
|
26287
26426
|
lines2 = [];
|
|
26288
26427
|
}
|
|
26289
26428
|
};
|
|
@@ -26291,7 +26430,7 @@ function splitParagraphs(body) {
|
|
|
26291
26430
|
const heading2 = line.match(/^#{1,6}\s+(.*)$/);
|
|
26292
26431
|
if (heading2) {
|
|
26293
26432
|
flush();
|
|
26294
|
-
|
|
26433
|
+
section2 = heading2[1].trim();
|
|
26295
26434
|
} else if (line.trim() === "") {
|
|
26296
26435
|
flush();
|
|
26297
26436
|
} else {
|
|
@@ -28267,17 +28406,17 @@ Refactor check failed:
|
|
|
28267
28406
|
|
|
28268
28407
|
// src/commands/refactor/check/getViolations/index.ts
|
|
28269
28408
|
import { execSync as execSync55 } from "child_process";
|
|
28270
|
-
import
|
|
28409
|
+
import fs31 from "fs";
|
|
28271
28410
|
import { minimatch as minimatch6 } from "minimatch";
|
|
28272
28411
|
|
|
28273
28412
|
// src/commands/refactor/check/getViolations/getIgnoredFiles.ts
|
|
28274
|
-
import
|
|
28413
|
+
import fs30 from "fs";
|
|
28275
28414
|
var REFACTOR_YML_PATH = "refactor.yml";
|
|
28276
28415
|
function parseRefactorYml() {
|
|
28277
|
-
if (!
|
|
28416
|
+
if (!fs30.existsSync(REFACTOR_YML_PATH)) {
|
|
28278
28417
|
return [];
|
|
28279
28418
|
}
|
|
28280
|
-
const content =
|
|
28419
|
+
const content = fs30.readFileSync(REFACTOR_YML_PATH, "utf8");
|
|
28281
28420
|
const entries = [];
|
|
28282
28421
|
const lines2 = content.split("\n");
|
|
28283
28422
|
let currentEntry = {};
|
|
@@ -28307,7 +28446,7 @@ function getIgnoredFiles() {
|
|
|
28307
28446
|
|
|
28308
28447
|
// src/commands/refactor/check/getViolations/index.ts
|
|
28309
28448
|
function countLines(filePath) {
|
|
28310
|
-
const content =
|
|
28449
|
+
const content = fs31.readFileSync(filePath, "utf8");
|
|
28311
28450
|
return content.split("\n").length;
|
|
28312
28451
|
}
|
|
28313
28452
|
function getGitFiles(options2) {
|
|
@@ -29012,13 +29151,13 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
29012
29151
|
// src/commands/refactor/extract/displayPlan.ts
|
|
29013
29152
|
import path50 from "path";
|
|
29014
29153
|
import chalk199 from "chalk";
|
|
29015
|
-
function
|
|
29154
|
+
function section(title) {
|
|
29016
29155
|
return `
|
|
29017
29156
|
${chalk199.cyan(title)}`;
|
|
29018
29157
|
}
|
|
29019
29158
|
function displayImporters(plan2, cwd) {
|
|
29020
29159
|
if (plan2.importersToUpdate.length === 0) return;
|
|
29021
|
-
console.log(
|
|
29160
|
+
console.log(section("Update importers:"));
|
|
29022
29161
|
for (const imp of plan2.importersToUpdate) {
|
|
29023
29162
|
const rel = path50.relative(cwd, imp.file.getFilePath());
|
|
29024
29163
|
console.log(` ${chalk199.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
@@ -29032,18 +29171,18 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
29032
29171
|
console.log(` ${name}`);
|
|
29033
29172
|
}
|
|
29034
29173
|
if (plan2.imports.length > 0) {
|
|
29035
|
-
console.log(
|
|
29174
|
+
console.log(section("Imports to copy:"));
|
|
29036
29175
|
for (const imp of plan2.imports) {
|
|
29037
29176
|
console.log(` ${formatImportLine(imp)}`);
|
|
29038
29177
|
}
|
|
29039
29178
|
}
|
|
29040
29179
|
if (plan2.exportedDeps.length > 0) {
|
|
29041
|
-
console.log(
|
|
29180
|
+
console.log(section("New imports from source:"));
|
|
29042
29181
|
console.log(
|
|
29043
29182
|
` import { ${plan2.exportedDeps.join(", ")} } from "${plan2.sourceRelPath}";`
|
|
29044
29183
|
);
|
|
29045
29184
|
}
|
|
29046
|
-
console.log(
|
|
29185
|
+
console.log(section("Source file changes:"));
|
|
29047
29186
|
console.log(` Remove: ${plan2.extractedNames.join(", ")}`);
|
|
29048
29187
|
if (plan2.sourceNeedsReimport) {
|
|
29049
29188
|
console.log(
|
|
@@ -29052,7 +29191,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
29052
29191
|
}
|
|
29053
29192
|
displayImporters(plan2, cwd);
|
|
29054
29193
|
if (plan2.barrel) {
|
|
29055
|
-
console.log(
|
|
29194
|
+
console.log(section("Barrel export:"));
|
|
29056
29195
|
console.log(
|
|
29057
29196
|
` Add: export { ${functionName} } from "${plan2.barrelRelPath}";`
|
|
29058
29197
|
);
|
|
@@ -29065,11 +29204,11 @@ import chalk200 from "chalk";
|
|
|
29065
29204
|
import { Project as Project4 } from "ts-morph";
|
|
29066
29205
|
|
|
29067
29206
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
29068
|
-
import
|
|
29207
|
+
import fs33 from "fs";
|
|
29069
29208
|
import path52 from "path";
|
|
29070
29209
|
|
|
29071
29210
|
// src/commands/refactor/extract/findEnclosingTsConfig.ts
|
|
29072
|
-
import
|
|
29211
|
+
import fs32 from "fs";
|
|
29073
29212
|
import path51 from "path";
|
|
29074
29213
|
|
|
29075
29214
|
// src/commands/refactor/extract/projectIncludesFile.ts
|
|
@@ -29090,7 +29229,7 @@ function findEnclosingTsConfig(sourcePath, rootDir, tried) {
|
|
|
29090
29229
|
const nested = path51.join(dir, "tsconfig.json");
|
|
29091
29230
|
if (!tried.has(nested)) {
|
|
29092
29231
|
tried.add(nested);
|
|
29093
|
-
if (
|
|
29232
|
+
if (fs32.existsSync(nested) && projectIncludesFile(nested, sourcePath)) {
|
|
29094
29233
|
return nested;
|
|
29095
29234
|
}
|
|
29096
29235
|
}
|
|
@@ -29104,7 +29243,7 @@ function findEnclosingTsConfig(sourcePath, rootDir, tried) {
|
|
|
29104
29243
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
29105
29244
|
function findTsConfig(sourcePath) {
|
|
29106
29245
|
const rootConfig = path52.resolve("tsconfig.json");
|
|
29107
|
-
if (!
|
|
29246
|
+
if (!fs33.existsSync(rootConfig)) return rootConfig;
|
|
29108
29247
|
const tried = /* @__PURE__ */ new Set();
|
|
29109
29248
|
const candidates = [rootConfig, ...readReferences(rootConfig)];
|
|
29110
29249
|
for (const candidate of candidates) {
|
|
@@ -29112,7 +29251,7 @@ function findTsConfig(sourcePath) {
|
|
|
29112
29251
|
tried.add(candidate);
|
|
29113
29252
|
if (projectIncludesFile(candidate, sourcePath)) return candidate;
|
|
29114
29253
|
}
|
|
29115
|
-
const siblings =
|
|
29254
|
+
const siblings = fs33.readdirSync(path52.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path52.resolve(path52.dirname(rootConfig), f));
|
|
29116
29255
|
for (const sibling of siblings) {
|
|
29117
29256
|
if (tried.has(sibling)) continue;
|
|
29118
29257
|
tried.add(sibling);
|
|
@@ -29127,8 +29266,8 @@ function findTsConfig(sourcePath) {
|
|
|
29127
29266
|
return rootConfig;
|
|
29128
29267
|
}
|
|
29129
29268
|
function readReferences(configPath) {
|
|
29130
|
-
if (!
|
|
29131
|
-
const raw =
|
|
29269
|
+
if (!fs33.existsSync(configPath)) return [];
|
|
29270
|
+
const raw = fs33.readFileSync(configPath, "utf8");
|
|
29132
29271
|
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
29133
29272
|
let parsed;
|
|
29134
29273
|
try {
|
|
@@ -29140,8 +29279,8 @@ function readReferences(configPath) {
|
|
|
29140
29279
|
const cwd = path52.dirname(configPath);
|
|
29141
29280
|
return parsed.references.map((ref) => {
|
|
29142
29281
|
const refPath = path52.resolve(cwd, ref.path);
|
|
29143
|
-
return
|
|
29144
|
-
}).filter((p) =>
|
|
29282
|
+
return fs33.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path52.join(refPath, "tsconfig.json") : refPath;
|
|
29283
|
+
}).filter((p) => fs33.existsSync(p));
|
|
29145
29284
|
}
|
|
29146
29285
|
|
|
29147
29286
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
@@ -29183,25 +29322,25 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
29183
29322
|
}
|
|
29184
29323
|
|
|
29185
29324
|
// src/commands/refactor/ignore.ts
|
|
29186
|
-
import
|
|
29325
|
+
import fs34 from "fs";
|
|
29187
29326
|
import chalk202 from "chalk";
|
|
29188
29327
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
29189
29328
|
function ignore2(file) {
|
|
29190
|
-
if (!
|
|
29329
|
+
if (!fs34.existsSync(file)) {
|
|
29191
29330
|
console.error(chalk202.red(`Error: File does not exist: ${file}`));
|
|
29192
29331
|
process.exit(1);
|
|
29193
29332
|
}
|
|
29194
|
-
const content =
|
|
29333
|
+
const content = fs34.readFileSync(file, "utf8");
|
|
29195
29334
|
const lineCount = content.split("\n").length;
|
|
29196
29335
|
const maxLines = lineCount + 10;
|
|
29197
29336
|
const entry = `- file: ${file}
|
|
29198
29337
|
maxLines: ${maxLines}
|
|
29199
29338
|
`;
|
|
29200
|
-
if (
|
|
29201
|
-
const existing =
|
|
29202
|
-
|
|
29339
|
+
if (fs34.existsSync(REFACTOR_YML_PATH2)) {
|
|
29340
|
+
const existing = fs34.readFileSync(REFACTOR_YML_PATH2, "utf8");
|
|
29341
|
+
fs34.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
29203
29342
|
} else {
|
|
29204
|
-
|
|
29343
|
+
fs34.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
29205
29344
|
}
|
|
29206
29345
|
console.log(
|
|
29207
29346
|
chalk202.green(
|
|
@@ -29211,12 +29350,12 @@ function ignore2(file) {
|
|
|
29211
29350
|
}
|
|
29212
29351
|
|
|
29213
29352
|
// src/commands/refactor/rename/index.ts
|
|
29214
|
-
import
|
|
29353
|
+
import fs37 from "fs";
|
|
29215
29354
|
import path59 from "path";
|
|
29216
29355
|
import chalk205 from "chalk";
|
|
29217
29356
|
|
|
29218
29357
|
// src/commands/refactor/rename/applyRename.ts
|
|
29219
|
-
import
|
|
29358
|
+
import fs36 from "fs";
|
|
29220
29359
|
import path56 from "path";
|
|
29221
29360
|
import chalk203 from "chalk";
|
|
29222
29361
|
|
|
@@ -29224,7 +29363,7 @@ import chalk203 from "chalk";
|
|
|
29224
29363
|
import path55 from "path";
|
|
29225
29364
|
|
|
29226
29365
|
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
29227
|
-
import
|
|
29366
|
+
import fs35 from "fs";
|
|
29228
29367
|
function getOrCreateList(map, key) {
|
|
29229
29368
|
const list5 = map.get(key) ?? [];
|
|
29230
29369
|
if (!map.has(key)) map.set(key, list5);
|
|
@@ -29243,7 +29382,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
|
29243
29382
|
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
29244
29383
|
}
|
|
29245
29384
|
function applyFileRewrites(file, fileRewrites) {
|
|
29246
|
-
let content =
|
|
29385
|
+
let content = fs35.readFileSync(file, "utf8");
|
|
29247
29386
|
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
29248
29387
|
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
29249
29388
|
}
|
|
@@ -29322,12 +29461,12 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
29322
29461
|
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
29323
29462
|
const updatedContents = applyRewrites(rewrites);
|
|
29324
29463
|
for (const [file, content] of updatedContents) {
|
|
29325
|
-
|
|
29464
|
+
fs36.writeFileSync(file, content, "utf8");
|
|
29326
29465
|
console.log(chalk203.cyan(` Updated imports in ${path56.relative(cwd, file)}`));
|
|
29327
29466
|
}
|
|
29328
29467
|
const destDir = path56.dirname(destPath);
|
|
29329
|
-
if (!
|
|
29330
|
-
|
|
29468
|
+
if (!fs36.existsSync(destDir)) fs36.mkdirSync(destDir, { recursive: true });
|
|
29469
|
+
fs36.renameSync(sourcePath, destPath);
|
|
29331
29470
|
console.log(
|
|
29332
29471
|
chalk203.white(
|
|
29333
29472
|
` Moved ${path56.relative(cwd, sourcePath)} \u2192 ${path56.relative(cwd, destPath)}`
|
|
@@ -29435,11 +29574,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
29435
29574
|
const cwd = process.cwd();
|
|
29436
29575
|
const relSource = path59.relative(cwd, sourcePath);
|
|
29437
29576
|
const relDest = path59.relative(cwd, destPath);
|
|
29438
|
-
if (!
|
|
29577
|
+
if (!fs37.existsSync(sourcePath)) {
|
|
29439
29578
|
console.log(chalk205.red(`File not found: ${source}`));
|
|
29440
29579
|
process.exit(1);
|
|
29441
29580
|
}
|
|
29442
|
-
if (destPath !== sourcePath &&
|
|
29581
|
+
if (destPath !== sourcePath && fs37.existsSync(destPath)) {
|
|
29443
29582
|
console.log(chalk205.red(`Destination already exists: ${destination}`));
|
|
29444
29583
|
process.exit(1);
|
|
29445
29584
|
}
|
|
@@ -29664,27 +29803,27 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
29664
29803
|
}
|
|
29665
29804
|
|
|
29666
29805
|
// src/commands/refactor/restructure/executePlan.ts
|
|
29667
|
-
import
|
|
29806
|
+
import fs38 from "fs";
|
|
29668
29807
|
import path64 from "path";
|
|
29669
29808
|
import chalk208 from "chalk";
|
|
29670
29809
|
function executePlan(plan2) {
|
|
29671
29810
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
29672
29811
|
for (const [file, content] of updatedContents) {
|
|
29673
|
-
|
|
29812
|
+
fs38.writeFileSync(file, content, "utf8");
|
|
29674
29813
|
console.log(
|
|
29675
29814
|
chalk208.cyan(` Rewrote imports in ${path64.relative(process.cwd(), file)}`)
|
|
29676
29815
|
);
|
|
29677
29816
|
}
|
|
29678
29817
|
for (const dir of plan2.newDirectories) {
|
|
29679
|
-
|
|
29818
|
+
fs38.mkdirSync(dir, { recursive: true });
|
|
29680
29819
|
console.log(chalk208.green(` Created ${path64.relative(process.cwd(), dir)}/`));
|
|
29681
29820
|
}
|
|
29682
29821
|
for (const move2 of plan2.moves) {
|
|
29683
29822
|
const targetDir = path64.dirname(move2.to);
|
|
29684
|
-
if (!
|
|
29685
|
-
|
|
29823
|
+
if (!fs38.existsSync(targetDir)) {
|
|
29824
|
+
fs38.mkdirSync(targetDir, { recursive: true });
|
|
29686
29825
|
}
|
|
29687
|
-
|
|
29826
|
+
fs38.renameSync(move2.from, move2.to);
|
|
29688
29827
|
console.log(
|
|
29689
29828
|
chalk208.white(
|
|
29690
29829
|
` Moved ${path64.relative(process.cwd(), move2.from)} \u2192 ${path64.relative(process.cwd(), move2.to)}`
|
|
@@ -29696,10 +29835,10 @@ function executePlan(plan2) {
|
|
|
29696
29835
|
function removeEmptyDirectories(dirs) {
|
|
29697
29836
|
const unique = [...new Set(dirs)];
|
|
29698
29837
|
for (const dir of unique) {
|
|
29699
|
-
if (!
|
|
29700
|
-
const entries =
|
|
29838
|
+
if (!fs38.existsSync(dir)) continue;
|
|
29839
|
+
const entries = fs38.readdirSync(dir);
|
|
29701
29840
|
if (entries.length === 0) {
|
|
29702
|
-
|
|
29841
|
+
fs38.rmdirSync(dir);
|
|
29703
29842
|
console.log(
|
|
29704
29843
|
chalk208.dim(
|
|
29705
29844
|
` Removed empty directory ${path64.relative(process.cwd(), dir)}`
|
|
@@ -29713,18 +29852,18 @@ function removeEmptyDirectories(dirs) {
|
|
|
29713
29852
|
import path66 from "path";
|
|
29714
29853
|
|
|
29715
29854
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
29716
|
-
import
|
|
29855
|
+
import fs39 from "fs";
|
|
29717
29856
|
function emptyResult() {
|
|
29718
29857
|
return { moves: [], directories: [], warnings: [] };
|
|
29719
29858
|
}
|
|
29720
29859
|
function checkDirConflict(result, label2, dir) {
|
|
29721
|
-
if (!
|
|
29860
|
+
if (!fs39.existsSync(dir)) return false;
|
|
29722
29861
|
result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
|
|
29723
29862
|
return true;
|
|
29724
29863
|
}
|
|
29725
29864
|
|
|
29726
29865
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
29727
|
-
import
|
|
29866
|
+
import fs40 from "fs";
|
|
29728
29867
|
import path65 from "path";
|
|
29729
29868
|
function collectEntry2(results, dir, entry) {
|
|
29730
29869
|
const full = path65.join(dir, entry.name);
|
|
@@ -29732,9 +29871,9 @@ function collectEntry2(results, dir, entry) {
|
|
|
29732
29871
|
results.push(...items2);
|
|
29733
29872
|
}
|
|
29734
29873
|
function listFilesRecursive(dir) {
|
|
29735
|
-
if (!
|
|
29874
|
+
if (!fs40.existsSync(dir)) return [];
|
|
29736
29875
|
const results = [];
|
|
29737
|
-
for (const entry of
|
|
29876
|
+
for (const entry of fs40.readdirSync(dir, { withFileTypes: true })) {
|
|
29738
29877
|
collectEntry2(results, dir, entry);
|
|
29739
29878
|
}
|
|
29740
29879
|
return results;
|
|
@@ -32893,7 +33032,7 @@ function registerSql(program2) {
|
|
|
32893
33032
|
}
|
|
32894
33033
|
|
|
32895
33034
|
// src/commands/sync.ts
|
|
32896
|
-
import * as
|
|
33035
|
+
import * as fs49 from "fs";
|
|
32897
33036
|
import * as os5 from "os";
|
|
32898
33037
|
import * as path85 from "path";
|
|
32899
33038
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
@@ -32902,7 +33041,7 @@ import { fileURLToPath as fileURLToPath9 } from "url";
|
|
|
32902
33041
|
import * as path76 from "path";
|
|
32903
33042
|
|
|
32904
33043
|
// src/commands/sync/pruneTarget.ts
|
|
32905
|
-
import * as
|
|
33044
|
+
import * as fs41 from "fs";
|
|
32906
33045
|
import * as path75 from "path";
|
|
32907
33046
|
function pruneTarget(targetDir, keepNames, shape, options2) {
|
|
32908
33047
|
const result = {
|
|
@@ -32911,9 +33050,9 @@ function pruneTarget(targetDir, keepNames, shape, options2) {
|
|
|
32911
33050
|
skipped: [],
|
|
32912
33051
|
unmanaged: []
|
|
32913
33052
|
};
|
|
32914
|
-
if (!
|
|
33053
|
+
if (!fs41.existsSync(targetDir)) return result;
|
|
32915
33054
|
const keep = new Set(keepNames);
|
|
32916
|
-
for (const entry of
|
|
33055
|
+
for (const entry of fs41.readdirSync(targetDir, { withFileTypes: true })) {
|
|
32917
33056
|
const name = shape.nameOf(entry);
|
|
32918
33057
|
if (name === void 0) {
|
|
32919
33058
|
result.unmanaged.push(entry.name);
|
|
@@ -32928,7 +33067,7 @@ function pruneTarget(targetDir, keepNames, shape, options2) {
|
|
|
32928
33067
|
continue;
|
|
32929
33068
|
}
|
|
32930
33069
|
if (options2.force) {
|
|
32931
|
-
|
|
33070
|
+
fs41.rmSync(entryPath, { recursive: true });
|
|
32932
33071
|
result.removed.push(entry.name);
|
|
32933
33072
|
}
|
|
32934
33073
|
}
|
|
@@ -32975,7 +33114,7 @@ function reportPrune(label2, result, force) {
|
|
|
32975
33114
|
}
|
|
32976
33115
|
|
|
32977
33116
|
// src/commands/sync/reportRetiredAgentsFiles.ts
|
|
32978
|
-
import * as
|
|
33117
|
+
import * as fs42 from "fs";
|
|
32979
33118
|
import * as path77 from "path";
|
|
32980
33119
|
var retired = [
|
|
32981
33120
|
path77.join(harnesses.claude.homeDir, "CLAUDE.md"),
|
|
@@ -32983,7 +33122,7 @@ var retired = [
|
|
|
32983
33122
|
path77.join(harnesses.pi.homeDir, "AGENTS.md")
|
|
32984
33123
|
];
|
|
32985
33124
|
function reportRetiredAgentsFiles() {
|
|
32986
|
-
const leftovers = retired.filter((file) =>
|
|
33125
|
+
const leftovers = retired.filter((file) => fs42.existsSync(file));
|
|
32987
33126
|
if (leftovers.length === 0) return;
|
|
32988
33127
|
console.log(
|
|
32989
33128
|
"No longer written by sync \u2014 each harness now composes its own advice at session start:"
|
|
@@ -32998,28 +33137,28 @@ function reportRetiredAgentsFiles() {
|
|
|
32998
33137
|
import * as path80 from "path";
|
|
32999
33138
|
|
|
33000
33139
|
// src/commands/sync/installHarnessCommands.ts
|
|
33001
|
-
import * as
|
|
33140
|
+
import * as fs43 from "fs";
|
|
33002
33141
|
import * as path78 from "path";
|
|
33003
33142
|
function installHarnessCommands(claudeDir, harness, transform) {
|
|
33004
33143
|
const commandsSource = path78.join(claudeDir, "commands");
|
|
33005
|
-
const files =
|
|
33144
|
+
const files = fs43.readdirSync(commandsSource);
|
|
33006
33145
|
const names = [];
|
|
33007
33146
|
let synced = 0;
|
|
33008
33147
|
for (const file of files) {
|
|
33009
33148
|
if (!file.endsWith(".md")) continue;
|
|
33010
33149
|
const name = file.replace(/\.md$/, "");
|
|
33011
33150
|
names.push(name);
|
|
33012
|
-
const content =
|
|
33151
|
+
const content = fs43.readFileSync(path78.join(commandsSource, file), "utf8");
|
|
33013
33152
|
const target = path78.join(harness.homeDir, harness.sync.commandDest(name));
|
|
33014
|
-
|
|
33015
|
-
|
|
33153
|
+
fs43.mkdirSync(path78.dirname(target), { recursive: true });
|
|
33154
|
+
fs43.writeFileSync(target, transform(name, content));
|
|
33016
33155
|
synced++;
|
|
33017
33156
|
}
|
|
33018
33157
|
return { total: files.length, synced, names };
|
|
33019
33158
|
}
|
|
33020
33159
|
|
|
33021
33160
|
// src/commands/sync/pruneSkills.ts
|
|
33022
|
-
import * as
|
|
33161
|
+
import * as fs44 from "fs";
|
|
33023
33162
|
function pruneSkills(targetDir, skillNames, options2) {
|
|
33024
33163
|
return pruneTarget(
|
|
33025
33164
|
targetDir,
|
|
@@ -33032,14 +33171,14 @@ function pruneSkills(targetDir, skillNames, options2) {
|
|
|
33032
33171
|
);
|
|
33033
33172
|
}
|
|
33034
33173
|
function unexpectedContent(skillDir) {
|
|
33035
|
-
const entries =
|
|
33174
|
+
const entries = fs44.readdirSync(skillDir);
|
|
33036
33175
|
const others = entries.filter((entry) => entry !== "SKILL.md");
|
|
33037
33176
|
if (others.length > 0) return `contains ${others.sort().join(", ")}`;
|
|
33038
33177
|
return entries.length === 0 ? "no SKILL.md" : void 0;
|
|
33039
33178
|
}
|
|
33040
33179
|
|
|
33041
33180
|
// src/commands/sync/syncCodexHooks.ts
|
|
33042
|
-
import * as
|
|
33181
|
+
import * as fs45 from "fs";
|
|
33043
33182
|
import * as path79 from "path";
|
|
33044
33183
|
var BEGIN = "# >>> assist codex hooks (managed) \u2014 do not edit >>>";
|
|
33045
33184
|
var END = "# <<< assist codex hooks (managed) <<<";
|
|
@@ -33070,11 +33209,11 @@ ${rest}
|
|
|
33070
33209
|
`;
|
|
33071
33210
|
}
|
|
33072
33211
|
function syncCodexHooks(sourcePath) {
|
|
33073
|
-
const body =
|
|
33212
|
+
const body = fs45.readFileSync(sourcePath, "utf8");
|
|
33074
33213
|
const configPath = path79.join(harnesses.codex.homeDir, "config.toml");
|
|
33075
|
-
const existing =
|
|
33076
|
-
|
|
33077
|
-
|
|
33214
|
+
const existing = fs45.existsSync(configPath) ? fs45.readFileSync(configPath, "utf8") : "";
|
|
33215
|
+
fs45.mkdirSync(path79.dirname(configPath), { recursive: true });
|
|
33216
|
+
fs45.writeFileSync(configPath, upsertManagedBlock(existing, body));
|
|
33078
33217
|
console.log(
|
|
33079
33218
|
"Registered assist codex-hook in ~/.codex/config.toml (SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PermissionRequest, Stop)"
|
|
33080
33219
|
);
|
|
@@ -33117,21 +33256,21 @@ function syncCodex(claudeDir, options2) {
|
|
|
33117
33256
|
}
|
|
33118
33257
|
|
|
33119
33258
|
// src/commands/sync/syncDesign.ts
|
|
33120
|
-
import * as
|
|
33259
|
+
import * as fs46 from "fs";
|
|
33121
33260
|
import * as path81 from "path";
|
|
33122
33261
|
function syncDesign(claudeDir, targetBase) {
|
|
33123
33262
|
const systemPromptSource = path81.join(claudeDir, "design-system-prompt.md");
|
|
33124
33263
|
const systemPromptTarget = path81.join(targetBase, "design-system-prompt.md");
|
|
33125
|
-
|
|
33264
|
+
fs46.copyFileSync(systemPromptSource, systemPromptTarget);
|
|
33126
33265
|
console.log(
|
|
33127
33266
|
"Copied design-system-prompt.md to ~/.claude/design-system-prompt.md"
|
|
33128
33267
|
);
|
|
33129
33268
|
const skillsSource = path81.join(claudeDir, "skills");
|
|
33130
33269
|
const skillsTarget = path81.join(targetBase, "skills");
|
|
33131
|
-
|
|
33132
|
-
const files =
|
|
33270
|
+
fs46.mkdirSync(skillsTarget, { recursive: true });
|
|
33271
|
+
const files = fs46.readdirSync(skillsSource);
|
|
33133
33272
|
for (const file of files) {
|
|
33134
|
-
|
|
33273
|
+
fs46.copyFileSync(
|
|
33135
33274
|
path81.join(skillsSource, file),
|
|
33136
33275
|
path81.join(skillsTarget, file)
|
|
33137
33276
|
);
|
|
@@ -33143,17 +33282,17 @@ function syncDesign(claudeDir, targetBase) {
|
|
|
33143
33282
|
import * as path83 from "path";
|
|
33144
33283
|
|
|
33145
33284
|
// src/commands/sync/syncPiHooks.ts
|
|
33146
|
-
import * as
|
|
33285
|
+
import * as fs47 from "fs";
|
|
33147
33286
|
import * as path82 from "path";
|
|
33148
33287
|
function piExtensionsDir() {
|
|
33149
33288
|
return path82.join(harnesses.pi.homeDir, "extensions");
|
|
33150
33289
|
}
|
|
33151
33290
|
function syncPiHooks(sourceDir) {
|
|
33152
33291
|
const target = piExtensionsDir();
|
|
33153
|
-
|
|
33154
|
-
const files =
|
|
33292
|
+
fs47.mkdirSync(target, { recursive: true });
|
|
33293
|
+
const files = fs47.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
|
|
33155
33294
|
for (const file of files) {
|
|
33156
|
-
|
|
33295
|
+
fs47.copyFileSync(
|
|
33157
33296
|
path82.join(sourceDir, file),
|
|
33158
33297
|
path82.join(target, `assist-${file}`)
|
|
33159
33298
|
);
|
|
@@ -33204,16 +33343,16 @@ function syncPi(claudeDir, options2) {
|
|
|
33204
33343
|
}
|
|
33205
33344
|
|
|
33206
33345
|
// src/commands/sync/syncSettings.ts
|
|
33207
|
-
import * as
|
|
33346
|
+
import * as fs48 from "fs";
|
|
33208
33347
|
import * as path84 from "path";
|
|
33209
33348
|
import chalk227 from "chalk";
|
|
33210
33349
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
33211
33350
|
const source = path84.join(claudeDir, "settings.json");
|
|
33212
33351
|
const target = path84.join(targetBase, "settings.json");
|
|
33213
|
-
const sourceContent =
|
|
33352
|
+
const sourceContent = fs48.readFileSync(source, "utf8");
|
|
33214
33353
|
const sourceSettings = JSON.parse(sourceContent);
|
|
33215
|
-
const targetExists =
|
|
33216
|
-
const targetContent = targetExists ?
|
|
33354
|
+
const targetExists = fs48.existsSync(target);
|
|
33355
|
+
const targetContent = targetExists ? fs48.readFileSync(target, "utf8") : "";
|
|
33217
33356
|
const preservedUserSettings = targetExists ? JSON.parse(targetContent) : {};
|
|
33218
33357
|
const mergedContent = JSON.stringify(
|
|
33219
33358
|
{ ...preservedUserSettings, ...sourceSettings },
|
|
@@ -33243,7 +33382,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
33243
33382
|
}
|
|
33244
33383
|
}
|
|
33245
33384
|
}
|
|
33246
|
-
|
|
33385
|
+
fs48.writeFileSync(target, mergedContent);
|
|
33247
33386
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
33248
33387
|
}
|
|
33249
33388
|
|
|
@@ -33274,10 +33413,10 @@ async function sync(options2) {
|
|
|
33274
33413
|
function syncCommands(claudeDir, targetBase) {
|
|
33275
33414
|
const sourceDir = path85.join(claudeDir, "commands");
|
|
33276
33415
|
const targetDir = path85.join(targetBase, "commands");
|
|
33277
|
-
|
|
33278
|
-
const files =
|
|
33416
|
+
fs49.mkdirSync(targetDir, { recursive: true });
|
|
33417
|
+
const files = fs49.readdirSync(sourceDir);
|
|
33279
33418
|
for (const file of files) {
|
|
33280
|
-
|
|
33419
|
+
fs49.copyFileSync(path85.join(sourceDir, file), path85.join(targetDir, file));
|
|
33281
33420
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
33282
33421
|
}
|
|
33283
33422
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -33596,9 +33735,9 @@ function clean(file, options2 = {}) {
|
|
|
33596
33735
|
}
|
|
33597
33736
|
|
|
33598
33737
|
// src/commands/transcript/shared.ts
|
|
33599
|
-
import * as
|
|
33738
|
+
import * as readline4 from "readline";
|
|
33600
33739
|
function createReadlineInterface() {
|
|
33601
|
-
return
|
|
33740
|
+
return readline4.createInterface({
|
|
33602
33741
|
input: process.stdin,
|
|
33603
33742
|
output: process.stdout
|
|
33604
33743
|
});
|
|
@@ -33989,6 +34128,11 @@ var checks = [
|
|
|
33989
34128
|
description: "Check every assistConfigSchema key is surfaced in some command's --help via configHelp",
|
|
33990
34129
|
action: configKeys
|
|
33991
34130
|
},
|
|
34131
|
+
{
|
|
34132
|
+
name: "advice-fragments",
|
|
34133
|
+
description: "Check ADVICE_FRAGMENT_NAMES matches the fragments shipped in claude/advice, so advice.include/exclude can name every one",
|
|
34134
|
+
action: adviceFragments
|
|
34135
|
+
},
|
|
33992
34136
|
{
|
|
33993
34137
|
name: "migrations",
|
|
33994
34138
|
description: "Check DB migrations are sequentially numbered, append-only, and gate destructive DDL behind an acknowledgement marker",
|
|
@@ -35659,7 +35803,7 @@ function listDaemonPids() {
|
|
|
35659
35803
|
}
|
|
35660
35804
|
|
|
35661
35805
|
// src/commands/sessions/daemon/queryDaemon.ts
|
|
35662
|
-
import { createInterface as
|
|
35806
|
+
import { createInterface as createInterface7 } from "readline";
|
|
35663
35807
|
var STATUS_TIMEOUT_MS = 5e3;
|
|
35664
35808
|
function queryDaemon(socket) {
|
|
35665
35809
|
socket.write(`${JSON.stringify({ type: "ping" })}
|
|
@@ -35668,7 +35812,7 @@ function queryDaemon(socket) {
|
|
|
35668
35812
|
const result = { sessions: [] };
|
|
35669
35813
|
const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
|
|
35670
35814
|
const timer = setTimeout(() => resolve25(result), STATUS_TIMEOUT_MS);
|
|
35671
|
-
const lines2 =
|
|
35815
|
+
const lines2 = createInterface7({ input: socket });
|
|
35672
35816
|
lines2.on("error", () => {
|
|
35673
35817
|
});
|
|
35674
35818
|
lines2.on("line", (line) => {
|
|
@@ -35758,7 +35902,7 @@ function reportStrays(pids) {
|
|
|
35758
35902
|
}
|
|
35759
35903
|
|
|
35760
35904
|
// src/commands/sessions/daemon/drainDaemon.ts
|
|
35761
|
-
import { createInterface as
|
|
35905
|
+
import { createInterface as createInterface8 } from "readline";
|
|
35762
35906
|
|
|
35763
35907
|
// src/commands/sessions/daemon/clearPersistedSessionsOnDrain.ts
|
|
35764
35908
|
function clearPersistedSessionsOnDrain() {
|
|
@@ -35800,7 +35944,7 @@ async function drainDaemon(options2 = {}) {
|
|
|
35800
35944
|
clearPersistedSessionsOnDrain();
|
|
35801
35945
|
return;
|
|
35802
35946
|
}
|
|
35803
|
-
const lines2 =
|
|
35947
|
+
const lines2 = createInterface8({ input: socket });
|
|
35804
35948
|
lines2.on("error", () => {
|
|
35805
35949
|
});
|
|
35806
35950
|
const live = await liveSessions(lines2);
|
|
@@ -36264,7 +36408,7 @@ function serverRunMeta(runName, cwd) {
|
|
|
36264
36408
|
}
|
|
36265
36409
|
|
|
36266
36410
|
// src/commands/sessions/daemon/readDesignSystemPrompt.ts
|
|
36267
|
-
import * as
|
|
36411
|
+
import * as fs50 from "fs";
|
|
36268
36412
|
import * as path87 from "path";
|
|
36269
36413
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
36270
36414
|
var __filename5 = fileURLToPath11(import.meta.url);
|
|
@@ -36276,7 +36420,7 @@ function readDesignSystemPrompt() {
|
|
|
36276
36420
|
"claude",
|
|
36277
36421
|
"design-system-prompt.md"
|
|
36278
36422
|
);
|
|
36279
|
-
return
|
|
36423
|
+
return fs50.readFileSync(promptPath, "utf8");
|
|
36280
36424
|
}
|
|
36281
36425
|
|
|
36282
36426
|
// src/commands/sessions/daemon/spawnClaude.ts
|
|
@@ -37365,7 +37509,7 @@ function reportSilentFailure(session, clients) {
|
|
|
37365
37509
|
}
|
|
37366
37510
|
|
|
37367
37511
|
// src/commands/sessions/shared/codex/resolveCodexSessionId.ts
|
|
37368
|
-
import * as
|
|
37512
|
+
import * as fs51 from "fs";
|
|
37369
37513
|
var META_LINES = 5;
|
|
37370
37514
|
async function resolveCodexSessionId(cwd, sinceMs) {
|
|
37371
37515
|
if (!cwd) return null;
|
|
@@ -37394,7 +37538,7 @@ async function startedIn(file, cwd, sinceMs) {
|
|
|
37394
37538
|
}
|
|
37395
37539
|
async function touchedSince(file, sinceMs) {
|
|
37396
37540
|
try {
|
|
37397
|
-
return (await
|
|
37541
|
+
return (await fs51.promises.stat(file)).mtimeMs >= sinceMs;
|
|
37398
37542
|
} catch {
|
|
37399
37543
|
return false;
|
|
37400
37544
|
}
|
|
@@ -37428,7 +37572,7 @@ function bindCodexSession(session, notify2) {
|
|
|
37428
37572
|
import { watch as watch3 } from "fs";
|
|
37429
37573
|
|
|
37430
37574
|
// src/commands/sessions/shared/findTranscriptPathSync.ts
|
|
37431
|
-
import * as
|
|
37575
|
+
import * as fs52 from "fs";
|
|
37432
37576
|
import * as path88 from "path";
|
|
37433
37577
|
function projectDirForCwd(cwd) {
|
|
37434
37578
|
return path88.join(claudeProjectsRoot(), projectSlug(cwd));
|
|
@@ -37438,11 +37582,11 @@ function transcriptPathFor(cwd, claudeSessionId) {
|
|
|
37438
37582
|
}
|
|
37439
37583
|
function findTranscriptPathSync(cwd, claudeSessionId) {
|
|
37440
37584
|
const direct = transcriptPathFor(cwd, claudeSessionId);
|
|
37441
|
-
if (
|
|
37585
|
+
if (fs52.existsSync(direct)) return direct;
|
|
37442
37586
|
const dir = projectDirForCwd(cwd);
|
|
37443
37587
|
let files;
|
|
37444
37588
|
try {
|
|
37445
|
-
files =
|
|
37589
|
+
files = fs52.readdirSync(dir);
|
|
37446
37590
|
} catch {
|
|
37447
37591
|
return null;
|
|
37448
37592
|
}
|
|
@@ -37456,14 +37600,14 @@ function findTranscriptPathSync(cwd, claudeSessionId) {
|
|
|
37456
37600
|
function headContainsSessionId(filePath, claudeSessionId) {
|
|
37457
37601
|
let fd;
|
|
37458
37602
|
try {
|
|
37459
|
-
fd =
|
|
37603
|
+
fd = fs52.openSync(filePath, "r");
|
|
37460
37604
|
const buf = Buffer.alloc(16384);
|
|
37461
|
-
const bytesRead =
|
|
37605
|
+
const bytesRead = fs52.readSync(fd, buf, 0, buf.length, 0);
|
|
37462
37606
|
return buf.toString("utf8", 0, bytesRead).includes(claudeSessionId);
|
|
37463
37607
|
} catch {
|
|
37464
37608
|
return false;
|
|
37465
37609
|
} finally {
|
|
37466
|
-
if (fd !== void 0)
|
|
37610
|
+
if (fd !== void 0) fs52.closeSync(fd);
|
|
37467
37611
|
}
|
|
37468
37612
|
}
|
|
37469
37613
|
|
|
@@ -37633,7 +37777,7 @@ function asRecord3(value) {
|
|
|
37633
37777
|
}
|
|
37634
37778
|
|
|
37635
37779
|
// src/commands/sessions/shared/readTranscriptTail.ts
|
|
37636
|
-
import * as
|
|
37780
|
+
import * as fs53 from "fs";
|
|
37637
37781
|
var DEFAULT_MAX_BYTES = 256 * 1024;
|
|
37638
37782
|
function parseTailEntries(raw) {
|
|
37639
37783
|
const entries = [];
|
|
@@ -37657,7 +37801,7 @@ function dropPartialFirstLine(raw, sliced) {
|
|
|
37657
37801
|
async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
|
|
37658
37802
|
let handle;
|
|
37659
37803
|
try {
|
|
37660
|
-
handle = await
|
|
37804
|
+
handle = await fs53.promises.open(filePath, "r");
|
|
37661
37805
|
const { size } = await handle.stat();
|
|
37662
37806
|
const start3 = Math.max(0, size - maxBytes);
|
|
37663
37807
|
const length = size - start3;
|
|
@@ -37676,20 +37820,20 @@ async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
|
|
|
37676
37820
|
function readTranscriptTailSync(filePath, maxBytes = DEFAULT_MAX_BYTES) {
|
|
37677
37821
|
let fd;
|
|
37678
37822
|
try {
|
|
37679
|
-
fd =
|
|
37680
|
-
const { size } =
|
|
37823
|
+
fd = fs53.openSync(filePath, "r");
|
|
37824
|
+
const { size } = fs53.fstatSync(fd);
|
|
37681
37825
|
const start3 = Math.max(0, size - maxBytes);
|
|
37682
37826
|
const length = size - start3;
|
|
37683
37827
|
if (length === 0) return [];
|
|
37684
37828
|
const buf = Buffer.alloc(length);
|
|
37685
|
-
|
|
37829
|
+
fs53.readSync(fd, buf, 0, length, start3);
|
|
37686
37830
|
return parseTailEntries(
|
|
37687
37831
|
dropPartialFirstLine(buf.toString("utf8"), start3 > 0)
|
|
37688
37832
|
);
|
|
37689
37833
|
} catch {
|
|
37690
37834
|
return [];
|
|
37691
37835
|
} finally {
|
|
37692
|
-
if (fd !== void 0)
|
|
37836
|
+
if (fd !== void 0) fs53.closeSync(fd);
|
|
37693
37837
|
}
|
|
37694
37838
|
}
|
|
37695
37839
|
|
|
@@ -38068,7 +38212,7 @@ async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
|
|
|
38068
38212
|
}
|
|
38069
38213
|
|
|
38070
38214
|
// src/commands/sessions/shared/transcriptUsage.ts
|
|
38071
|
-
import * as
|
|
38215
|
+
import * as fs54 from "fs";
|
|
38072
38216
|
function transcriptUsage(lines2) {
|
|
38073
38217
|
const byId = /* @__PURE__ */ new Map();
|
|
38074
38218
|
for (const line of lines2) {
|
|
@@ -38092,7 +38236,7 @@ function transcriptUsage(lines2) {
|
|
|
38092
38236
|
return [...byId.values()];
|
|
38093
38237
|
}
|
|
38094
38238
|
async function readTranscriptUsage(transcriptPath2) {
|
|
38095
|
-
const content = await
|
|
38239
|
+
const content = await fs54.promises.readFile(transcriptPath2, "utf8");
|
|
38096
38240
|
return transcriptUsage(content.split("\n"));
|
|
38097
38241
|
}
|
|
38098
38242
|
|
|
@@ -39785,10 +39929,10 @@ async function isWindowsDaemonRunning() {
|
|
|
39785
39929
|
import { spawn as spawn11 } from "child_process";
|
|
39786
39930
|
|
|
39787
39931
|
// src/commands/sessions/daemon/logChildStream.ts
|
|
39788
|
-
import { createInterface as
|
|
39932
|
+
import { createInterface as createInterface9 } from "readline";
|
|
39789
39933
|
function logChildStream(stream, label2, onLine) {
|
|
39790
39934
|
if (!stream) return;
|
|
39791
|
-
const lines2 =
|
|
39935
|
+
const lines2 = createInterface9({ input: stream });
|
|
39792
39936
|
lines2.on("line", (line) => {
|
|
39793
39937
|
daemonLog(`[${label2}] ${line}`);
|
|
39794
39938
|
onLine?.(line);
|
|
@@ -40218,7 +40362,7 @@ function isWindowsIo(data) {
|
|
|
40218
40362
|
}
|
|
40219
40363
|
|
|
40220
40364
|
// src/commands/sessions/daemon/WindowsConnection.ts
|
|
40221
|
-
import { createInterface as
|
|
40365
|
+
import { createInterface as createInterface10 } from "readline";
|
|
40222
40366
|
|
|
40223
40367
|
// src/commands/sessions/daemon/LaunchCircuitBreaker.ts
|
|
40224
40368
|
var MAX_FAILURES = 3;
|
|
@@ -40305,7 +40449,7 @@ var WindowsConnection = class {
|
|
|
40305
40449
|
return socket;
|
|
40306
40450
|
}
|
|
40307
40451
|
wire(socket) {
|
|
40308
|
-
const lines2 =
|
|
40452
|
+
const lines2 = createInterface10({ input: socket });
|
|
40309
40453
|
lines2.on("error", () => {
|
|
40310
40454
|
});
|
|
40311
40455
|
lines2.on("line", (line) => this.deps.onLine(line));
|
|
@@ -40914,7 +41058,7 @@ function exitAfterFlush(code) {
|
|
|
40914
41058
|
}
|
|
40915
41059
|
|
|
40916
41060
|
// src/commands/sessions/daemon/handleConnection.ts
|
|
40917
|
-
import { createInterface as
|
|
41061
|
+
import { createInterface as createInterface11 } from "readline";
|
|
40918
41062
|
|
|
40919
41063
|
// src/commands/sessions/daemon/creator.ts
|
|
40920
41064
|
function creator(isNew, spawn13) {
|
|
@@ -40989,7 +41133,7 @@ function handleSetStatus(client, m, d) {
|
|
|
40989
41133
|
}
|
|
40990
41134
|
|
|
40991
41135
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
40992
|
-
import * as
|
|
41136
|
+
import * as fs55 from "fs";
|
|
40993
41137
|
|
|
40994
41138
|
// src/commands/sessions/shared/codex/findCodexRolloutPath.ts
|
|
40995
41139
|
import * as path89 from "path";
|
|
@@ -41072,7 +41216,7 @@ async function parseTranscript(sessionId) {
|
|
|
41072
41216
|
}
|
|
41073
41217
|
async function readMessages(filePath, parse4) {
|
|
41074
41218
|
try {
|
|
41075
|
-
const raw = await
|
|
41219
|
+
const raw = await fs55.promises.readFile(filePath, "utf8");
|
|
41076
41220
|
return parse4(raw.split("\n"));
|
|
41077
41221
|
} catch {
|
|
41078
41222
|
return [];
|
|
@@ -41278,7 +41422,7 @@ function handleConnection(socket, manager) {
|
|
|
41278
41422
|
};
|
|
41279
41423
|
manager.addClient(client);
|
|
41280
41424
|
manager.clients.greet(client);
|
|
41281
|
-
const lines2 =
|
|
41425
|
+
const lines2 = createInterface11({ input: socket });
|
|
41282
41426
|
lines2.on("error", () => {
|
|
41283
41427
|
});
|
|
41284
41428
|
lines2.on("line", (line) => {
|
|
@@ -41600,17 +41744,17 @@ async function renameSession(title) {
|
|
|
41600
41744
|
}
|
|
41601
41745
|
|
|
41602
41746
|
// src/commands/sessions/summarise/index.ts
|
|
41603
|
-
import * as
|
|
41747
|
+
import * as fs57 from "fs";
|
|
41604
41748
|
import chalk230 from "chalk";
|
|
41605
41749
|
|
|
41606
41750
|
// src/commands/sessions/summarise/shared.ts
|
|
41607
|
-
import * as
|
|
41751
|
+
import * as fs56 from "fs";
|
|
41608
41752
|
function writeSummary(jsonlPath2, summary) {
|
|
41609
|
-
|
|
41753
|
+
fs56.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
41610
41754
|
`, "utf8");
|
|
41611
41755
|
}
|
|
41612
41756
|
function hasSummary(jsonlPath2) {
|
|
41613
|
-
return
|
|
41757
|
+
return fs56.existsSync(summaryPathFor(jsonlPath2));
|
|
41614
41758
|
}
|
|
41615
41759
|
function summaryPathFor(jsonlPath2) {
|
|
41616
41760
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -41682,7 +41826,7 @@ function selectCandidates(files, options2) {
|
|
|
41682
41826
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
41683
41827
|
candidates.sort((a, b) => {
|
|
41684
41828
|
try {
|
|
41685
|
-
return
|
|
41829
|
+
return fs57.statSync(b).mtimeMs - fs57.statSync(a).mtimeMs;
|
|
41686
41830
|
} catch {
|
|
41687
41831
|
return 0;
|
|
41688
41832
|
}
|
|
@@ -42005,6 +42149,7 @@ configHelp(screenshotCommand, rootConfigHelp.screenshot);
|
|
|
42005
42149
|
registerActivity(program);
|
|
42006
42150
|
registerAdvise(program);
|
|
42007
42151
|
registerBackup(program);
|
|
42152
|
+
registerChart(program);
|
|
42008
42153
|
registerDb(program);
|
|
42009
42154
|
registerDbMigration(program);
|
|
42010
42155
|
registerCliHook(program);
|