agentpacks 0.9.0 → 1.0.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 +41 -14
- package/dist/api.js +403 -179
- package/dist/cli/export-cmd.js +58 -5
- package/dist/cli/generate.js +268 -59
- package/dist/cli/import-cmd.js +203 -95
- package/dist/cli/install.js +1 -0
- package/dist/cli/models-explain.js +56 -0
- package/dist/cli/pack/list.js +56 -0
- package/dist/cli/pack/validate.js +143 -18
- package/dist/cli/publish.js +1 -0
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.js +1 -0
- package/dist/core/index.js +56 -0
- package/dist/core/metarepo.js +1 -0
- package/dist/core/pack-loader.js +56 -0
- package/dist/exporters/cursor-plugin.js +109 -22
- package/dist/exporters/index.js +109 -22
- package/dist/features/index.d.ts +1 -1
- package/dist/features/index.js +59 -0
- package/dist/features/skills.d.ts +22 -0
- package/dist/features/skills.js +60 -1
- package/dist/importers/cursor.js +122 -26
- package/dist/importers/opencode.js +138 -24
- package/dist/importers/rulesync.js +147 -33
- package/dist/index.js +484 -244
- package/dist/node/api.js +403 -179
- package/dist/node/cli/export-cmd.js +58 -5
- package/dist/node/cli/generate.js +268 -59
- package/dist/node/cli/import-cmd.js +203 -95
- package/dist/node/cli/install.js +1 -0
- package/dist/node/cli/models-explain.js +56 -0
- package/dist/node/cli/pack/list.js +56 -0
- package/dist/node/cli/pack/validate.js +143 -18
- package/dist/node/cli/publish.js +1 -0
- package/dist/node/core/config.js +1 -0
- package/dist/node/core/index.js +56 -0
- package/dist/node/core/metarepo.js +1 -0
- package/dist/node/core/pack-loader.js +56 -0
- package/dist/node/exporters/cursor-plugin.js +109 -22
- package/dist/node/exporters/index.js +109 -22
- package/dist/node/features/index.js +59 -0
- package/dist/node/features/skills.js +60 -1
- package/dist/node/importers/cursor.js +122 -26
- package/dist/node/importers/opencode.js +138 -24
- package/dist/node/importers/rulesync.js +147 -33
- package/dist/node/index.js +484 -244
- package/dist/node/targets/claude-code.js +56 -1
- package/dist/node/targets/codex-cli.js +56 -1
- package/dist/node/targets/copilot.js +56 -1
- package/dist/node/targets/cursor.js +56 -5
- package/dist/node/targets/index.js +268 -59
- package/dist/node/targets/mistral-vibe.js +661 -0
- package/dist/node/targets/opencode.js +56 -1
- package/dist/node/targets/registry.js +267 -59
- package/dist/node/utils/model-allowlist.js +6 -2
- package/dist/targets/claude-code.js +56 -1
- package/dist/targets/codex-cli.js +56 -1
- package/dist/targets/copilot.js +56 -1
- package/dist/targets/cursor.js +56 -5
- package/dist/targets/index.d.ts +1 -0
- package/dist/targets/index.js +268 -59
- package/dist/targets/mistral-vibe.d.ts +13 -0
- package/dist/targets/mistral-vibe.js +661 -0
- package/dist/targets/opencode.js +56 -1
- package/dist/targets/registry.js +267 -59
- package/dist/utils/model-allowlist.js +6 -2
- package/package.json +15 -3
package/dist/cli/export-cmd.js
CHANGED
|
@@ -11,6 +11,7 @@ var TARGET_IDS = [
|
|
|
11
11
|
"cursor",
|
|
12
12
|
"claudecode",
|
|
13
13
|
"codexcli",
|
|
14
|
+
"mistralvibe",
|
|
14
15
|
"geminicli",
|
|
15
16
|
"copilot",
|
|
16
17
|
"agentsmd",
|
|
@@ -351,6 +352,8 @@ function agentMatchesTarget(agent, targetId) {
|
|
|
351
352
|
// src/features/skills.ts
|
|
352
353
|
import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
|
|
353
354
|
import { basename as basename4, join as join2 } from "path";
|
|
355
|
+
var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
356
|
+
var SKILL_NAME_MAX_LENGTH = 64;
|
|
354
357
|
function parseSkills(skillsDir, packName) {
|
|
355
358
|
const dirs = listDirs(skillsDir);
|
|
356
359
|
const skills = [];
|
|
@@ -374,6 +377,59 @@ function parseSkillFile(filepath, skillDir, packName) {
|
|
|
374
377
|
content
|
|
375
378
|
};
|
|
376
379
|
}
|
|
380
|
+
function buildSkillFrontmatter(skill) {
|
|
381
|
+
return {
|
|
382
|
+
...skill.meta,
|
|
383
|
+
name: skill.name
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function serializeSkill(skill) {
|
|
387
|
+
return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
|
|
388
|
+
}
|
|
389
|
+
function normalizeImportedSkillMarkdown(source, skillName) {
|
|
390
|
+
const { data, content } = parseFrontmatter(source);
|
|
391
|
+
const normalized = {
|
|
392
|
+
...data,
|
|
393
|
+
name: skillName
|
|
394
|
+
};
|
|
395
|
+
let addedDescription = false;
|
|
396
|
+
const description = normalized.description;
|
|
397
|
+
if (typeof description !== "string" || description.trim().length === 0) {
|
|
398
|
+
normalized.description = `Imported skill: ${skillName}`;
|
|
399
|
+
addedDescription = true;
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
content: serializeFrontmatter(normalized, content),
|
|
403
|
+
addedDescription
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function validateAgentSkillsFrontmatter(skill) {
|
|
407
|
+
const errors = [];
|
|
408
|
+
const dirName = basename4(skill.sourceDir);
|
|
409
|
+
const declaredName = skill.meta.name;
|
|
410
|
+
if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
|
|
411
|
+
errors.push('Missing required frontmatter field "name".');
|
|
412
|
+
} else {
|
|
413
|
+
if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
|
|
414
|
+
errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
|
|
415
|
+
}
|
|
416
|
+
if (!SKILL_NAME_PATTERN.test(declaredName)) {
|
|
417
|
+
errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
|
|
418
|
+
}
|
|
419
|
+
if (declaredName !== dirName) {
|
|
420
|
+
errors.push(`Invalid "name": must match containing directory "${dirName}".`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
const description = skill.meta.description;
|
|
424
|
+
if (typeof description !== "string" || description.trim().length === 0) {
|
|
425
|
+
errors.push('Missing required frontmatter field "description".');
|
|
426
|
+
}
|
|
427
|
+
const allowedTools = skill.meta["allowed-tools"];
|
|
428
|
+
if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
|
|
429
|
+
errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
|
|
430
|
+
}
|
|
431
|
+
return errors;
|
|
432
|
+
}
|
|
377
433
|
function skillMatchesTarget(skill, targetId) {
|
|
378
434
|
const { targets } = skill.meta;
|
|
379
435
|
if (!targets || targets === "*")
|
|
@@ -859,12 +915,9 @@ function exportCursorPlugin(pack, outputDir) {
|
|
|
859
915
|
for (const skill of pack.skills) {
|
|
860
916
|
const skillSubDir = join8(skillsDir, skill.name);
|
|
861
917
|
ensureDir(skillSubDir);
|
|
862
|
-
const fm = {
|
|
863
|
-
name: skill.name,
|
|
864
|
-
description: skill.meta.description ?? ""
|
|
865
|
-
};
|
|
866
918
|
const filepath = join8(skillSubDir, "SKILL.md");
|
|
867
|
-
|
|
919
|
+
const content = serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
|
|
920
|
+
writeFileSync2(filepath, content);
|
|
868
921
|
filesWritten.push(filepath);
|
|
869
922
|
}
|
|
870
923
|
}
|
package/dist/cli/generate.js
CHANGED
|
@@ -11,6 +11,7 @@ var TARGET_IDS = [
|
|
|
11
11
|
"cursor",
|
|
12
12
|
"claudecode",
|
|
13
13
|
"codexcli",
|
|
14
|
+
"mistralvibe",
|
|
14
15
|
"geminicli",
|
|
15
16
|
"copilot",
|
|
16
17
|
"agentsmd",
|
|
@@ -351,6 +352,8 @@ function agentMatchesTarget(agent, targetId) {
|
|
|
351
352
|
// src/features/skills.ts
|
|
352
353
|
import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
|
|
353
354
|
import { basename as basename4, join as join2 } from "path";
|
|
355
|
+
var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
356
|
+
var SKILL_NAME_MAX_LENGTH = 64;
|
|
354
357
|
function parseSkills(skillsDir, packName) {
|
|
355
358
|
const dirs = listDirs(skillsDir);
|
|
356
359
|
const skills = [];
|
|
@@ -374,6 +377,59 @@ function parseSkillFile(filepath, skillDir, packName) {
|
|
|
374
377
|
content
|
|
375
378
|
};
|
|
376
379
|
}
|
|
380
|
+
function buildSkillFrontmatter(skill) {
|
|
381
|
+
return {
|
|
382
|
+
...skill.meta,
|
|
383
|
+
name: skill.name
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function serializeSkill(skill) {
|
|
387
|
+
return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
|
|
388
|
+
}
|
|
389
|
+
function normalizeImportedSkillMarkdown(source, skillName) {
|
|
390
|
+
const { data, content } = parseFrontmatter(source);
|
|
391
|
+
const normalized = {
|
|
392
|
+
...data,
|
|
393
|
+
name: skillName
|
|
394
|
+
};
|
|
395
|
+
let addedDescription = false;
|
|
396
|
+
const description = normalized.description;
|
|
397
|
+
if (typeof description !== "string" || description.trim().length === 0) {
|
|
398
|
+
normalized.description = `Imported skill: ${skillName}`;
|
|
399
|
+
addedDescription = true;
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
content: serializeFrontmatter(normalized, content),
|
|
403
|
+
addedDescription
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function validateAgentSkillsFrontmatter(skill) {
|
|
407
|
+
const errors = [];
|
|
408
|
+
const dirName = basename4(skill.sourceDir);
|
|
409
|
+
const declaredName = skill.meta.name;
|
|
410
|
+
if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
|
|
411
|
+
errors.push('Missing required frontmatter field "name".');
|
|
412
|
+
} else {
|
|
413
|
+
if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
|
|
414
|
+
errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
|
|
415
|
+
}
|
|
416
|
+
if (!SKILL_NAME_PATTERN.test(declaredName)) {
|
|
417
|
+
errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
|
|
418
|
+
}
|
|
419
|
+
if (declaredName !== dirName) {
|
|
420
|
+
errors.push(`Invalid "name": must match containing directory "${dirName}".`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
const description = skill.meta.description;
|
|
424
|
+
if (typeof description !== "string" || description.trim().length === 0) {
|
|
425
|
+
errors.push('Missing required frontmatter field "description".');
|
|
426
|
+
}
|
|
427
|
+
const allowedTools = skill.meta["allowed-tools"];
|
|
428
|
+
if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
|
|
429
|
+
errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
|
|
430
|
+
}
|
|
431
|
+
return errors;
|
|
432
|
+
}
|
|
377
433
|
function skillMatchesTarget(skill, targetId) {
|
|
378
434
|
const { targets } = skill.meta;
|
|
379
435
|
if (!targets || targets === "*")
|
|
@@ -1111,7 +1167,7 @@ class OpenCodeTarget extends BaseTarget {
|
|
|
1111
1167
|
const skillSubDir = join8(skillDir, skill.name);
|
|
1112
1168
|
ensureDir(skillSubDir);
|
|
1113
1169
|
const filepath = join8(skillSubDir, "SKILL.md");
|
|
1114
|
-
writeGeneratedFile(filepath, skill
|
|
1170
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
1115
1171
|
filesWritten.push(filepath);
|
|
1116
1172
|
}
|
|
1117
1173
|
}
|
|
@@ -1366,12 +1422,8 @@ class CursorTarget extends BaseTarget {
|
|
|
1366
1422
|
for (const skill of skills) {
|
|
1367
1423
|
const skillSubDir = join9(skillsDir, skill.name);
|
|
1368
1424
|
ensureDir(skillSubDir);
|
|
1369
|
-
const frontmatter = {
|
|
1370
|
-
name: skill.name,
|
|
1371
|
-
description: skill.meta.description ?? ""
|
|
1372
|
-
};
|
|
1373
1425
|
const filepath = join9(skillSubDir, "SKILL.md");
|
|
1374
|
-
const content =
|
|
1426
|
+
const content = serializeSkill(skill);
|
|
1375
1427
|
writeGeneratedFile(filepath, content);
|
|
1376
1428
|
filesWritten.push(filepath);
|
|
1377
1429
|
}
|
|
@@ -1671,7 +1723,7 @@ ${content}`;
|
|
|
1671
1723
|
const skillSubDir = join10(skillsDir, skill.name);
|
|
1672
1724
|
ensureDir(skillSubDir);
|
|
1673
1725
|
const filepath = join10(skillSubDir, "SKILL.md");
|
|
1674
|
-
writeGeneratedFile(filepath, skill
|
|
1726
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
1675
1727
|
filesWritten.push(filepath);
|
|
1676
1728
|
}
|
|
1677
1729
|
}
|
|
@@ -1801,7 +1853,7 @@ class CodexCliTarget extends BaseTarget {
|
|
|
1801
1853
|
const skillSubDir = join11(skillsDir, skill.name);
|
|
1802
1854
|
ensureDir(skillSubDir);
|
|
1803
1855
|
const filepath = join11(skillSubDir, "SKILL.md");
|
|
1804
|
-
writeGeneratedFile(filepath, skill
|
|
1856
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
1805
1857
|
filesWritten.push(filepath);
|
|
1806
1858
|
}
|
|
1807
1859
|
}
|
|
@@ -1809,12 +1861,168 @@ class CodexCliTarget extends BaseTarget {
|
|
|
1809
1861
|
}
|
|
1810
1862
|
}
|
|
1811
1863
|
|
|
1812
|
-
// src/targets/
|
|
1864
|
+
// src/targets/mistral-vibe.ts
|
|
1813
1865
|
import { resolve as resolve7, join as join12 } from "path";
|
|
1814
|
-
var TARGET_ID5 = "
|
|
1866
|
+
var TARGET_ID5 = "mistralvibe";
|
|
1815
1867
|
|
|
1816
|
-
class
|
|
1868
|
+
class MistralVibeTarget extends BaseTarget {
|
|
1817
1869
|
id = TARGET_ID5;
|
|
1870
|
+
name = "Mistral Vibe";
|
|
1871
|
+
supportedFeatures = [
|
|
1872
|
+
"rules",
|
|
1873
|
+
"commands",
|
|
1874
|
+
"agents",
|
|
1875
|
+
"skills",
|
|
1876
|
+
"mcp",
|
|
1877
|
+
"ignore",
|
|
1878
|
+
"models"
|
|
1879
|
+
];
|
|
1880
|
+
generate(options) {
|
|
1881
|
+
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
1882
|
+
const root = resolve7(projectRoot, baseDir);
|
|
1883
|
+
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
1884
|
+
const filesWritten = [];
|
|
1885
|
+
const filesDeleted = [];
|
|
1886
|
+
const warnings = [];
|
|
1887
|
+
const vibeDir = resolve7(root, ".vibe");
|
|
1888
|
+
ensureDir(vibeDir);
|
|
1889
|
+
if (effective.includes("rules")) {
|
|
1890
|
+
const rulesDir = resolve7(vibeDir, "rules");
|
|
1891
|
+
if (deleteExisting) {
|
|
1892
|
+
removeIfExists(rulesDir);
|
|
1893
|
+
filesDeleted.push(rulesDir);
|
|
1894
|
+
}
|
|
1895
|
+
ensureDir(rulesDir);
|
|
1896
|
+
const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
|
|
1897
|
+
for (const rule of rules) {
|
|
1898
|
+
const filepath = join12(rulesDir, `${rule.name}.md`);
|
|
1899
|
+
writeGeneratedFile(filepath, rule.content);
|
|
1900
|
+
filesWritten.push(filepath);
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
if (effective.includes("agents")) {
|
|
1904
|
+
const agentsDir = resolve7(vibeDir, "agents");
|
|
1905
|
+
if (deleteExisting) {
|
|
1906
|
+
removeIfExists(agentsDir);
|
|
1907
|
+
filesDeleted.push(agentsDir);
|
|
1908
|
+
}
|
|
1909
|
+
ensureDir(agentsDir);
|
|
1910
|
+
const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID5));
|
|
1911
|
+
for (const agent of agents) {
|
|
1912
|
+
const filepath = join12(agentsDir, `${agent.name}.md`);
|
|
1913
|
+
writeGeneratedFile(filepath, agent.content);
|
|
1914
|
+
filesWritten.push(filepath);
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
if (effective.includes("skills")) {
|
|
1918
|
+
const skillsDir = resolve7(vibeDir, "skills");
|
|
1919
|
+
if (deleteExisting) {
|
|
1920
|
+
removeIfExists(skillsDir);
|
|
1921
|
+
filesDeleted.push(skillsDir);
|
|
1922
|
+
}
|
|
1923
|
+
ensureDir(skillsDir);
|
|
1924
|
+
const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID5));
|
|
1925
|
+
for (const skill of skills) {
|
|
1926
|
+
const skillSubDir = join12(skillsDir, skill.name);
|
|
1927
|
+
ensureDir(skillSubDir);
|
|
1928
|
+
const filepath = join12(skillSubDir, "SKILL.md");
|
|
1929
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
1930
|
+
filesWritten.push(filepath);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
if (effective.includes("commands")) {
|
|
1934
|
+
const commandsDir = resolve7(vibeDir, "commands");
|
|
1935
|
+
if (deleteExisting) {
|
|
1936
|
+
removeIfExists(commandsDir);
|
|
1937
|
+
filesDeleted.push(commandsDir);
|
|
1938
|
+
}
|
|
1939
|
+
ensureDir(commandsDir);
|
|
1940
|
+
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID5));
|
|
1941
|
+
for (const command of commands) {
|
|
1942
|
+
const filepath = join12(commandsDir, `${command.name}.md`);
|
|
1943
|
+
writeGeneratedFile(filepath, command.content);
|
|
1944
|
+
filesWritten.push(filepath);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
let hasMcpConfig = false;
|
|
1948
|
+
if (effective.includes("mcp")) {
|
|
1949
|
+
const mcpEntries = Object.entries(features.mcpServers);
|
|
1950
|
+
if (mcpEntries.length > 0) {
|
|
1951
|
+
const filepath = resolve7(vibeDir, "mcp.json");
|
|
1952
|
+
writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
|
|
1953
|
+
header: false
|
|
1954
|
+
});
|
|
1955
|
+
filesWritten.push(filepath);
|
|
1956
|
+
hasMcpConfig = true;
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
if (effective.includes("ignore") && features.ignorePatterns.length > 0) {
|
|
1960
|
+
const filepath = resolve7(root, ".vibeignore");
|
|
1961
|
+
writeGeneratedFile(filepath, features.ignorePatterns.join(`
|
|
1962
|
+
`) + `
|
|
1963
|
+
`);
|
|
1964
|
+
filesWritten.push(filepath);
|
|
1965
|
+
}
|
|
1966
|
+
let defaultModel;
|
|
1967
|
+
let smallModel;
|
|
1968
|
+
if (effective.includes("models") && features.models) {
|
|
1969
|
+
const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID5);
|
|
1970
|
+
defaultModel = resolved.default;
|
|
1971
|
+
smallModel = resolved.small;
|
|
1972
|
+
const guidance = generateModelGuidanceMarkdown(resolved);
|
|
1973
|
+
if (guidance) {
|
|
1974
|
+
const filepath = join12(vibeDir, "model-config.md");
|
|
1975
|
+
writeGeneratedFile(filepath, guidance);
|
|
1976
|
+
filesWritten.push(filepath);
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
const vibeConfig = buildVibeConfigToml({
|
|
1980
|
+
hasMcpConfig,
|
|
1981
|
+
defaultModel,
|
|
1982
|
+
smallModel,
|
|
1983
|
+
profile: options.modelProfile
|
|
1984
|
+
});
|
|
1985
|
+
if (vibeConfig.length > 0) {
|
|
1986
|
+
const filepath = resolve7(vibeDir, "config.toml");
|
|
1987
|
+
writeGeneratedFile(filepath, vibeConfig);
|
|
1988
|
+
filesWritten.push(filepath);
|
|
1989
|
+
}
|
|
1990
|
+
return this.createResult(filesWritten, filesDeleted, warnings);
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
function buildVibeConfigToml(options) {
|
|
1994
|
+
const lines = [];
|
|
1995
|
+
if (options.defaultModel || options.smallModel || options.profile) {
|
|
1996
|
+
lines.push("[models]");
|
|
1997
|
+
if (options.defaultModel) {
|
|
1998
|
+
lines.push(`default = "${escapeTomlString(options.defaultModel)}"`);
|
|
1999
|
+
}
|
|
2000
|
+
if (options.smallModel) {
|
|
2001
|
+
lines.push(`small = "${escapeTomlString(options.smallModel)}"`);
|
|
2002
|
+
}
|
|
2003
|
+
if (options.profile) {
|
|
2004
|
+
lines.push(`profile = "${escapeTomlString(options.profile)}"`);
|
|
2005
|
+
}
|
|
2006
|
+
lines.push("");
|
|
2007
|
+
}
|
|
2008
|
+
if (options.hasMcpConfig) {
|
|
2009
|
+
lines.push("[mcp]");
|
|
2010
|
+
lines.push('config_path = ".vibe/mcp.json"');
|
|
2011
|
+
lines.push("");
|
|
2012
|
+
}
|
|
2013
|
+
return lines.join(`
|
|
2014
|
+
`).trim();
|
|
2015
|
+
}
|
|
2016
|
+
function escapeTomlString(value) {
|
|
2017
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
// src/targets/gemini-cli.ts
|
|
2021
|
+
import { resolve as resolve8, join as join13 } from "path";
|
|
2022
|
+
var TARGET_ID6 = "geminicli";
|
|
2023
|
+
|
|
2024
|
+
class GeminiCliTarget extends BaseTarget {
|
|
2025
|
+
id = TARGET_ID6;
|
|
1818
2026
|
name = "Gemini CLI";
|
|
1819
2027
|
supportedFeatures = [
|
|
1820
2028
|
"rules",
|
|
@@ -1826,49 +2034,49 @@ class GeminiCliTarget extends BaseTarget {
|
|
|
1826
2034
|
];
|
|
1827
2035
|
generate(options) {
|
|
1828
2036
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
1829
|
-
const root =
|
|
2037
|
+
const root = resolve8(projectRoot, baseDir);
|
|
1830
2038
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
1831
2039
|
const filesWritten = [];
|
|
1832
2040
|
const filesDeleted = [];
|
|
1833
2041
|
const warnings = [];
|
|
1834
|
-
const geminiDir =
|
|
2042
|
+
const geminiDir = resolve8(root, ".gemini");
|
|
1835
2043
|
if (effective.includes("rules")) {
|
|
1836
|
-
const rules = features.rules.filter((r) => ruleMatchesTarget(r,
|
|
2044
|
+
const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
|
|
1837
2045
|
const rootRules = getRootRules(rules);
|
|
1838
2046
|
const detailRules = getDetailRules(rules);
|
|
1839
2047
|
if (rootRules.length > 0) {
|
|
1840
2048
|
const geminiMd = rootRules.map((r) => r.content).join(`
|
|
1841
2049
|
|
|
1842
2050
|
`);
|
|
1843
|
-
const filepath =
|
|
2051
|
+
const filepath = resolve8(root, "GEMINI.md");
|
|
1844
2052
|
writeGeneratedFile(filepath, geminiMd);
|
|
1845
2053
|
filesWritten.push(filepath);
|
|
1846
2054
|
}
|
|
1847
2055
|
if (detailRules.length > 0) {
|
|
1848
|
-
const memoriesDir =
|
|
2056
|
+
const memoriesDir = resolve8(geminiDir, "memories");
|
|
1849
2057
|
if (deleteExisting) {
|
|
1850
2058
|
removeIfExists(memoriesDir);
|
|
1851
2059
|
filesDeleted.push(memoriesDir);
|
|
1852
2060
|
}
|
|
1853
2061
|
ensureDir(memoriesDir);
|
|
1854
2062
|
for (const rule of detailRules) {
|
|
1855
|
-
const filepath =
|
|
2063
|
+
const filepath = join13(memoriesDir, `${rule.name}.md`);
|
|
1856
2064
|
writeGeneratedFile(filepath, rule.content);
|
|
1857
2065
|
filesWritten.push(filepath);
|
|
1858
2066
|
}
|
|
1859
2067
|
}
|
|
1860
2068
|
}
|
|
1861
2069
|
if (effective.includes("commands")) {
|
|
1862
|
-
const commandsDir =
|
|
2070
|
+
const commandsDir = resolve8(geminiDir, "commands");
|
|
1863
2071
|
if (deleteExisting) {
|
|
1864
2072
|
removeIfExists(commandsDir);
|
|
1865
2073
|
filesDeleted.push(commandsDir);
|
|
1866
2074
|
}
|
|
1867
2075
|
ensureDir(commandsDir);
|
|
1868
|
-
const commands = features.commands.filter((c) => commandMatchesTarget(c,
|
|
2076
|
+
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID6));
|
|
1869
2077
|
for (const cmd of commands) {
|
|
1870
2078
|
const toml = buildGeminiCommand(cmd.name, cmd.meta.description ?? "", cmd.content);
|
|
1871
|
-
const filepath =
|
|
2079
|
+
const filepath = join13(commandsDir, `${cmd.name}.toml`);
|
|
1872
2080
|
writeGeneratedFile(filepath, toml, { type: "md" });
|
|
1873
2081
|
filesWritten.push(filepath);
|
|
1874
2082
|
}
|
|
@@ -1877,14 +2085,14 @@ class GeminiCliTarget extends BaseTarget {
|
|
|
1877
2085
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
1878
2086
|
if (mcpEntries.length > 0) {
|
|
1879
2087
|
const settings = buildGeminiSettings(features.mcpServers);
|
|
1880
|
-
const filepath =
|
|
2088
|
+
const filepath = resolve8(geminiDir, "settings.json");
|
|
1881
2089
|
writeGeneratedJson(filepath, settings, { header: false });
|
|
1882
2090
|
filesWritten.push(filepath);
|
|
1883
2091
|
}
|
|
1884
2092
|
}
|
|
1885
2093
|
if (effective.includes("ignore")) {
|
|
1886
2094
|
if (features.ignorePatterns.length > 0) {
|
|
1887
|
-
const filepath =
|
|
2095
|
+
const filepath = resolve8(root, ".geminiignore");
|
|
1888
2096
|
const content = features.ignorePatterns.join(`
|
|
1889
2097
|
`) + `
|
|
1890
2098
|
`;
|
|
@@ -1923,11 +2131,11 @@ function buildGeminiSettings(servers) {
|
|
|
1923
2131
|
}
|
|
1924
2132
|
|
|
1925
2133
|
// src/targets/copilot.ts
|
|
1926
|
-
import { resolve as
|
|
1927
|
-
var
|
|
2134
|
+
import { resolve as resolve9, join as join14 } from "path";
|
|
2135
|
+
var TARGET_ID7 = "copilot";
|
|
1928
2136
|
|
|
1929
2137
|
class CopilotTarget extends BaseTarget {
|
|
1930
|
-
id =
|
|
2138
|
+
id = TARGET_ID7;
|
|
1931
2139
|
name = "GitHub Copilot";
|
|
1932
2140
|
supportedFeatures = [
|
|
1933
2141
|
"rules",
|
|
@@ -1940,81 +2148,81 @@ class CopilotTarget extends BaseTarget {
|
|
|
1940
2148
|
];
|
|
1941
2149
|
generate(options) {
|
|
1942
2150
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
1943
|
-
const root =
|
|
2151
|
+
const root = resolve9(projectRoot, baseDir);
|
|
1944
2152
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
1945
2153
|
const filesWritten = [];
|
|
1946
2154
|
const filesDeleted = [];
|
|
1947
2155
|
const warnings = [];
|
|
1948
|
-
const githubDir =
|
|
2156
|
+
const githubDir = resolve9(root, ".github");
|
|
1949
2157
|
if (effective.includes("rules")) {
|
|
1950
|
-
const rules = features.rules.filter((r) => ruleMatchesTarget(r,
|
|
2158
|
+
const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID7));
|
|
1951
2159
|
if (rules.length > 0) {
|
|
1952
2160
|
const combinedContent = rules.map((r) => r.content).join(`
|
|
1953
2161
|
|
|
1954
2162
|
---
|
|
1955
2163
|
|
|
1956
2164
|
`);
|
|
1957
|
-
const filepath =
|
|
2165
|
+
const filepath = resolve9(githubDir, "copilot-instructions.md");
|
|
1958
2166
|
ensureDir(githubDir);
|
|
1959
2167
|
writeGeneratedFile(filepath, combinedContent);
|
|
1960
2168
|
filesWritten.push(filepath);
|
|
1961
2169
|
}
|
|
1962
2170
|
}
|
|
1963
2171
|
if (effective.includes("agents")) {
|
|
1964
|
-
const copilotDir =
|
|
1965
|
-
const agentsDir =
|
|
2172
|
+
const copilotDir = resolve9(githubDir, "copilot");
|
|
2173
|
+
const agentsDir = resolve9(copilotDir, "agents");
|
|
1966
2174
|
if (deleteExisting) {
|
|
1967
2175
|
removeIfExists(agentsDir);
|
|
1968
2176
|
filesDeleted.push(agentsDir);
|
|
1969
2177
|
}
|
|
1970
2178
|
ensureDir(agentsDir);
|
|
1971
|
-
const agents = features.agents.filter((a) => agentMatchesTarget(a,
|
|
2179
|
+
const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID7));
|
|
1972
2180
|
for (const agent of agents) {
|
|
1973
|
-
const filepath =
|
|
2181
|
+
const filepath = join14(agentsDir, `${agent.name}.md`);
|
|
1974
2182
|
writeGeneratedFile(filepath, agent.content);
|
|
1975
2183
|
filesWritten.push(filepath);
|
|
1976
2184
|
}
|
|
1977
2185
|
}
|
|
1978
2186
|
if (effective.includes("skills")) {
|
|
1979
|
-
const copilotDir =
|
|
1980
|
-
const skillsDir =
|
|
2187
|
+
const copilotDir = resolve9(githubDir, "copilot");
|
|
2188
|
+
const skillsDir = resolve9(copilotDir, "skills");
|
|
1981
2189
|
if (deleteExisting) {
|
|
1982
2190
|
removeIfExists(skillsDir);
|
|
1983
2191
|
filesDeleted.push(skillsDir);
|
|
1984
2192
|
}
|
|
1985
2193
|
ensureDir(skillsDir);
|
|
1986
|
-
const skills = features.skills.filter((s) => skillMatchesTarget(s,
|
|
2194
|
+
const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID7));
|
|
1987
2195
|
for (const skill of skills) {
|
|
1988
|
-
const skillSubDir =
|
|
2196
|
+
const skillSubDir = join14(skillsDir, skill.name);
|
|
1989
2197
|
ensureDir(skillSubDir);
|
|
1990
|
-
const filepath =
|
|
1991
|
-
writeGeneratedFile(filepath, skill
|
|
2198
|
+
const filepath = join14(skillSubDir, "SKILL.md");
|
|
2199
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
1992
2200
|
filesWritten.push(filepath);
|
|
1993
2201
|
}
|
|
1994
2202
|
}
|
|
1995
2203
|
if (effective.includes("commands")) {
|
|
1996
|
-
const copilotDir =
|
|
1997
|
-
const commandsDir =
|
|
2204
|
+
const copilotDir = resolve9(githubDir, "copilot");
|
|
2205
|
+
const commandsDir = resolve9(copilotDir, "commands");
|
|
1998
2206
|
if (deleteExisting) {
|
|
1999
2207
|
removeIfExists(commandsDir);
|
|
2000
2208
|
filesDeleted.push(commandsDir);
|
|
2001
2209
|
}
|
|
2002
2210
|
ensureDir(commandsDir);
|
|
2003
|
-
const commands = features.commands.filter((c) => commandMatchesTarget(c,
|
|
2211
|
+
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID7));
|
|
2004
2212
|
for (const cmd of commands) {
|
|
2005
|
-
const filepath =
|
|
2213
|
+
const filepath = join14(commandsDir, `${cmd.name}.md`);
|
|
2006
2214
|
writeGeneratedFile(filepath, cmd.content);
|
|
2007
2215
|
filesWritten.push(filepath);
|
|
2008
2216
|
}
|
|
2009
2217
|
}
|
|
2010
2218
|
if (effective.includes("ignore")) {}
|
|
2011
2219
|
if (effective.includes("models") && features.models) {
|
|
2012
|
-
const resolved = resolveModels(features.models, options.modelProfile,
|
|
2220
|
+
const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID7);
|
|
2013
2221
|
const guidance = generateModelGuidanceMarkdown(resolved);
|
|
2014
2222
|
if (guidance) {
|
|
2015
|
-
const copilotDir =
|
|
2223
|
+
const copilotDir = resolve9(githubDir, "copilot");
|
|
2016
2224
|
ensureDir(copilotDir);
|
|
2017
|
-
const filepath =
|
|
2225
|
+
const filepath = join14(copilotDir, "model-config.md");
|
|
2018
2226
|
writeGeneratedFile(filepath, guidance);
|
|
2019
2227
|
filesWritten.push(filepath);
|
|
2020
2228
|
}
|
|
@@ -2024,14 +2232,14 @@ class CopilotTarget extends BaseTarget {
|
|
|
2024
2232
|
}
|
|
2025
2233
|
|
|
2026
2234
|
// src/targets/agents-md.ts
|
|
2027
|
-
import { resolve as
|
|
2235
|
+
import { resolve as resolve10 } from "path";
|
|
2028
2236
|
class AgentsMdTarget extends BaseTarget {
|
|
2029
2237
|
id = "agentsmd";
|
|
2030
2238
|
name = "AGENTS.md";
|
|
2031
2239
|
supportedFeatures = ["rules"];
|
|
2032
2240
|
generate(options) {
|
|
2033
2241
|
const { projectRoot, baseDir, features } = options;
|
|
2034
|
-
const root =
|
|
2242
|
+
const root = resolve10(projectRoot, baseDir);
|
|
2035
2243
|
const filesWritten = [];
|
|
2036
2244
|
const warnings = [];
|
|
2037
2245
|
const rootRules = getRootRules(features.rules);
|
|
@@ -2043,7 +2251,7 @@ class AgentsMdTarget extends BaseTarget {
|
|
|
2043
2251
|
const content = sections.join(`
|
|
2044
2252
|
|
|
2045
2253
|
`);
|
|
2046
|
-
const filepath =
|
|
2254
|
+
const filepath = resolve10(root, "AGENTS.md");
|
|
2047
2255
|
writeGeneratedFile(filepath, content);
|
|
2048
2256
|
filesWritten.push(filepath);
|
|
2049
2257
|
return this.createResult(filesWritten, [], warnings);
|
|
@@ -2051,7 +2259,7 @@ class AgentsMdTarget extends BaseTarget {
|
|
|
2051
2259
|
}
|
|
2052
2260
|
|
|
2053
2261
|
// src/targets/generic-md-target.ts
|
|
2054
|
-
import { resolve as
|
|
2262
|
+
import { resolve as resolve11, join as join15 } from "path";
|
|
2055
2263
|
function createGenericMdTarget(config) {
|
|
2056
2264
|
return new GenericMdTarget(config);
|
|
2057
2265
|
}
|
|
@@ -2070,16 +2278,16 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2070
2278
|
}
|
|
2071
2279
|
generate(options) {
|
|
2072
2280
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
2073
|
-
const root =
|
|
2281
|
+
const root = resolve11(projectRoot, baseDir);
|
|
2074
2282
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
2075
2283
|
const filesWritten = [];
|
|
2076
2284
|
const filesDeleted = [];
|
|
2077
2285
|
const warnings = [];
|
|
2078
|
-
const configDir =
|
|
2286
|
+
const configDir = resolve11(root, this.config.configDir);
|
|
2079
2287
|
const rulesSubDir = this.config.rulesDir ?? "rules";
|
|
2080
2288
|
const ext = this.config.ruleExtension ?? ".md";
|
|
2081
2289
|
if (effective.includes("rules")) {
|
|
2082
|
-
const rulesDir =
|
|
2290
|
+
const rulesDir = resolve11(configDir, rulesSubDir);
|
|
2083
2291
|
if (deleteExisting) {
|
|
2084
2292
|
removeIfExists(rulesDir);
|
|
2085
2293
|
filesDeleted.push(rulesDir);
|
|
@@ -2087,13 +2295,13 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2087
2295
|
ensureDir(rulesDir);
|
|
2088
2296
|
const rules = features.rules.filter((r) => ruleMatchesTarget(r, this.id));
|
|
2089
2297
|
for (const rule of rules) {
|
|
2090
|
-
const filepath =
|
|
2298
|
+
const filepath = join15(rulesDir, `${rule.name}${ext}`);
|
|
2091
2299
|
writeGeneratedFile(filepath, rule.content);
|
|
2092
2300
|
filesWritten.push(filepath);
|
|
2093
2301
|
}
|
|
2094
2302
|
}
|
|
2095
2303
|
if (effective.includes("commands")) {
|
|
2096
|
-
const commandsDir =
|
|
2304
|
+
const commandsDir = resolve11(configDir, "commands");
|
|
2097
2305
|
if (deleteExisting) {
|
|
2098
2306
|
removeIfExists(commandsDir);
|
|
2099
2307
|
filesDeleted.push(commandsDir);
|
|
@@ -2101,7 +2309,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2101
2309
|
ensureDir(commandsDir);
|
|
2102
2310
|
const commands = features.commands.filter((c) => commandMatchesTarget(c, this.id));
|
|
2103
2311
|
for (const cmd of commands) {
|
|
2104
|
-
const filepath =
|
|
2312
|
+
const filepath = join15(commandsDir, `${cmd.name}.md`);
|
|
2105
2313
|
writeGeneratedFile(filepath, cmd.content);
|
|
2106
2314
|
filesWritten.push(filepath);
|
|
2107
2315
|
}
|
|
@@ -2110,7 +2318,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2110
2318
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
2111
2319
|
if (mcpEntries.length > 0) {
|
|
2112
2320
|
const mcpDir = this.config.mcpInConfigDir ? configDir : root;
|
|
2113
|
-
const filepath =
|
|
2321
|
+
const filepath = resolve11(mcpDir, "mcp.json");
|
|
2114
2322
|
writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
|
|
2115
2323
|
header: false
|
|
2116
2324
|
});
|
|
@@ -2119,7 +2327,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2119
2327
|
}
|
|
2120
2328
|
if (effective.includes("ignore") && this.config.ignoreFile) {
|
|
2121
2329
|
if (features.ignorePatterns.length > 0) {
|
|
2122
|
-
const filepath =
|
|
2330
|
+
const filepath = resolve11(root, this.config.ignoreFile);
|
|
2123
2331
|
writeGeneratedFile(filepath, features.ignorePatterns.join(`
|
|
2124
2332
|
`) + `
|
|
2125
2333
|
`);
|
|
@@ -2131,7 +2339,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2131
2339
|
const guidance = generateModelGuidanceMarkdown(resolved);
|
|
2132
2340
|
if (guidance) {
|
|
2133
2341
|
ensureDir(configDir);
|
|
2134
|
-
const filepath =
|
|
2342
|
+
const filepath = join15(configDir, "model-config.md");
|
|
2135
2343
|
writeGeneratedFile(filepath, guidance);
|
|
2136
2344
|
filesWritten.push(filepath);
|
|
2137
2345
|
}
|
|
@@ -2243,6 +2451,7 @@ var TARGETS = [
|
|
|
2243
2451
|
new CursorTarget,
|
|
2244
2452
|
new ClaudeCodeTarget,
|
|
2245
2453
|
new CodexCliTarget,
|
|
2454
|
+
new MistralVibeTarget,
|
|
2246
2455
|
new GeminiCliTarget,
|
|
2247
2456
|
new CopilotTarget,
|
|
2248
2457
|
new AgentsMdTarget,
|