@hasna/instructions 0.4.1 → 0.4.2
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/cli/index.js +25 -50
- package/dist/db/database.d.ts +1 -1
- package/dist/db/database.d.ts.map +1 -1
- package/dist/index.js +13 -38
- package/dist/mcp/index.js +10 -32
- package/dist/server/index.js +2 -2
- package/dist/status.d.ts +2 -3
- package/dist/status.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2112,21 +2112,17 @@ var init_types = __esm(() => {
|
|
|
2112
2112
|
|
|
2113
2113
|
// src/db/database.ts
|
|
2114
2114
|
import { Database } from "bun:sqlite";
|
|
2115
|
-
import {
|
|
2115
|
+
import { existsSync as existsSync2, mkdirSync, rmSync } from "fs";
|
|
2116
2116
|
import { join as join2 } from "path";
|
|
2117
2117
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2118
2118
|
function getDbPath() {
|
|
2119
|
-
if (process.env["
|
|
2120
|
-
return process.env["
|
|
2119
|
+
if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
|
|
2120
|
+
return process.env["HASNA_INSTRUCTIONS_DB_PATH"];
|
|
2121
2121
|
}
|
|
2122
|
-
if (process.env["CONFIGS_DB_PATH"]) {
|
|
2123
|
-
return process.env["CONFIGS_DB_PATH"];
|
|
2124
|
-
}
|
|
2125
|
-
migrateDotfile();
|
|
2126
2122
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
2127
|
-
const dir = join2(home, ".hasna", "
|
|
2123
|
+
const dir = join2(home, ".hasna", "instructions");
|
|
2128
2124
|
mkdirSync(dir, { recursive: true });
|
|
2129
|
-
return join2(dir, "
|
|
2125
|
+
return join2(dir, "instructions.db");
|
|
2130
2126
|
}
|
|
2131
2127
|
function uuid() {
|
|
2132
2128
|
return randomUUID3();
|
|
@@ -2212,24 +2208,6 @@ function insertFeedback(input, db) {
|
|
|
2212
2208
|
const d = db || getDatabase();
|
|
2213
2209
|
d.run("INSERT INTO feedback (message, email, category, version) VALUES (?, ?, ?, ?)", [input.message, input.email ?? null, input.category ?? "general", input.version ?? null]);
|
|
2214
2210
|
}
|
|
2215
|
-
function migrateDotfile() {
|
|
2216
|
-
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
2217
|
-
const oldDirs = [join2(home, ".open-configs"), join2(home, ".configs")];
|
|
2218
|
-
const newDir = join2(home, ".hasna", "configs");
|
|
2219
|
-
if (existsSync2(newDir))
|
|
2220
|
-
return;
|
|
2221
|
-
for (const oldDir of oldDirs) {
|
|
2222
|
-
if (!existsSync2(oldDir))
|
|
2223
|
-
continue;
|
|
2224
|
-
try {
|
|
2225
|
-
if (!statSync(oldDir).isDirectory())
|
|
2226
|
-
continue;
|
|
2227
|
-
mkdirSync(join2(home, ".hasna"), { recursive: true });
|
|
2228
|
-
cpSync(oldDir, newDir, { recursive: true, force: false });
|
|
2229
|
-
return;
|
|
2230
|
-
} catch {}
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
2211
|
var MIGRATIONS, _db = null;
|
|
2234
2212
|
var init_database = __esm(() => {
|
|
2235
2213
|
MIGRATIONS = [
|
|
@@ -3594,7 +3572,7 @@ var init_redact = __esm(() => {
|
|
|
3594
3572
|
});
|
|
3595
3573
|
|
|
3596
3574
|
// src/lib/sync-dir.ts
|
|
3597
|
-
import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync2, statSync
|
|
3575
|
+
import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
3598
3576
|
import { join as join4, relative } from "path";
|
|
3599
3577
|
import { homedir as homedir4 } from "os";
|
|
3600
3578
|
function shouldSkip(p) {
|
|
@@ -3605,7 +3583,7 @@ async function syncFromDir(dir, opts = {}) {
|
|
|
3605
3583
|
const absDir = expandPath(dir);
|
|
3606
3584
|
if (!existsSync5(absDir))
|
|
3607
3585
|
return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
|
|
3608
|
-
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join4(absDir, f)).filter((f) =>
|
|
3586
|
+
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join4(absDir, f)).filter((f) => statSync(f).isFile());
|
|
3609
3587
|
const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
|
|
3610
3588
|
const home = homedir4();
|
|
3611
3589
|
const allConfigs = await store.listConfigs();
|
|
@@ -5345,7 +5323,7 @@ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join9, parse as
|
|
|
5345
5323
|
|
|
5346
5324
|
// src/lib/session-render.ts
|
|
5347
5325
|
import { createHash } from "crypto";
|
|
5348
|
-
import { existsSync as existsSync9, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as
|
|
5326
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
|
|
5349
5327
|
import { homedir as homedir5 } from "os";
|
|
5350
5328
|
import { basename as basename4, dirname as dirname2, extname as extname3, isAbsolute, join as join8, parse, posix, relative as relative2, resolve as resolve4 } from "path";
|
|
5351
5329
|
var CODEWITH_NATIVE_IMPORTS_ENV = "HASNA_CONFIGS_CODEWITH_NATIVE_IMPORTS";
|
|
@@ -6111,7 +6089,7 @@ function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
|
|
|
6111
6089
|
}
|
|
6112
6090
|
return;
|
|
6113
6091
|
}
|
|
6114
|
-
const stat =
|
|
6092
|
+
const stat = statSync2(resolvedPath);
|
|
6115
6093
|
if (!stat.isFile()) {
|
|
6116
6094
|
throw new Error(`Identity instruction source path is not a file for ${sourceId}: ${sourcePath.path}`);
|
|
6117
6095
|
}
|
|
@@ -6748,14 +6726,12 @@ import { existsSync as existsSync11, readFileSync as readFileSync7 } from "fs";
|
|
|
6748
6726
|
var PACKAGE_NAME = "@hasna/instructions";
|
|
6749
6727
|
var PACKAGE_VERSION = "0.3.0";
|
|
6750
6728
|
function activeDatabaseEnv() {
|
|
6751
|
-
if (process.env["
|
|
6752
|
-
return "
|
|
6753
|
-
if (process.env["CONFIGS_DB_PATH"])
|
|
6754
|
-
return "CONFIGS_DB_PATH";
|
|
6729
|
+
if (process.env["HASNA_INSTRUCTIONS_DB_PATH"])
|
|
6730
|
+
return "HASNA_INSTRUCTIONS_DB_PATH";
|
|
6755
6731
|
return null;
|
|
6756
6732
|
}
|
|
6757
6733
|
function configuredDatabaseKind() {
|
|
6758
|
-
const value = process.env["
|
|
6734
|
+
const value = process.env["HASNA_INSTRUCTIONS_DB_PATH"] ?? "";
|
|
6759
6735
|
return value === ":memory:" || value.startsWith("file::memory:") ? "memory" : "file";
|
|
6760
6736
|
}
|
|
6761
6737
|
function countBy(items, getValue) {
|
|
@@ -6829,8 +6805,7 @@ async function getConfigsStatus(store = resolveConfigStore()) {
|
|
|
6829
6805
|
},
|
|
6830
6806
|
env: {
|
|
6831
6807
|
database: {
|
|
6832
|
-
primary: "
|
|
6833
|
-
fallback: "CONFIGS_DB_PATH",
|
|
6808
|
+
primary: "HASNA_INSTRUCTIONS_DB_PATH",
|
|
6834
6809
|
active: activeDatabaseEnv(),
|
|
6835
6810
|
kind: configuredDatabaseKind()
|
|
6836
6811
|
}
|
|
@@ -7333,9 +7308,9 @@ program.command("import <file>").description("Import configs from a tar.gz bundl
|
|
|
7333
7308
|
});
|
|
7334
7309
|
program.command("whoami").description("Show setup summary").action(async () => {
|
|
7335
7310
|
const store = resolveConfigStore();
|
|
7336
|
-
const dbPath = isCloudMode() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1 (self_hosted)` : process.env["
|
|
7311
|
+
const dbPath = isCloudMode() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1 (self_hosted)` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join11(homedir7(), ".hasna", "instructions", "instructions.db");
|
|
7337
7312
|
const stats = await store.getConfigStats();
|
|
7338
|
-
console.log(chalk.bold("@hasna/
|
|
7313
|
+
console.log(chalk.bold("@hasna/instructions") + chalk.dim(" v" + pkg.version));
|
|
7339
7314
|
console.log(chalk.cyan(isCloudMode() ? "API:" : "DB:") + " " + dbPath);
|
|
7340
7315
|
console.log(chalk.cyan("Total configs:") + " " + (stats["total"] || 0));
|
|
7341
7316
|
console.log();
|
|
@@ -7798,7 +7773,7 @@ program.command("package-manager-scan [paths...]").description("Scan package-man
|
|
|
7798
7773
|
}
|
|
7799
7774
|
});
|
|
7800
7775
|
var mcpCmd = program.command("mcp").description("Install/remove MCP server for AI agents");
|
|
7801
|
-
mcpCmd.command("install").alias("add").description("Install configs MCP server into an agent").option("--claude", "install into Claude Code").option("--codex", "install into Codex").option("--gemini", "install into Gemini").option("--all", "install into all agents").option("--profile <level>", "set
|
|
7776
|
+
mcpCmd.command("install").alias("add").description("Install configs MCP server into an agent").option("--claude", "install into Claude Code").option("--codex", "install into Codex").option("--gemini", "install into Gemini").option("--all", "install into all agents").option("--profile <level>", "set INSTRUCTIONS_PROFILE (minimal|standard|full)", "standard").action(async (opts) => {
|
|
7802
7777
|
const targets = opts.all ? ["claude", "codex", "gemini"] : [
|
|
7803
7778
|
...opts.claude ? ["claude"] : [],
|
|
7804
7779
|
...opts.codex ? ["codex"] : [],
|
|
@@ -7813,7 +7788,7 @@ mcpCmd.command("install").alias("add").description("Install configs MCP server i
|
|
|
7813
7788
|
const { vars } = await getMachineProfileContext({}, resolveConfigStore());
|
|
7814
7789
|
const mcpBinary = `${vars["BUN_BIN_DIR"]}/configs-mcp`;
|
|
7815
7790
|
if (target === "claude") {
|
|
7816
|
-
const cmd = opts.profile && opts.profile !== "full" ? ["claude", "mcp", "add", "--transport", "stdio", "--scope", "user", "configs", "--", "env", `
|
|
7791
|
+
const cmd = opts.profile && opts.profile !== "full" ? ["claude", "mcp", "add", "--transport", "stdio", "--scope", "user", "configs", "--", "env", `INSTRUCTIONS_PROFILE=${opts.profile}`, mcpBinary] : ["claude", "mcp", "add", "--transport", "stdio", "--scope", "user", "configs", "--", mcpBinary];
|
|
7817
7792
|
const proc = Bun.spawn(cmd, { stdout: "inherit", stderr: "inherit" });
|
|
7818
7793
|
await proc.exited;
|
|
7819
7794
|
console.log(chalk.green("\u2713") + " Installed into Claude Code");
|
|
@@ -7870,7 +7845,7 @@ program.command("init").description("First-time setup: sync all known configs, c
|
|
|
7870
7845
|
await store.reset();
|
|
7871
7846
|
console.log(chalk.dim("Reset local store."));
|
|
7872
7847
|
}
|
|
7873
|
-
console.log(chalk.bold(`@hasna/
|
|
7848
|
+
console.log(chalk.bold(`@hasna/instructions \u2014 initializing
|
|
7874
7849
|
`));
|
|
7875
7850
|
const result = await syncKnown({ store });
|
|
7876
7851
|
console.log(chalk.green("\u2713") + ` Synced: +${result.added} updated:${result.updated} unchanged:${result.unchanged}`);
|
|
@@ -7914,7 +7889,7 @@ DB stats:`));
|
|
|
7914
7889
|
if (count > 0)
|
|
7915
7890
|
console.log(` ${key.padEnd(18)} ${count}`);
|
|
7916
7891
|
}
|
|
7917
|
-
const location = isCloudMode() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1 (self_hosted)` : process.env["
|
|
7892
|
+
const location = isCloudMode() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1 (self_hosted)` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join11(homedir7(), ".hasna", "instructions", "instructions.db");
|
|
7918
7893
|
console.log(chalk.dim(`
|
|
7919
7894
|
${isCloudMode() ? "API" : "DB"}: ${location}`));
|
|
7920
7895
|
});
|
|
@@ -7924,7 +7899,7 @@ program.command("status").description("Health check: total configs, drift from d
|
|
|
7924
7899
|
printJson(status);
|
|
7925
7900
|
return;
|
|
7926
7901
|
}
|
|
7927
|
-
console.log(chalk.bold("@hasna/
|
|
7902
|
+
console.log(chalk.bold("@hasna/instructions") + chalk.dim(` v${pkg.version}`));
|
|
7928
7903
|
console.log(chalk.cyan("Database:") + ` ${status.env.database.kind} (${status.env.database.active ?? "default"})`);
|
|
7929
7904
|
console.log(chalk.cyan("Total:") + ` ${status.counts.configs.total} configs
|
|
7930
7905
|
`);
|
|
@@ -7935,7 +7910,7 @@ program.command("status").description("Health check: total configs, drift from d
|
|
|
7935
7910
|
});
|
|
7936
7911
|
program.command("backup").description("Export configs to a timestamped backup file").action(async () => {
|
|
7937
7912
|
const { mkdirSync: mk } = await import("fs");
|
|
7938
|
-
const backupDir = join11(homedir7(), ".hasna", "
|
|
7913
|
+
const backupDir = join11(homedir7(), ".hasna", "instructions", "backups");
|
|
7939
7914
|
mk(backupDir, { recursive: true });
|
|
7940
7915
|
const ts = new Date().toISOString().replace(/[:.]/g, "-").replace("T", "-").slice(0, 19);
|
|
7941
7916
|
const outPath = join11(backupDir, `configs-${ts}.tar.gz`);
|
|
@@ -8086,7 +8061,7 @@ program.command("watch").description("Watch known config files for changes and a
|
|
|
8086
8061
|
const interval = Number(opts.interval);
|
|
8087
8062
|
const { statSync: st } = await import("fs");
|
|
8088
8063
|
const { expandPath: expandPath2 } = await Promise.resolve().then(() => (init_apply(), exports_apply));
|
|
8089
|
-
console.log(chalk.bold("@hasna/
|
|
8064
|
+
console.log(chalk.bold("@hasna/instructions watch") + chalk.dim(` \u2014 polling every ${interval}ms`));
|
|
8090
8065
|
console.log(chalk.dim(`Watching known config files for changes\u2026
|
|
8091
8066
|
`));
|
|
8092
8067
|
const mtimes = new Map;
|
|
@@ -8246,7 +8221,7 @@ program.command("bootstrap").description("Install the full @hasna ecosystem: CLI
|
|
|
8246
8221
|
{ name: "@hasna/assistants", bin: "assistants", mcp: "assistants-mcp" },
|
|
8247
8222
|
{ name: "@hasna/brains", bin: "brains", mcp: "brains-mcp" }
|
|
8248
8223
|
];
|
|
8249
|
-
console.log(chalk.bold("@hasna/
|
|
8224
|
+
console.log(chalk.bold("@hasna/instructions bootstrap") + chalk.dim(` \u2014 installing ${packages.length} ecosystem packages
|
|
8250
8225
|
`));
|
|
8251
8226
|
console.log(chalk.cyan("Installing CLI tools:"));
|
|
8252
8227
|
for (const pkg2 of packages) {
|
|
@@ -8306,7 +8281,7 @@ program.command("push").description("Alias for sync --to-disk (write DB configs
|
|
|
8306
8281
|
});
|
|
8307
8282
|
program.command("update").description("Check for updates and install latest version").option("--check", "only check, don't install").action(async (opts) => {
|
|
8308
8283
|
try {
|
|
8309
|
-
const proc = Bun.spawn(["npm", "view", "@hasna/
|
|
8284
|
+
const proc = Bun.spawn(["npm", "view", "@hasna/instructions", "version"], { stdout: "pipe", stderr: "pipe" });
|
|
8310
8285
|
const latest = (await new Response(proc.stdout).text()).trim();
|
|
8311
8286
|
await proc.exited;
|
|
8312
8287
|
if (latest === pkg.version) {
|
|
@@ -8315,7 +8290,7 @@ program.command("update").description("Check for updates and install latest vers
|
|
|
8315
8290
|
console.log(`Current: ${chalk.dim(pkg.version)} \u2192 Latest: ${chalk.green(latest)}`);
|
|
8316
8291
|
if (!opts.check) {
|
|
8317
8292
|
console.log(chalk.dim("Installing..."));
|
|
8318
|
-
const install = Bun.spawn(["bun", "install", "-g", `@hasna/
|
|
8293
|
+
const install = Bun.spawn(["bun", "install", "-g", `@hasna/instructions@${latest}`], { stdout: "inherit", stderr: "inherit" });
|
|
8319
8294
|
await install.exited;
|
|
8320
8295
|
console.log(chalk.green("\u2713") + ` Updated to ${latest}`);
|
|
8321
8296
|
}
|
package/dist/db/database.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare function resetDatabase(): void;
|
|
|
7
7
|
/**
|
|
8
8
|
* Destroy the on-disk local database: close the handle and delete the db file
|
|
9
9
|
* plus its WAL/SHM sidecars. Used by `init --force`. Resolves the path from the
|
|
10
|
-
* db module (honoring
|
|
10
|
+
* db module (honoring HASNA_INSTRUCTIONS_DB_PATH); a no-op for the
|
|
11
11
|
* in-memory (`:memory:`) database. Local-only — the CloudConfigStore never calls
|
|
12
12
|
* this (destroying the shared cloud store from a client is forbidden).
|
|
13
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAetC,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5C;AAyED,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAqBnD;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAOzC;AAsDD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAMxE"}
|
package/dist/index.js
CHANGED
|
@@ -73,21 +73,17 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
73
73
|
|
|
74
74
|
// src/db/database.ts
|
|
75
75
|
import { Database } from "bun:sqlite";
|
|
76
|
-
import {
|
|
76
|
+
import { existsSync, mkdirSync, rmSync } from "fs";
|
|
77
77
|
import { join } from "path";
|
|
78
78
|
import { randomUUID } from "crypto";
|
|
79
79
|
function getDbPath() {
|
|
80
|
-
if (process.env["
|
|
81
|
-
return process.env["
|
|
80
|
+
if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
|
|
81
|
+
return process.env["HASNA_INSTRUCTIONS_DB_PATH"];
|
|
82
82
|
}
|
|
83
|
-
if (process.env["CONFIGS_DB_PATH"]) {
|
|
84
|
-
return process.env["CONFIGS_DB_PATH"];
|
|
85
|
-
}
|
|
86
|
-
migrateDotfile();
|
|
87
83
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
88
|
-
const dir = join(home, ".hasna", "
|
|
84
|
+
const dir = join(home, ".hasna", "instructions");
|
|
89
85
|
mkdirSync(dir, { recursive: true });
|
|
90
|
-
return join(dir, "
|
|
86
|
+
return join(dir, "instructions.db");
|
|
91
87
|
}
|
|
92
88
|
function uuid() {
|
|
93
89
|
return randomUUID();
|
|
@@ -242,24 +238,6 @@ function insertFeedback(input, db) {
|
|
|
242
238
|
const d = db || getDatabase();
|
|
243
239
|
d.run("INSERT INTO feedback (message, email, category, version) VALUES (?, ?, ?, ?)", [input.message, input.email ?? null, input.category ?? "general", input.version ?? null]);
|
|
244
240
|
}
|
|
245
|
-
function migrateDotfile() {
|
|
246
|
-
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
247
|
-
const oldDirs = [join(home, ".open-configs"), join(home, ".configs")];
|
|
248
|
-
const newDir = join(home, ".hasna", "configs");
|
|
249
|
-
if (existsSync(newDir))
|
|
250
|
-
return;
|
|
251
|
-
for (const oldDir of oldDirs) {
|
|
252
|
-
if (!existsSync(oldDir))
|
|
253
|
-
continue;
|
|
254
|
-
try {
|
|
255
|
-
if (!statSync(oldDir).isDirectory())
|
|
256
|
-
continue;
|
|
257
|
-
mkdirSync(join(home, ".hasna"), { recursive: true });
|
|
258
|
-
cpSync(oldDir, newDir, { recursive: true, force: false });
|
|
259
|
-
return;
|
|
260
|
-
} catch {}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
241
|
|
|
264
242
|
// src/db/configs.ts
|
|
265
243
|
function rowToConfig(row) {
|
|
@@ -1510,14 +1488,12 @@ function hasSecrets(content, format) {
|
|
|
1510
1488
|
var PACKAGE_NAME = "@hasna/instructions";
|
|
1511
1489
|
var PACKAGE_VERSION = "0.3.0";
|
|
1512
1490
|
function activeDatabaseEnv() {
|
|
1513
|
-
if (process.env["
|
|
1514
|
-
return "
|
|
1515
|
-
if (process.env["CONFIGS_DB_PATH"])
|
|
1516
|
-
return "CONFIGS_DB_PATH";
|
|
1491
|
+
if (process.env["HASNA_INSTRUCTIONS_DB_PATH"])
|
|
1492
|
+
return "HASNA_INSTRUCTIONS_DB_PATH";
|
|
1517
1493
|
return null;
|
|
1518
1494
|
}
|
|
1519
1495
|
function configuredDatabaseKind() {
|
|
1520
|
-
const value = process.env["
|
|
1496
|
+
const value = process.env["HASNA_INSTRUCTIONS_DB_PATH"] ?? "";
|
|
1521
1497
|
return value === ":memory:" || value.startsWith("file::memory:") ? "memory" : "file";
|
|
1522
1498
|
}
|
|
1523
1499
|
function countBy(items, getValue) {
|
|
@@ -1591,8 +1567,7 @@ async function getConfigsStatus(store = resolveConfigStore()) {
|
|
|
1591
1567
|
},
|
|
1592
1568
|
env: {
|
|
1593
1569
|
database: {
|
|
1594
|
-
primary: "
|
|
1595
|
-
fallback: "CONFIGS_DB_PATH",
|
|
1570
|
+
primary: "HASNA_INSTRUCTIONS_DB_PATH",
|
|
1596
1571
|
active: activeDatabaseEnv(),
|
|
1597
1572
|
kind: configuredDatabaseKind()
|
|
1598
1573
|
}
|
|
@@ -1697,7 +1672,7 @@ var PG_MIGRATIONS = [
|
|
|
1697
1672
|
];
|
|
1698
1673
|
// src/lib/session-render.ts
|
|
1699
1674
|
import { createHash } from "crypto";
|
|
1700
|
-
import { existsSync as existsSync5, readFileSync as readFileSync3, realpathSync as realpathSync2, statSync
|
|
1675
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, realpathSync as realpathSync2, statSync } from "fs";
|
|
1701
1676
|
import { homedir as homedir3 } from "os";
|
|
1702
1677
|
import { basename as basename3, dirname as dirname2, extname as extname2, isAbsolute, join as join3, parse, posix, relative, resolve as resolve2 } from "path";
|
|
1703
1678
|
var CODEWITH_NATIVE_IMPORTS_ENV = "HASNA_CONFIGS_CODEWITH_NATIVE_IMPORTS";
|
|
@@ -2463,7 +2438,7 @@ function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
|
|
|
2463
2438
|
}
|
|
2464
2439
|
return;
|
|
2465
2440
|
}
|
|
2466
|
-
const stat =
|
|
2441
|
+
const stat = statSync(resolvedPath);
|
|
2467
2442
|
if (!stat.isFile()) {
|
|
2468
2443
|
throw new Error(`Identity instruction source path is not a file for ${sourceId}: ${sourcePath.path}`);
|
|
2469
2444
|
}
|
|
@@ -3101,7 +3076,7 @@ import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as
|
|
|
3101
3076
|
import { basename as basename4, extname as extname3, join as join6 } from "path";
|
|
3102
3077
|
|
|
3103
3078
|
// src/lib/sync-dir.ts
|
|
3104
|
-
import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync5, statSync as
|
|
3079
|
+
import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
|
|
3105
3080
|
import { join as join5, relative as relative3 } from "path";
|
|
3106
3081
|
import { homedir as homedir4 } from "os";
|
|
3107
3082
|
var SKIP = [".db", ".db-shm", ".db-wal", ".log", ".lock", ".DS_Store", "node_modules", ".git"];
|
|
@@ -3113,7 +3088,7 @@ async function syncFromDir(dir, opts = {}) {
|
|
|
3113
3088
|
const absDir = expandPath(dir);
|
|
3114
3089
|
if (!existsSync7(absDir))
|
|
3115
3090
|
return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
|
|
3116
|
-
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join5(absDir, f)).filter((f) =>
|
|
3091
|
+
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join5(absDir, f)).filter((f) => statSync2(f).isFile());
|
|
3117
3092
|
const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
|
|
3118
3093
|
const home = homedir4();
|
|
3119
3094
|
const allConfigs = await store.listConfigs();
|
package/dist/mcp/index.js
CHANGED
|
@@ -49,21 +49,17 @@ var init_types = __esm(() => {
|
|
|
49
49
|
|
|
50
50
|
// src/db/database.ts
|
|
51
51
|
import { Database } from "bun:sqlite";
|
|
52
|
-
import {
|
|
52
|
+
import { existsSync, mkdirSync, rmSync } from "fs";
|
|
53
53
|
import { join } from "path";
|
|
54
54
|
import { randomUUID } from "crypto";
|
|
55
55
|
function getDbPath() {
|
|
56
|
-
if (process.env["
|
|
57
|
-
return process.env["
|
|
56
|
+
if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
|
|
57
|
+
return process.env["HASNA_INSTRUCTIONS_DB_PATH"];
|
|
58
58
|
}
|
|
59
|
-
if (process.env["CONFIGS_DB_PATH"]) {
|
|
60
|
-
return process.env["CONFIGS_DB_PATH"];
|
|
61
|
-
}
|
|
62
|
-
migrateDotfile();
|
|
63
59
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
64
|
-
const dir = join(home, ".hasna", "
|
|
60
|
+
const dir = join(home, ".hasna", "instructions");
|
|
65
61
|
mkdirSync(dir, { recursive: true });
|
|
66
|
-
return join(dir, "
|
|
62
|
+
return join(dir, "instructions.db");
|
|
67
63
|
}
|
|
68
64
|
function uuid() {
|
|
69
65
|
return randomUUID();
|
|
@@ -149,24 +145,6 @@ function insertFeedback(input, db) {
|
|
|
149
145
|
const d = db || getDatabase();
|
|
150
146
|
d.run("INSERT INTO feedback (message, email, category, version) VALUES (?, ?, ?, ?)", [input.message, input.email ?? null, input.category ?? "general", input.version ?? null]);
|
|
151
147
|
}
|
|
152
|
-
function migrateDotfile() {
|
|
153
|
-
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
154
|
-
const oldDirs = [join(home, ".open-configs"), join(home, ".configs")];
|
|
155
|
-
const newDir = join(home, ".hasna", "configs");
|
|
156
|
-
if (existsSync(newDir))
|
|
157
|
-
return;
|
|
158
|
-
for (const oldDir of oldDirs) {
|
|
159
|
-
if (!existsSync(oldDir))
|
|
160
|
-
continue;
|
|
161
|
-
try {
|
|
162
|
-
if (!statSync(oldDir).isDirectory())
|
|
163
|
-
continue;
|
|
164
|
-
mkdirSync(join(home, ".hasna"), { recursive: true });
|
|
165
|
-
cpSync(oldDir, newDir, { recursive: true, force: false });
|
|
166
|
-
return;
|
|
167
|
-
} catch {}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
148
|
var MIGRATIONS, _db = null;
|
|
171
149
|
var init_database = __esm(() => {
|
|
172
150
|
MIGRATIONS = [
|
|
@@ -1974,7 +1952,7 @@ var init_sync = __esm(() => {
|
|
|
1974
1952
|
});
|
|
1975
1953
|
|
|
1976
1954
|
// src/lib/sync-dir.ts
|
|
1977
|
-
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync
|
|
1955
|
+
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync } from "fs";
|
|
1978
1956
|
import { join as join4, relative } from "path";
|
|
1979
1957
|
import { homedir as homedir3 } from "os";
|
|
1980
1958
|
function shouldSkip(p) {
|
|
@@ -1985,7 +1963,7 @@ async function syncFromDir(dir, opts = {}) {
|
|
|
1985
1963
|
const absDir = expandPath(dir);
|
|
1986
1964
|
if (!existsSync5(absDir))
|
|
1987
1965
|
return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
|
|
1988
|
-
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join4(absDir, f)).filter((f) =>
|
|
1966
|
+
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join4(absDir, f)).filter((f) => statSync(f).isFile());
|
|
1989
1967
|
const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
|
|
1990
1968
|
const home = homedir3();
|
|
1991
1969
|
const allConfigs = await store.listConfigs();
|
|
@@ -2062,7 +2040,7 @@ var init_sync_dir = __esm(() => {
|
|
|
2062
2040
|
var require_package = __commonJS((exports, module) => {
|
|
2063
2041
|
module.exports = {
|
|
2064
2042
|
name: "@hasna/instructions",
|
|
2065
|
-
version: "0.4.
|
|
2043
|
+
version: "0.4.2",
|
|
2066
2044
|
description: "AI coding agent instruction & configuration manager \u2014 store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
|
|
2067
2045
|
type: "module",
|
|
2068
2046
|
main: "dist/index.js",
|
|
@@ -2286,7 +2264,7 @@ var PROFILES = {
|
|
|
2286
2264
|
standard: ["list_configs", "get_config", "create_config", "update_config", "apply_config", "sync_known", "get_status", "render_template", "scan_secrets", "list_profiles", "apply_profile", "search_tools", "describe_tools"],
|
|
2287
2265
|
full: []
|
|
2288
2266
|
};
|
|
2289
|
-
var activeProfile = process.env["
|
|
2267
|
+
var activeProfile = process.env["INSTRUCTIONS_PROFILE"] || "full";
|
|
2290
2268
|
var profileFilter = PROFILES[activeProfile];
|
|
2291
2269
|
var ALL_LEAN_TOOLS = [
|
|
2292
2270
|
{ name: "list_configs", inputSchema: { type: "object", properties: { category: { type: "string" }, agent: { type: "string" }, kind: { type: "string" }, search: { type: "string" }, limit: { type: "number" }, cursor: { type: "number" }, verbose: { type: "boolean" } } } },
|
|
@@ -2466,7 +2444,7 @@ function buildServer() {
|
|
|
2466
2444
|
drifted,
|
|
2467
2445
|
drifted_configs: driftedSlugs.slice(0, 5),
|
|
2468
2446
|
missing,
|
|
2469
|
-
db_path: process.env["
|
|
2447
|
+
db_path: process.env["HASNA_INSTRUCTIONS_DB_PATH"] || "~/.hasna/instructions/instructions.db"
|
|
2470
2448
|
});
|
|
2471
2449
|
}
|
|
2472
2450
|
case "sync_known": {
|
package/dist/server/index.js
CHANGED
|
@@ -3199,7 +3199,7 @@ if (process.argv.includes("--version") || process.argv.includes("-V")) {
|
|
|
3199
3199
|
console.log(getPackageVersion());
|
|
3200
3200
|
process.exit(0);
|
|
3201
3201
|
}
|
|
3202
|
-
var PORT = Number(process.env["PORT"] ?? process.env["INSTRUCTIONS_PORT"] ??
|
|
3202
|
+
var PORT = Number(process.env["PORT"] ?? process.env["INSTRUCTIONS_PORT"] ?? 3457);
|
|
3203
3203
|
var app = new Hono2;
|
|
3204
3204
|
app.use("*", cors());
|
|
3205
3205
|
function serviceMode() {
|
|
@@ -3268,7 +3268,7 @@ if (dashDir) {
|
|
|
3268
3268
|
});
|
|
3269
3269
|
});
|
|
3270
3270
|
}
|
|
3271
|
-
var HOST = process.env["HOST"] ?? process.env["INSTRUCTIONS_HOST"] ??
|
|
3271
|
+
var HOST = process.env["HOST"] ?? process.env["INSTRUCTIONS_HOST"] ?? "localhost";
|
|
3272
3272
|
console.log(`instructions-serve listening on http://${HOST}:${PORT} (mode: ${serviceMode()})${dashDir ? " (dashboard: /)" : " (no dashboard)"}`);
|
|
3273
3273
|
var server_default = { port: PORT, hostname: HOST, fetch: app.fetch };
|
|
3274
3274
|
export {
|
package/dist/status.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ConfigStore } from "./data/config-store.js";
|
|
2
|
-
type ActiveDbEnv = "
|
|
2
|
+
type ActiveDbEnv = "HASNA_INSTRUCTIONS_DB_PATH" | null;
|
|
3
3
|
type DatabaseKind = "memory" | "file";
|
|
4
4
|
type ContractStatus = "ok" | "warn";
|
|
5
5
|
export interface ConfigsStatusContract {
|
|
@@ -11,8 +11,7 @@ export interface ConfigsStatusContract {
|
|
|
11
11
|
};
|
|
12
12
|
env: {
|
|
13
13
|
database: {
|
|
14
|
-
primary: "
|
|
15
|
-
fallback: "CONFIGS_DB_PATH";
|
|
14
|
+
primary: "HASNA_INSTRUCTIONS_DB_PATH";
|
|
16
15
|
active: ActiveDbEnv;
|
|
17
16
|
kind: DatabaseKind;
|
|
18
17
|
};
|
package/dist/status.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQ9E,KAAK,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQ9E,KAAK,WAAW,GAAG,4BAA4B,GAAG,IAAI,CAAC;AACvD,KAAK,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;AACtC,KAAK,cAAc,GAAG,IAAI,GAAG,MAAM,CAAC;AAEpC,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,SAAS,CAAC;IACnB,aAAa,EAAE,KAAK,CAAC;IACrB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,GAAG,EAAE;QACH,QAAQ,EAAE;YACR,OAAO,EAAE,4BAA4B,CAAC;YACtC,MAAM,EAAE,WAAW,CAAC;YACpB,IAAI,EAAE,YAAY,CAAC;SACpB,CAAC;KACH,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE;YACP,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC;QACF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,cAAc,CAAC;QACvB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,wBAAwB,EAAE,MAAM,CAAC;QACjC,QAAQ,EAAE,OAAO,CAAC;QAClB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,oBAAoB,EAAE,OAAO,CAAC;KAC/B,CAAC;IACF,MAAM,EAAE;QACN,oBAAoB,EAAE,KAAK,CAAC;QAC5B,oBAAoB,EAAE,KAAK,CAAC;QAC5B,iBAAiB,EAAE,KAAK,CAAC;QACzB,oBAAoB,EAAE,KAAK,CAAC;QAC5B,0BAA0B,EAAE,IAAI,CAAC;KAClC,CAAC;CACH;AAsBD,wBAAsB,gBAAgB,CACpC,KAAK,GAAE,WAAkC,GACxC,OAAO,CAAC,qBAAqB,CAAC,CAiHhC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/instructions",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "AI coding agent instruction & configuration manager — store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|