@omnidev-ai/cli 0.7.0 → 0.8.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/dist/index.js +131 -79
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -32,26 +32,24 @@ import { existsSync as existsSync4 } from "node:fs";
|
|
|
32
32
|
|
|
33
33
|
// ../adapters/src/claude-code/index.ts
|
|
34
34
|
import { existsSync, mkdirSync } from "node:fs";
|
|
35
|
-
import { writeFile } from "node:fs/promises";
|
|
35
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
36
36
|
import { join } from "node:path";
|
|
37
37
|
var claudeCodeAdapter = {
|
|
38
38
|
id: "claude-code",
|
|
39
39
|
displayName: "Claude Code",
|
|
40
|
-
async init(
|
|
41
|
-
const claudeMdPath = join(ctx.projectRoot, "CLAUDE.md");
|
|
42
|
-
const filesCreated = [];
|
|
43
|
-
if (!existsSync(claudeMdPath)) {
|
|
44
|
-
await writeFile(claudeMdPath, generateClaudeTemplate(), "utf-8");
|
|
45
|
-
filesCreated.push("CLAUDE.md");
|
|
46
|
-
}
|
|
40
|
+
async init(_ctx) {
|
|
47
41
|
return {
|
|
48
|
-
filesCreated,
|
|
49
|
-
message:
|
|
42
|
+
filesCreated: [],
|
|
43
|
+
message: "Claude Code adapter initialized"
|
|
50
44
|
};
|
|
51
45
|
},
|
|
52
46
|
async sync(bundle, ctx) {
|
|
53
47
|
const filesWritten = [];
|
|
54
48
|
const filesDeleted = [];
|
|
49
|
+
const claudeMdPath = join(ctx.projectRoot, "CLAUDE.md");
|
|
50
|
+
const claudeMdContent = await generateClaudeMdContent(ctx.projectRoot);
|
|
51
|
+
await writeFile(claudeMdPath, claudeMdContent, "utf-8");
|
|
52
|
+
filesWritten.push("CLAUDE.md");
|
|
55
53
|
const skillsDir = join(ctx.projectRoot, ".claude", "skills");
|
|
56
54
|
mkdirSync(skillsDir, { recursive: true });
|
|
57
55
|
for (const skill of bundle.skills) {
|
|
@@ -73,51 +71,61 @@ ${skill.instructions}`;
|
|
|
73
71
|
};
|
|
74
72
|
}
|
|
75
73
|
};
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
async function generateClaudeMdContent(projectRoot) {
|
|
75
|
+
const omniMdPath = join(projectRoot, "OMNI.md");
|
|
76
|
+
let omniMdContent = "";
|
|
77
|
+
if (existsSync(omniMdPath)) {
|
|
78
|
+
omniMdContent = await readFile(omniMdPath, "utf-8");
|
|
79
|
+
}
|
|
80
|
+
let content = omniMdContent;
|
|
81
|
+
content += `
|
|
80
82
|
|
|
81
83
|
## OmniDev
|
|
82
84
|
|
|
83
85
|
@import .omni/instructions.md
|
|
84
86
|
`;
|
|
87
|
+
return content;
|
|
85
88
|
}
|
|
86
89
|
// ../adapters/src/codex/index.ts
|
|
87
90
|
import { existsSync as existsSync2 } from "node:fs";
|
|
88
|
-
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
91
|
+
import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
89
92
|
import { join as join2 } from "node:path";
|
|
90
93
|
var codexAdapter = {
|
|
91
94
|
id: "codex",
|
|
92
95
|
displayName: "Codex",
|
|
93
|
-
async init(
|
|
94
|
-
const agentsMdPath = join2(ctx.projectRoot, "AGENTS.md");
|
|
95
|
-
const filesCreated = [];
|
|
96
|
-
if (!existsSync2(agentsMdPath)) {
|
|
97
|
-
await writeFile2(agentsMdPath, generateAgentsTemplate(), "utf-8");
|
|
98
|
-
filesCreated.push("AGENTS.md");
|
|
99
|
-
}
|
|
96
|
+
async init(_ctx) {
|
|
100
97
|
return {
|
|
101
|
-
filesCreated,
|
|
102
|
-
message:
|
|
98
|
+
filesCreated: [],
|
|
99
|
+
message: "Codex adapter initialized"
|
|
103
100
|
};
|
|
104
101
|
},
|
|
105
|
-
async sync(_bundle,
|
|
102
|
+
async sync(_bundle, ctx) {
|
|
103
|
+
const filesWritten = [];
|
|
104
|
+
const filesDeleted = [];
|
|
105
|
+
const agentsMdPath = join2(ctx.projectRoot, "AGENTS.md");
|
|
106
|
+
const agentsMdContent = await generateAgentsMdContent(ctx.projectRoot);
|
|
107
|
+
await writeFile2(agentsMdPath, agentsMdContent, "utf-8");
|
|
108
|
+
filesWritten.push("AGENTS.md");
|
|
106
109
|
return {
|
|
107
|
-
filesWritten
|
|
108
|
-
filesDeleted
|
|
110
|
+
filesWritten,
|
|
111
|
+
filesDeleted
|
|
109
112
|
};
|
|
110
113
|
}
|
|
111
114
|
};
|
|
112
|
-
function
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
async function generateAgentsMdContent(projectRoot) {
|
|
116
|
+
const omniMdPath = join2(projectRoot, "OMNI.md");
|
|
117
|
+
let omniMdContent = "";
|
|
118
|
+
if (existsSync2(omniMdPath)) {
|
|
119
|
+
omniMdContent = await readFile2(omniMdPath, "utf-8");
|
|
120
|
+
}
|
|
121
|
+
let content = omniMdContent;
|
|
122
|
+
content += `
|
|
116
123
|
|
|
117
124
|
## OmniDev
|
|
118
125
|
|
|
119
126
|
@import .omni/instructions.md
|
|
120
127
|
`;
|
|
128
|
+
return content;
|
|
121
129
|
}
|
|
122
130
|
// ../adapters/src/cursor/index.ts
|
|
123
131
|
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
@@ -152,7 +160,7 @@ var cursorAdapter = {
|
|
|
152
160
|
};
|
|
153
161
|
// ../adapters/src/opencode/index.ts
|
|
154
162
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
155
|
-
import { writeFile as writeFile4 } from "node:fs/promises";
|
|
163
|
+
import { readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
|
|
156
164
|
import { join as join4 } from "node:path";
|
|
157
165
|
var opencodeAdapter = {
|
|
158
166
|
id: "opencode",
|
|
@@ -160,33 +168,40 @@ var opencodeAdapter = {
|
|
|
160
168
|
async init(ctx) {
|
|
161
169
|
const opencodeDir = join4(ctx.projectRoot, ".opencode");
|
|
162
170
|
mkdirSync3(opencodeDir, { recursive: true });
|
|
163
|
-
const instructionsPath = join4(opencodeDir, "instructions.md");
|
|
164
|
-
const filesCreated = [];
|
|
165
|
-
if (!existsSync3(instructionsPath)) {
|
|
166
|
-
await writeFile4(instructionsPath, generateOpencodeTemplate(), "utf-8");
|
|
167
|
-
filesCreated.push(".opencode/instructions.md");
|
|
168
|
-
}
|
|
169
171
|
return {
|
|
170
|
-
filesCreated,
|
|
171
|
-
message:
|
|
172
|
+
filesCreated: [".opencode/"],
|
|
173
|
+
message: "OpenCode adapter initialized"
|
|
172
174
|
};
|
|
173
175
|
},
|
|
174
|
-
async sync(_bundle,
|
|
176
|
+
async sync(_bundle, ctx) {
|
|
177
|
+
const filesWritten = [];
|
|
178
|
+
const filesDeleted = [];
|
|
179
|
+
const opencodeDir = join4(ctx.projectRoot, ".opencode");
|
|
180
|
+
mkdirSync3(opencodeDir, { recursive: true });
|
|
181
|
+
const instructionsPath = join4(opencodeDir, "instructions.md");
|
|
182
|
+
const instructionsContent = await generateOpencodeInstructionsContent(ctx.projectRoot);
|
|
183
|
+
await writeFile4(instructionsPath, instructionsContent, "utf-8");
|
|
184
|
+
filesWritten.push(".opencode/instructions.md");
|
|
175
185
|
return {
|
|
176
|
-
filesWritten
|
|
177
|
-
filesDeleted
|
|
186
|
+
filesWritten,
|
|
187
|
+
filesDeleted
|
|
178
188
|
};
|
|
179
189
|
}
|
|
180
190
|
};
|
|
181
|
-
function
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
191
|
+
async function generateOpencodeInstructionsContent(projectRoot) {
|
|
192
|
+
const omniMdPath = join4(projectRoot, "OMNI.md");
|
|
193
|
+
let omniMdContent = "";
|
|
194
|
+
if (existsSync3(omniMdPath)) {
|
|
195
|
+
omniMdContent = await readFile3(omniMdPath, "utf-8");
|
|
196
|
+
}
|
|
197
|
+
let content = omniMdContent;
|
|
198
|
+
content += `
|
|
185
199
|
|
|
186
200
|
## OmniDev
|
|
187
201
|
|
|
188
202
|
@import ../.omni/instructions.md
|
|
189
203
|
`;
|
|
204
|
+
return content;
|
|
190
205
|
}
|
|
191
206
|
// ../adapters/src/registry.ts
|
|
192
207
|
import { readEnabledProviders } from "@omnidev-ai/core";
|
|
@@ -663,7 +678,7 @@ var capabilityRoutes = buildRouteMap2({
|
|
|
663
678
|
// src/commands/doctor.ts
|
|
664
679
|
import { existsSync as existsSync5 } from "node:fs";
|
|
665
680
|
import { execFile } from "node:child_process";
|
|
666
|
-
import { readFile } from "node:fs/promises";
|
|
681
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
667
682
|
import { promisify } from "node:util";
|
|
668
683
|
import { buildCommand as buildCommand3 } from "@stricli/core";
|
|
669
684
|
var doctorCommand = buildCommand3({
|
|
@@ -803,7 +818,7 @@ async function checkRootGitignore() {
|
|
|
803
818
|
fix: "Run: omnidev init"
|
|
804
819
|
};
|
|
805
820
|
}
|
|
806
|
-
const content = await
|
|
821
|
+
const content = await readFile4(gitignorePath, "utf-8");
|
|
807
822
|
const lines = content.split(`
|
|
808
823
|
`).map((line) => line.trim());
|
|
809
824
|
const hasOmniDir = lines.includes(".omni/");
|
|
@@ -844,10 +859,12 @@ async function checkCapabilitiesDir() {
|
|
|
844
859
|
}
|
|
845
860
|
|
|
846
861
|
// src/commands/init.ts
|
|
862
|
+
import { exec } from "node:child_process";
|
|
847
863
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4 } from "node:fs";
|
|
848
|
-
import { readFile as
|
|
864
|
+
import { readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
|
|
865
|
+
import { promisify as promisify2 } from "node:util";
|
|
849
866
|
import {
|
|
850
|
-
|
|
867
|
+
generateOmniMdTemplate,
|
|
851
868
|
loadConfig,
|
|
852
869
|
setActiveProfile,
|
|
853
870
|
syncAgentConfiguration as syncAgentConfiguration3,
|
|
@@ -857,7 +874,17 @@ import {
|
|
|
857
874
|
import { buildCommand as buildCommand4 } from "@stricli/core";
|
|
858
875
|
|
|
859
876
|
// src/prompts/provider.ts
|
|
860
|
-
import { checkbox } from "@inquirer/prompts";
|
|
877
|
+
import { checkbox, confirm } from "@inquirer/prompts";
|
|
878
|
+
var PROVIDER_GITIGNORE_FILES = {
|
|
879
|
+
claude: ["CLAUDE.md", ".claude/"],
|
|
880
|
+
"claude-code": ["CLAUDE.md", ".claude/"],
|
|
881
|
+
cursor: [".cursor/"],
|
|
882
|
+
codex: ["AGENTS.md", ".codex/"],
|
|
883
|
+
opencode: [".opencode/"]
|
|
884
|
+
};
|
|
885
|
+
function getProviderGitignoreFiles(providers) {
|
|
886
|
+
return providers.flatMap((p) => PROVIDER_GITIGNORE_FILES[p] ?? []);
|
|
887
|
+
}
|
|
861
888
|
async function promptForProviders() {
|
|
862
889
|
const answers = await checkbox({
|
|
863
890
|
message: "Select your AI provider(s):",
|
|
@@ -871,8 +898,16 @@ async function promptForProviders() {
|
|
|
871
898
|
});
|
|
872
899
|
return answers;
|
|
873
900
|
}
|
|
901
|
+
async function promptForGitignoreProviderFiles(selectedProviders) {
|
|
902
|
+
const filesToIgnore = getProviderGitignoreFiles(selectedProviders);
|
|
903
|
+
return confirm({
|
|
904
|
+
message: `Add provider files to .gitignore? (${filesToIgnore.join(", ")})`,
|
|
905
|
+
default: false
|
|
906
|
+
});
|
|
907
|
+
}
|
|
874
908
|
|
|
875
909
|
// src/commands/init.ts
|
|
910
|
+
var execAsync = promisify2(exec);
|
|
876
911
|
async function runInit(_flags, providerArg) {
|
|
877
912
|
console.log("Initializing OmniDev...");
|
|
878
913
|
mkdirSync4(".omni", { recursive: true });
|
|
@@ -880,15 +915,31 @@ async function runInit(_flags, providerArg) {
|
|
|
880
915
|
mkdirSync4(".omni/state", { recursive: true });
|
|
881
916
|
await updateRootGitignore();
|
|
882
917
|
let providerIds;
|
|
918
|
+
const isInteractive = !providerArg;
|
|
883
919
|
if (providerArg) {
|
|
884
920
|
providerIds = parseProviderArg(providerArg);
|
|
885
921
|
} else {
|
|
886
922
|
providerIds = await promptForProviders();
|
|
887
923
|
}
|
|
924
|
+
if (isInteractive) {
|
|
925
|
+
const shouldIgnoreProviderFiles = await promptForGitignoreProviderFiles(providerIds);
|
|
926
|
+
if (shouldIgnoreProviderFiles) {
|
|
927
|
+
const filesToIgnore = getProviderGitignoreFiles(providerIds);
|
|
928
|
+
await addProviderFilesToGitignore(filesToIgnore);
|
|
929
|
+
const trackedFiles = await getTrackedProviderFiles(filesToIgnore);
|
|
930
|
+
if (trackedFiles.length > 0) {
|
|
931
|
+
console.log("");
|
|
932
|
+
console.log("⚠️ Some provider files are already tracked in git.");
|
|
933
|
+
console.log(" Run the following to stop tracking them:");
|
|
934
|
+
console.log("");
|
|
935
|
+
console.log(` git rm --cached ${trackedFiles.join(" ")}`);
|
|
936
|
+
console.log("");
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
888
940
|
await writeEnabledProviders(providerIds);
|
|
889
941
|
if (!existsSync6("omni.toml")) {
|
|
890
942
|
await writeConfig2({
|
|
891
|
-
project: "my-project",
|
|
892
943
|
profiles: {
|
|
893
944
|
default: {
|
|
894
945
|
capabilities: []
|
|
@@ -903,8 +954,8 @@ async function runInit(_flags, providerArg) {
|
|
|
903
954
|
});
|
|
904
955
|
await setActiveProfile("default");
|
|
905
956
|
}
|
|
906
|
-
if (!existsSync6(".
|
|
907
|
-
await writeFile5(".
|
|
957
|
+
if (!existsSync6("OMNI.md")) {
|
|
958
|
+
await writeFile5("OMNI.md", generateOmniMdTemplate(), "utf-8");
|
|
908
959
|
}
|
|
909
960
|
const config = await loadConfig();
|
|
910
961
|
const ctx = {
|
|
@@ -913,14 +964,9 @@ async function runInit(_flags, providerArg) {
|
|
|
913
964
|
};
|
|
914
965
|
const allAdapters = getAllAdapters();
|
|
915
966
|
const selectedAdapters = allAdapters.filter((a) => providerIds.includes(a.id));
|
|
916
|
-
const filesCreated = [];
|
|
917
|
-
const filesExisting = [];
|
|
918
967
|
for (const adapter of selectedAdapters) {
|
|
919
968
|
if (adapter.init) {
|
|
920
|
-
|
|
921
|
-
if (result.filesCreated) {
|
|
922
|
-
filesCreated.push(...result.filesCreated);
|
|
923
|
-
}
|
|
969
|
+
await adapter.init(ctx);
|
|
924
970
|
}
|
|
925
971
|
}
|
|
926
972
|
const enabledAdapters = await getEnabledAdapters();
|
|
@@ -928,22 +974,10 @@ async function runInit(_flags, providerArg) {
|
|
|
928
974
|
console.log("");
|
|
929
975
|
console.log(`✓ OmniDev initialized for ${selectedAdapters.map((a) => a.displayName).join(" and ")}!`);
|
|
930
976
|
console.log("");
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
console.log(" • .omni/instructions.md");
|
|
934
|
-
}
|
|
935
|
-
if (filesExisting.length > 0) {
|
|
936
|
-
console.log("\uD83D\uDCDD Add this line to your existing file(s):");
|
|
937
|
-
for (const file of filesExisting) {
|
|
938
|
-
console.log(` • ${file}: @import .omni/instructions.md`);
|
|
939
|
-
}
|
|
940
|
-
}
|
|
977
|
+
console.log("\uD83D\uDCDD Add your project description and instructions to OMNI.md");
|
|
978
|
+
console.log(" This will be transformed into provider-specific files (CLAUDE.md, AGENTS.md, etc.)");
|
|
941
979
|
console.log("");
|
|
942
|
-
console.log("\uD83D\uDCA1
|
|
943
|
-
console.log(" Add provider-specific files to .gitignore:");
|
|
944
|
-
console.log(" CLAUDE.md, .claude/, AGENTS.md, .cursor/, .mcp.json");
|
|
945
|
-
console.log("");
|
|
946
|
-
console.log(" Run 'omnidev capability list' to see available capabilities.");
|
|
980
|
+
console.log("\uD83D\uDCA1 Run 'omnidev capability list' to see available capabilities.");
|
|
947
981
|
}
|
|
948
982
|
var initCommand = buildCommand4({
|
|
949
983
|
parameters: {
|
|
@@ -985,11 +1019,17 @@ function parseProviderArg(arg) {
|
|
|
985
1019
|
return result;
|
|
986
1020
|
}
|
|
987
1021
|
async function updateRootGitignore() {
|
|
988
|
-
const gitignorePath = ".gitignore";
|
|
989
1022
|
const entriesToAdd = [".omni/", "omni.local.toml"];
|
|
1023
|
+
await addToGitignore(entriesToAdd, "OmniDev");
|
|
1024
|
+
}
|
|
1025
|
+
async function addProviderFilesToGitignore(entries) {
|
|
1026
|
+
await addToGitignore(entries, "OmniDev Provider Files");
|
|
1027
|
+
}
|
|
1028
|
+
async function addToGitignore(entriesToAdd, sectionHeader) {
|
|
1029
|
+
const gitignorePath = ".gitignore";
|
|
990
1030
|
let content = "";
|
|
991
1031
|
if (existsSync6(gitignorePath)) {
|
|
992
|
-
content = await
|
|
1032
|
+
content = await readFile5(gitignorePath, "utf-8");
|
|
993
1033
|
}
|
|
994
1034
|
const lines = content.split(`
|
|
995
1035
|
`);
|
|
@@ -1000,12 +1040,24 @@ async function updateRootGitignore() {
|
|
|
1000
1040
|
const needsNewline = content.length > 0 && !content.endsWith(`
|
|
1001
1041
|
`);
|
|
1002
1042
|
const section = `${needsNewline ? `
|
|
1003
|
-
` : ""}#
|
|
1043
|
+
` : ""}# ${sectionHeader}
|
|
1004
1044
|
${missingEntries.join(`
|
|
1005
1045
|
`)}
|
|
1006
1046
|
`;
|
|
1007
1047
|
await writeFile5(gitignorePath, content + section, "utf-8");
|
|
1008
1048
|
}
|
|
1049
|
+
async function getTrackedProviderFiles(files) {
|
|
1050
|
+
const tracked = [];
|
|
1051
|
+
for (const file of files) {
|
|
1052
|
+
try {
|
|
1053
|
+
const { stdout } = await execAsync(`git ls-files "${file}"`);
|
|
1054
|
+
if (stdout.trim()) {
|
|
1055
|
+
tracked.push(file);
|
|
1056
|
+
}
|
|
1057
|
+
} catch {}
|
|
1058
|
+
}
|
|
1059
|
+
return tracked;
|
|
1060
|
+
}
|
|
1009
1061
|
|
|
1010
1062
|
// src/commands/profile.ts
|
|
1011
1063
|
import { existsSync as existsSync7 } from "node:fs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omnidev-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@inquirer/prompts": "^8.1.0",
|
|
31
|
-
"@omnidev-ai/core": "0.
|
|
31
|
+
"@omnidev-ai/core": "0.8.0",
|
|
32
32
|
"@stricli/core": "^1.2.5"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|