@hasna/configs 0.2.16 → 0.2.18
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/db/database.test.d.ts +2 -0
- package/dist/db/database.test.d.ts.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -0
- package/dist/lib/export-import.test.d.ts +2 -0
- package/dist/lib/export-import.test.d.ts.map +1 -0
- package/dist/lib/sync-known.test.d.ts +2 -0
- package/dist/lib/sync-known.test.d.ts.map +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +13 -3
- package/package.json +3 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.test.d.ts","sourceRoot":"","sources":["../../src/db/database.test.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ export { registerMachine, updateMachineApplied, listMachines, currentHostname, c
|
|
|
6
6
|
export { getDatabase, resetDatabase, uuid, now, slugify } from "./db/database.js";
|
|
7
7
|
export { applyConfig, applyConfigs, expandPath } from "./lib/apply.js";
|
|
8
8
|
export type { ApplyOptions } from "./lib/apply.js";
|
|
9
|
-
export { syncKnown, syncToDisk, diffConfig, detectCategory, detectAgent, detectFormat, KNOWN_CONFIGS } from "./lib/sync.js";
|
|
9
|
+
export { syncKnown, syncToDisk, syncProject, diffConfig, detectCategory, detectAgent, detectFormat, KNOWN_CONFIGS, PROJECT_CONFIG_FILES } from "./lib/sync.js";
|
|
10
10
|
export { syncFromDir, syncToDir } from "./lib/sync-dir.js";
|
|
11
|
-
export type { SyncKnownOptions, SyncToDiskOptions } from "./lib/sync.js";
|
|
11
|
+
export type { SyncKnownOptions, SyncToDiskOptions, SyncProjectOptions, KnownConfig } from "./lib/sync.js";
|
|
12
12
|
export type { SyncFromDirOptions } from "./lib/sync-dir.js";
|
|
13
13
|
export { exportConfigs } from "./lib/export.js";
|
|
14
14
|
export { importConfigs } from "./lib/import.js";
|
|
@@ -16,4 +16,6 @@ export type { ExportOptions } from "./lib/export.js";
|
|
|
16
16
|
export type { ImportOptions, ImportResult } from "./lib/import.js";
|
|
17
17
|
export { parseTemplateVars, extractTemplateVars, renderTemplate, isTemplate } from "./lib/template.js";
|
|
18
18
|
export type { TemplateVar } from "./lib/template.js";
|
|
19
|
+
export { redactContent, scanSecrets, hasSecrets } from "./lib/redact.js";
|
|
20
|
+
export type { RedactResult, RedactedVar, RedactFormat } from "./lib/redact.js";
|
|
19
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGlI,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGrH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGzK,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGnH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGlF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACvE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGlI,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGrH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGzK,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGnH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGlF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACvE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC/J,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1G,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACvG,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACzE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -700,6 +700,13 @@ function redactContent(content, format) {
|
|
|
700
700
|
return redactGeneric(content);
|
|
701
701
|
}
|
|
702
702
|
}
|
|
703
|
+
function scanSecrets(content, format) {
|
|
704
|
+
const r = redactContent(content, format);
|
|
705
|
+
return r.redacted;
|
|
706
|
+
}
|
|
707
|
+
function hasSecrets(content, format) {
|
|
708
|
+
return scanSecrets(content, format).length > 0;
|
|
709
|
+
}
|
|
703
710
|
|
|
704
711
|
// src/lib/sync-dir.ts
|
|
705
712
|
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
@@ -801,6 +808,77 @@ var KNOWN_CONFIGS = [
|
|
|
801
808
|
{ path: "~/.npmrc", name: "npmrc", category: "tools", agent: "npm", format: "ini" },
|
|
802
809
|
{ path: "~/.bunfig.toml", name: "bunfig", category: "tools", agent: "global", format: "toml", optional: true }
|
|
803
810
|
];
|
|
811
|
+
var PROJECT_CONFIG_FILES = [
|
|
812
|
+
{ file: "CLAUDE.md", category: "rules", agent: "claude", format: "markdown" },
|
|
813
|
+
{ file: ".claude/settings.json", category: "agent", agent: "claude", format: "json" },
|
|
814
|
+
{ file: ".claude/settings.local.json", category: "agent", agent: "claude", format: "json" },
|
|
815
|
+
{ file: ".mcp.json", category: "mcp", agent: "claude", format: "json" },
|
|
816
|
+
{ file: "AGENTS.md", category: "rules", agent: "codex", format: "markdown" },
|
|
817
|
+
{ file: ".codex/AGENTS.md", category: "rules", agent: "codex", format: "markdown" },
|
|
818
|
+
{ file: "GEMINI.md", category: "rules", agent: "gemini", format: "markdown" }
|
|
819
|
+
];
|
|
820
|
+
async function syncProject(opts) {
|
|
821
|
+
const d = opts.db || getDatabase();
|
|
822
|
+
const absDir = expandPath(opts.projectDir);
|
|
823
|
+
const projectName = absDir.split("/").pop() || "project";
|
|
824
|
+
const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
|
|
825
|
+
const allConfigs = listConfigs(undefined, d);
|
|
826
|
+
for (const pf of PROJECT_CONFIG_FILES) {
|
|
827
|
+
const abs = join3(absDir, pf.file);
|
|
828
|
+
if (!existsSync4(abs))
|
|
829
|
+
continue;
|
|
830
|
+
try {
|
|
831
|
+
const rawContent = readFileSync3(abs, "utf-8");
|
|
832
|
+
if (rawContent.length > 500000) {
|
|
833
|
+
result.skipped.push(pf.file);
|
|
834
|
+
continue;
|
|
835
|
+
}
|
|
836
|
+
const { content, isTemplate } = redactContent(rawContent, pf.format);
|
|
837
|
+
const name = `${projectName}/${pf.file}`;
|
|
838
|
+
const targetPath = abs.replace(homedir3(), "~");
|
|
839
|
+
const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
840
|
+
const existing = allConfigs.find((c) => c.target_path === targetPath || c.slug === slug);
|
|
841
|
+
if (!existing) {
|
|
842
|
+
if (!opts.dryRun)
|
|
843
|
+
createConfig({ name, category: pf.category, agent: pf.agent, format: pf.format, content, target_path: targetPath, is_template: isTemplate }, d);
|
|
844
|
+
result.added++;
|
|
845
|
+
} else if (existing.content !== content) {
|
|
846
|
+
if (!opts.dryRun)
|
|
847
|
+
updateConfig(existing.id, { content, is_template: isTemplate }, d);
|
|
848
|
+
result.updated++;
|
|
849
|
+
} else {
|
|
850
|
+
result.unchanged++;
|
|
851
|
+
}
|
|
852
|
+
} catch {
|
|
853
|
+
result.skipped.push(pf.file);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
const rulesDir = join3(absDir, ".claude", "rules");
|
|
857
|
+
if (existsSync4(rulesDir)) {
|
|
858
|
+
const mdFiles = readdirSync2(rulesDir).filter((f) => f.endsWith(".md"));
|
|
859
|
+
for (const f of mdFiles) {
|
|
860
|
+
const abs = join3(rulesDir, f);
|
|
861
|
+
const raw = readFileSync3(abs, "utf-8");
|
|
862
|
+
const { content, isTemplate } = redactContent(raw, "markdown");
|
|
863
|
+
const name = `${projectName}/rules/${f}`;
|
|
864
|
+
const targetPath = abs.replace(homedir3(), "~");
|
|
865
|
+
const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
866
|
+
const existing = allConfigs.find((c) => c.target_path === targetPath || c.slug === slug);
|
|
867
|
+
if (!existing) {
|
|
868
|
+
if (!opts.dryRun)
|
|
869
|
+
createConfig({ name, category: "rules", agent: "claude", format: "markdown", content, target_path: targetPath, is_template: isTemplate }, d);
|
|
870
|
+
result.added++;
|
|
871
|
+
} else if (existing.content !== content) {
|
|
872
|
+
if (!opts.dryRun)
|
|
873
|
+
updateConfig(existing.id, { content, is_template: isTemplate }, d);
|
|
874
|
+
result.updated++;
|
|
875
|
+
} else {
|
|
876
|
+
result.unchanged++;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
return result;
|
|
881
|
+
}
|
|
804
882
|
async function syncKnown(opts = {}) {
|
|
805
883
|
const d = opts.db || getDatabase();
|
|
806
884
|
const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
|
|
@@ -1134,13 +1212,16 @@ export {
|
|
|
1134
1212
|
updateConfig,
|
|
1135
1213
|
syncToDisk,
|
|
1136
1214
|
syncToDir,
|
|
1215
|
+
syncProject,
|
|
1137
1216
|
syncKnown,
|
|
1138
1217
|
syncFromDir,
|
|
1139
1218
|
slugify,
|
|
1219
|
+
scanSecrets,
|
|
1140
1220
|
resetDatabase,
|
|
1141
1221
|
renderTemplate,
|
|
1142
1222
|
removeConfigFromProfile,
|
|
1143
1223
|
registerMachine,
|
|
1224
|
+
redactContent,
|
|
1144
1225
|
pruneSnapshots,
|
|
1145
1226
|
parseTemplateVars,
|
|
1146
1227
|
now,
|
|
@@ -1150,6 +1231,7 @@ export {
|
|
|
1150
1231
|
listConfigs,
|
|
1151
1232
|
isTemplate,
|
|
1152
1233
|
importConfigs,
|
|
1234
|
+
hasSecrets,
|
|
1153
1235
|
getSnapshotByVersion,
|
|
1154
1236
|
getSnapshot,
|
|
1155
1237
|
getProfileConfigs,
|
|
@@ -1177,6 +1259,7 @@ export {
|
|
|
1177
1259
|
addConfigToProfile,
|
|
1178
1260
|
TemplateRenderError,
|
|
1179
1261
|
ProfileNotFoundError,
|
|
1262
|
+
PROJECT_CONFIG_FILES,
|
|
1180
1263
|
KNOWN_CONFIGS,
|
|
1181
1264
|
ConfigNotFoundError,
|
|
1182
1265
|
ConfigApplyError,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-import.test.d.ts","sourceRoot":"","sources":["../../src/lib/export-import.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-known.test.d.ts","sourceRoot":"","sources":["../../src/lib/sync-known.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;;;;AAgSA,wBAAgE"}
|
package/dist/server/index.js
CHANGED
|
@@ -2608,8 +2608,10 @@ app.post("/api/configs/:id/snapshot", async (c) => {
|
|
|
2608
2608
|
});
|
|
2609
2609
|
app.get("/api/configs/:id/snapshots", (c) => {
|
|
2610
2610
|
try {
|
|
2611
|
+
const { fields } = c.req.query();
|
|
2611
2612
|
const config = getConfig(c.req.param("id"));
|
|
2612
|
-
|
|
2613
|
+
const snaps = listSnapshots(config.id);
|
|
2614
|
+
return c.json(fields ? snaps.map((s) => pickFields(s, fields)) : snaps);
|
|
2613
2615
|
} catch {
|
|
2614
2616
|
return c.json({ error: "Not found" }, 404);
|
|
2615
2617
|
}
|
|
@@ -2631,7 +2633,11 @@ app.post("/api/sync", async (c) => {
|
|
|
2631
2633
|
return c.json({ error: e instanceof Error ? e.message : String(e) }, 422);
|
|
2632
2634
|
}
|
|
2633
2635
|
});
|
|
2634
|
-
app.get("/api/profiles", (c) =>
|
|
2636
|
+
app.get("/api/profiles", (c) => {
|
|
2637
|
+
const { fields } = c.req.query();
|
|
2638
|
+
const profiles = listProfiles();
|
|
2639
|
+
return c.json(fields ? profiles.map((p) => pickFields(p, fields)) : profiles);
|
|
2640
|
+
});
|
|
2635
2641
|
app.post("/api/profiles", async (c) => {
|
|
2636
2642
|
try {
|
|
2637
2643
|
const body = await c.req.json();
|
|
@@ -2677,7 +2683,11 @@ app.post("/api/profiles/:id/apply", async (c) => {
|
|
|
2677
2683
|
return c.json({ error: e instanceof Error ? e.message : String(e) }, 422);
|
|
2678
2684
|
}
|
|
2679
2685
|
});
|
|
2680
|
-
app.get("/api/machines", (c) =>
|
|
2686
|
+
app.get("/api/machines", (c) => {
|
|
2687
|
+
const { fields } = c.req.query();
|
|
2688
|
+
const machines = listMachines();
|
|
2689
|
+
return c.json(fields ? machines.map((m) => pickFields(m, fields)) : machines);
|
|
2690
|
+
});
|
|
2681
2691
|
app.post("/api/machines", async (c) => {
|
|
2682
2692
|
try {
|
|
2683
2693
|
const body = await c.req.json().catch(() => ({}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/configs",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.18",
|
|
4
4
|
"description": "AI coding agent configuration manager — store, version, apply, and share all your AI coding configs. CLI + MCP + REST API + Dashboard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"dev:cli": "bun run src/cli/index.tsx",
|
|
31
31
|
"dev:mcp": "bun run src/mcp/index.ts",
|
|
32
32
|
"dev:serve": "bun run src/server/index.ts",
|
|
33
|
-
"seed": "bun run scripts/seed.ts"
|
|
33
|
+
"seed": "bun run scripts/seed.ts",
|
|
34
|
+
"prepublishOnly": "bun run build"
|
|
34
35
|
},
|
|
35
36
|
"keywords": [
|
|
36
37
|
"configs",
|