@kood/claude-code 0.7.8 → 0.7.9
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/dist/index.js +63 -55
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,7 +23,8 @@ var banner = () => {
|
|
|
23
23
|
|
|
24
24
|
// src/commands/init.ts
|
|
25
25
|
import fs9 from "fs-extra";
|
|
26
|
-
import
|
|
26
|
+
import os from "os";
|
|
27
|
+
import path11 from "path";
|
|
27
28
|
|
|
28
29
|
// src/features/templates/template-path-resolver.ts
|
|
29
30
|
import path2 from "path";
|
|
@@ -689,7 +690,7 @@ async function promptScopeSelection(options) {
|
|
|
689
690
|
return { scope: response.value };
|
|
690
691
|
}
|
|
691
692
|
async function promptCodexSync(options) {
|
|
692
|
-
const { providedSyncCodex } = options;
|
|
693
|
+
const { providedSyncCodex, codexSkillsPath } = options;
|
|
693
694
|
if (providedSyncCodex !== void 0) {
|
|
694
695
|
return { syncCodex: providedSyncCodex };
|
|
695
696
|
}
|
|
@@ -697,8 +698,9 @@ async function promptCodexSync(options) {
|
|
|
697
698
|
return { syncCodex: false };
|
|
698
699
|
}
|
|
699
700
|
logger.blank();
|
|
701
|
+
const pathHint = codexSkillsPath ? ` (${codexSkillsPath})` : "";
|
|
700
702
|
const result = await promptConfirm(
|
|
701
|
-
|
|
703
|
+
`Also sync with Codex now?${pathHint}`,
|
|
702
704
|
false
|
|
703
705
|
);
|
|
704
706
|
return { syncCodex: result.confirmed };
|
|
@@ -720,6 +722,7 @@ var CLAUDE_GENERATED_FOLDERS = [
|
|
|
720
722
|
".claude/research/",
|
|
721
723
|
".claude/validation-results/"
|
|
722
724
|
];
|
|
725
|
+
var CODEX_GENERATED_FOLDERS = [".codex/"];
|
|
723
726
|
function normalizeIgnorePattern(pattern) {
|
|
724
727
|
return pattern.replace(/\\/g, "/").replace(/^\.?\//, "").replace(/\/+$/, "").trim();
|
|
725
728
|
}
|
|
@@ -732,9 +735,11 @@ function parseIgnoreLine(line) {
|
|
|
732
735
|
const normalized = normalizeIgnorePattern(rawPattern);
|
|
733
736
|
return normalized || null;
|
|
734
737
|
}
|
|
735
|
-
async function updateGitignore(targetDir) {
|
|
738
|
+
async function updateGitignore(targetDir, options = {}) {
|
|
739
|
+
const { includeCodex = false } = options;
|
|
736
740
|
const gitignorePath = path9.join(targetDir, ".gitignore");
|
|
737
741
|
const sectionComment = "# Claude Code generated files";
|
|
742
|
+
const targetFolders = includeCodex ? [...CLAUDE_GENERATED_FOLDERS, ...CODEX_GENERATED_FOLDERS] : CLAUDE_GENERATED_FOLDERS;
|
|
738
743
|
let content = "";
|
|
739
744
|
let hasGitignore = false;
|
|
740
745
|
try {
|
|
@@ -748,7 +753,7 @@ async function updateGitignore(targetDir) {
|
|
|
748
753
|
const existingPatterns = new Set(
|
|
749
754
|
lines.map((line) => parseIgnoreLine(line)).filter((pattern) => Boolean(pattern))
|
|
750
755
|
);
|
|
751
|
-
const linesToAdd =
|
|
756
|
+
const linesToAdd = targetFolders.filter(
|
|
752
757
|
(folder) => !existingPatterns.has(normalizeIgnorePattern(folder))
|
|
753
758
|
);
|
|
754
759
|
if (linesToAdd.length === 0) {
|
|
@@ -781,15 +786,8 @@ async function updateGitignore(targetDir) {
|
|
|
781
786
|
|
|
782
787
|
// src/features/codex-sync/codex-sync.ts
|
|
783
788
|
import fs8 from "fs-extra";
|
|
784
|
-
import os from "os";
|
|
785
789
|
import path10 from "path";
|
|
786
|
-
|
|
787
|
-
const envCodexHome = process.env.CODEX_HOME?.trim();
|
|
788
|
-
if (envCodexHome) {
|
|
789
|
-
return path10.resolve(envCodexHome);
|
|
790
|
-
}
|
|
791
|
-
return path10.join(os.homedir(), ".codex");
|
|
792
|
-
}
|
|
790
|
+
var RESERVED_CODEX_SKILL_DIRS = /* @__PURE__ */ new Set([".system", "claude-commands"]);
|
|
793
791
|
function normalizeLineEndings(content) {
|
|
794
792
|
return content.replace(/\r\n/g, "\n");
|
|
795
793
|
}
|
|
@@ -836,35 +834,44 @@ ${normalizedCommand}
|
|
|
836
834
|
`;
|
|
837
835
|
}
|
|
838
836
|
async function syncSkills(claudeSkillsDir, codexSkillsDir) {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
837
|
+
await fs8.ensureDir(codexSkillsDir);
|
|
838
|
+
let sourceSkillNames = [];
|
|
839
|
+
if (await fs8.pathExists(claudeSkillsDir)) {
|
|
840
|
+
const sourceEntries = await fs8.readdir(claudeSkillsDir, { withFileTypes: true });
|
|
841
|
+
sourceSkillNames = sourceEntries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => name !== ".system");
|
|
842
|
+
}
|
|
843
|
+
const sourceSkillSet = new Set(sourceSkillNames);
|
|
844
|
+
const codexEntries = await fs8.readdir(codexSkillsDir, { withFileTypes: true });
|
|
845
|
+
for (const entry of codexEntries) {
|
|
845
846
|
if (!entry.isDirectory()) {
|
|
846
847
|
continue;
|
|
847
848
|
}
|
|
848
|
-
if (entry.name
|
|
849
|
+
if (RESERVED_CODEX_SKILL_DIRS.has(entry.name)) {
|
|
849
850
|
continue;
|
|
850
851
|
}
|
|
851
|
-
|
|
852
|
-
|
|
852
|
+
if (!sourceSkillSet.has(entry.name)) {
|
|
853
|
+
await fs8.remove(path10.join(codexSkillsDir, entry.name));
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
for (const skillName of sourceSkillNames) {
|
|
857
|
+
const src = path10.join(claudeSkillsDir, skillName);
|
|
858
|
+
const dest = path10.join(codexSkillsDir, skillName);
|
|
853
859
|
if (await fs8.pathExists(dest)) {
|
|
854
860
|
await fs8.remove(dest);
|
|
855
861
|
}
|
|
856
862
|
await copyRecursive(src, dest, { files: 0, directories: 0 });
|
|
857
|
-
syncedSkills++;
|
|
858
863
|
}
|
|
859
|
-
return
|
|
864
|
+
return sourceSkillNames.length;
|
|
860
865
|
}
|
|
861
866
|
async function syncCommands(claudeCommandsDir, codexCommandsDir) {
|
|
862
867
|
if (!await fs8.pathExists(claudeCommandsDir)) {
|
|
868
|
+
await fs8.remove(codexCommandsDir);
|
|
863
869
|
return 0;
|
|
864
870
|
}
|
|
865
871
|
const entries = await fs8.readdir(claudeCommandsDir, { withFileTypes: true });
|
|
866
872
|
const commandFiles = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
867
873
|
if (commandFiles.length === 0) {
|
|
874
|
+
await fs8.remove(codexCommandsDir);
|
|
868
875
|
return 0;
|
|
869
876
|
}
|
|
870
877
|
await fs8.remove(codexCommandsDir);
|
|
@@ -881,7 +888,7 @@ async function syncCommands(claudeCommandsDir, codexCommandsDir) {
|
|
|
881
888
|
return commandFiles.length;
|
|
882
889
|
}
|
|
883
890
|
async function syncWithCodex(targetDir) {
|
|
884
|
-
const codexHome =
|
|
891
|
+
const codexHome = path10.resolve(targetDir, ".codex");
|
|
885
892
|
const codexSkillsDir = path10.join(codexHome, "skills");
|
|
886
893
|
const codexCommandsDir = path10.join(codexSkillsDir, "claude-commands");
|
|
887
894
|
await fs8.ensureDir(codexSkillsDir);
|
|
@@ -1049,7 +1056,7 @@ var init = async (options) => {
|
|
|
1049
1056
|
const { scope } = await promptScopeSelection({
|
|
1050
1057
|
providedScope: options.scope
|
|
1051
1058
|
});
|
|
1052
|
-
const targetDir = scope === "user" ?
|
|
1059
|
+
const targetDir = scope === "user" ? os.homedir() : projectDir;
|
|
1053
1060
|
const isUserScope = scope === "user";
|
|
1054
1061
|
if (isUserScope) {
|
|
1055
1062
|
logger.blank();
|
|
@@ -1095,54 +1102,55 @@ var init = async (options) => {
|
|
|
1095
1102
|
hasScripts,
|
|
1096
1103
|
scope
|
|
1097
1104
|
);
|
|
1098
|
-
|
|
1105
|
+
const codexSkillsPath = path11.join(targetDir, ".codex", "skills");
|
|
1106
|
+
const { syncCodex } = await promptCodexSync({
|
|
1107
|
+
providedSyncCodex: options.syncCodex,
|
|
1108
|
+
codexSkillsPath
|
|
1109
|
+
});
|
|
1110
|
+
if (syncCodex) {
|
|
1111
|
+
logger.blank();
|
|
1112
|
+
logger.info("Syncing .claude skills/commands to Codex...");
|
|
1099
1113
|
try {
|
|
1100
|
-
await
|
|
1114
|
+
const result = await syncWithCodex(targetDir);
|
|
1115
|
+
if (result.syncedSkills > 0) {
|
|
1116
|
+
logger.step(`Skills synced: ${result.syncedSkills}`);
|
|
1117
|
+
}
|
|
1118
|
+
if (result.syncedCommands > 0) {
|
|
1119
|
+
logger.step(`Commands synced: ${result.syncedCommands}`);
|
|
1120
|
+
}
|
|
1121
|
+
if (result.syncedSkills === 0 && result.syncedCommands === 0) {
|
|
1122
|
+
logger.warn(
|
|
1123
|
+
"Nothing was synced. .claude/skills and .claude/commands were not found."
|
|
1124
|
+
);
|
|
1125
|
+
} else {
|
|
1126
|
+
logger.success(`Codex sync complete: ${result.codexSkillsDir}`);
|
|
1127
|
+
}
|
|
1101
1128
|
} catch (error) {
|
|
1102
1129
|
logger.warn(
|
|
1103
|
-
`
|
|
1130
|
+
`Codex sync failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1104
1131
|
);
|
|
1105
1132
|
}
|
|
1106
1133
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
return;
|
|
1112
|
-
}
|
|
1113
|
-
logger.blank();
|
|
1114
|
-
logger.info("Syncing .claude skills/commands to Codex...");
|
|
1115
|
-
try {
|
|
1116
|
-
const result = await syncWithCodex(targetDir);
|
|
1117
|
-
if (result.syncedSkills > 0) {
|
|
1118
|
-
logger.step(`Skills synced: ${result.syncedSkills}`);
|
|
1119
|
-
}
|
|
1120
|
-
if (result.syncedCommands > 0) {
|
|
1121
|
-
logger.step(`Commands synced: ${result.syncedCommands}`);
|
|
1122
|
-
}
|
|
1123
|
-
if (result.syncedSkills === 0 && result.syncedCommands === 0) {
|
|
1134
|
+
if (!isUserScope) {
|
|
1135
|
+
try {
|
|
1136
|
+
await updateGitignore(targetDir, { includeCodex: syncCodex });
|
|
1137
|
+
} catch (error) {
|
|
1124
1138
|
logger.warn(
|
|
1125
|
-
|
|
1139
|
+
`Failed to update .gitignore: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1126
1140
|
);
|
|
1127
|
-
} else {
|
|
1128
|
-
logger.success(`Codex sync complete: ${result.codexSkillsDir}`);
|
|
1129
1141
|
}
|
|
1130
|
-
} catch (error) {
|
|
1131
|
-
logger.warn(
|
|
1132
|
-
`Codex sync failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1133
|
-
);
|
|
1134
1142
|
}
|
|
1135
1143
|
};
|
|
1136
1144
|
|
|
1137
1145
|
// src/index.ts
|
|
1138
1146
|
var program = new Command();
|
|
1139
|
-
program.name("claude-code").description("Claude Code documentation installer for projects").version("0.7.
|
|
1147
|
+
program.name("claude-code").description("Claude Code documentation installer for projects").version("0.7.9");
|
|
1140
1148
|
program.option(
|
|
1141
1149
|
"-t, --template <names>",
|
|
1142
1150
|
"template names (comma-separated: tanstack-start,hono)"
|
|
1143
1151
|
).option("-f, --force", "overwrite existing files without prompting").option("--cwd <path>", "target directory (default: current directory)").option("--list", "list available templates").option("-s, --skills", "install skills to .claude/skills/").option("-c, --commands", "install commands to .claude/commands/").option("-a, --agents", "install agents to .claude/agents/").option(
|
|
1144
1152
|
"--sync-codex",
|
|
1145
|
-
"sync installed .claude skills/commands to
|
|
1153
|
+
"sync installed .claude skills/commands to selected-scope .codex/skills/"
|
|
1146
1154
|
).option("--scope <scope>", "installation scope (project|user)").action(async (options) => {
|
|
1147
1155
|
banner();
|
|
1148
1156
|
if (options.list) {
|