@holdyourvoice/hyv 2.9.21 → 2.9.23
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/agents/AGENTS.md +80 -0
- package/dist/index.js +156 -3
- package/package.json +1 -1
- package/scripts/postinstall-lib.js +5 -5
package/agents/AGENTS.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Hold Your Voice — Agent Instructions
|
|
2
|
+
|
|
3
|
+
The user has a voice profile that defines their unique writing style. Your job is to make ALL written content match their voice automatically — without waiting for them to mention "voice" or "hyv".
|
|
4
|
+
|
|
5
|
+
## Auto-trigger — do these automatically
|
|
6
|
+
|
|
7
|
+
**Before delivering any written content (emails, replies, posts, docs, messages, or prose):**
|
|
8
|
+
1. Run `hyv_scan` for a fast local check (free, offline, works without a profile)
|
|
9
|
+
2. Run `hyv_clean` for the full scan → fix → validate pipeline, or `hyv_fix` then `hyv_rewrite`
|
|
10
|
+
3. Run `hyv_validate` to verify the output matches their voice
|
|
11
|
+
|
|
12
|
+
**When the user asks you to write, draft, compose, edit, improve, or rewrite anything:**
|
|
13
|
+
1. Write your draft normally
|
|
14
|
+
2. Run `hyv_scan` or `hyv_clean` on it
|
|
15
|
+
3. Run `hyv_rewrite` to match their voice profile
|
|
16
|
+
4. Deliver the voice-matched version
|
|
17
|
+
|
|
18
|
+
**After the user accepts a substantial edit:**
|
|
19
|
+
- Suggest they run `hyv reinforce --last` so their profile learns from the change
|
|
20
|
+
|
|
21
|
+
## Which tool to use
|
|
22
|
+
|
|
23
|
+
| Tool | What it does | When to use |
|
|
24
|
+
|------|-------------|-------------|
|
|
25
|
+
| `hyv_welcome` | Onboarding guide (name → samples → test → signup) | New users, first time |
|
|
26
|
+
| `hyv_mcp_setup` | Status, integrate apps, ChatGPT connector | Check/refresh setup |
|
|
27
|
+
| `hyv_profiles` | List voice profiles | See which profiles are available |
|
|
28
|
+
| `hyv_scan` | Fast local AI-pattern scan (free, 220+ patterns) | Before any prose delivery |
|
|
29
|
+
| `hyv_analyze` | Full hybrid scan (local + server, paid) | Important drafts |
|
|
30
|
+
| `hyv_clean` | Scan → fix → validate → rewrite in one call | Best single-call pipeline |
|
|
31
|
+
| `hyv_fix` | Auto-fix deterministic patterns (no LLM) | Before rewrite |
|
|
32
|
+
| `hyv_rewrite` | Profile-aware rewrite prompt | After scan/fix |
|
|
33
|
+
| `hyv_validate` | Verify output matches voice profile | After rewrite |
|
|
34
|
+
| `hyv_check` | Quick pass/fail | Spot checks |
|
|
35
|
+
| `hyv_score` | 0-100 voice score | Quantify quality |
|
|
36
|
+
| `hyv_diff` | Before/after comparison | Review changes |
|
|
37
|
+
| `hyv_list_free_tools` | List all free capabilities | What's available |
|
|
38
|
+
|
|
39
|
+
## Voice profiles
|
|
40
|
+
|
|
41
|
+
- Run `hyv_profiles` first if unsure which profile is active.
|
|
42
|
+
- Terminal profiles (from `hyv welcome`) are already local — no extra step.
|
|
43
|
+
- Dashboard profiles sync after the user runs `hyv init` once (MCP auto-downloads).
|
|
44
|
+
- Pass `profile: "<slug>"` on tools only when using a non-default profile.
|
|
45
|
+
- If no profile exists yet, free local scan still works — call `hyv_welcome` to onboard.
|
|
46
|
+
|
|
47
|
+
## Rewrite rules
|
|
48
|
+
|
|
49
|
+
1. **Never** use AI-slop words: delve, leverage, tapestry, foster, harness, pivotal, innovative, cutting-edge, robust, holistic, nuanced, resonate, unpack, navigate, landscape, ecosystem, transformative, paradigm, revolutionize, unlock, supercharge, game-changer
|
|
50
|
+
2. **Never** use formulaic connectors: firstly, secondly, moreover, furthermore, in conclusion, to conclude, notably
|
|
51
|
+
3. **Never** use hedging: arguably, perhaps, some might say, it's worth noting, it's important to note
|
|
52
|
+
4. **Never** use signpost claims: this is why, this is how, here's where, here's why
|
|
53
|
+
5. **Never** use antithesis patterns: "not just X, but Y", "more than just", "it's not about X, it's about Y"
|
|
54
|
+
6. **Match** the user's sentence rhythm, vocabulary, and tone from their voice profile
|
|
55
|
+
7. **Preserve** roughness that carries voice — don't over-polish
|
|
56
|
+
8. **Open** from concrete observations, not generic setups
|
|
57
|
+
9. **Fix only** flagged lines — preserve clean lines exactly
|
|
58
|
+
10. **Never add** sections, hooks, CTAs, markdown, or commentary
|
|
59
|
+
|
|
60
|
+
## MCP setup (no terminal needed)
|
|
61
|
+
|
|
62
|
+
- `hyv_mcp_setup` with `action=status` — see what's integrated and onboarding progress
|
|
63
|
+
- `hyv_mcp_setup` with `action=integrate` — refresh Cursor/Claude configs (`force=true` after hyv upgrade)
|
|
64
|
+
- `hyv_mcp_setup` with `action=chatgpt` — ChatGPT remote OAuth steps (recommended for paid users)
|
|
65
|
+
- `hyv_welcome` — finish voice onboarding inside this chat
|
|
66
|
+
|
|
67
|
+
## CLI fallback (when MCP tools aren't available)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
echo "text to check" | hyv scan -
|
|
71
|
+
hyv fix file.md # apply auto-fixes without LLM
|
|
72
|
+
hyv rewrite file.md # generate rewrite prompt
|
|
73
|
+
hyv check "inline text" # quick spot-check
|
|
74
|
+
hyv score file.md # just a 0-100 number
|
|
75
|
+
hyv diff file.md # show proposed fixes
|
|
76
|
+
hyv profiles # list profiles
|
|
77
|
+
hyv reinforce --last # learn from last edit
|
|
78
|
+
hyv mcp --setup # view all MCP configs
|
|
79
|
+
hyv mcp --test # verify everything works
|
|
80
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -4727,6 +4727,41 @@ var init_profile_meta = __esm({
|
|
|
4727
4727
|
});
|
|
4728
4728
|
|
|
4729
4729
|
// src/lib/config.ts
|
|
4730
|
+
var config_exports = {};
|
|
4731
|
+
__export(config_exports, {
|
|
4732
|
+
API_BASE: () => API_BASE,
|
|
4733
|
+
AUTH_FILE: () => AUTH_FILE,
|
|
4734
|
+
CACHE_DIR: () => CACHE_DIR2,
|
|
4735
|
+
CONFIG_FILE: () => CONFIG_FILE,
|
|
4736
|
+
HYV_DIR: () => HYV_DIR,
|
|
4737
|
+
LAST_SESSION_FILE: () => LAST_SESSION_FILE,
|
|
4738
|
+
PROFILES_DIR: () => PROFILES_DIR,
|
|
4739
|
+
QUEUE_DIR: () => QUEUE_DIR,
|
|
4740
|
+
appendSecureLine: () => appendSecureLine,
|
|
4741
|
+
assertSafeOAuthUrl: () => assertSafeOAuthUrl,
|
|
4742
|
+
assertSafeOpenUrl: () => assertSafeOpenUrl,
|
|
4743
|
+
assertSafeProfileName: () => assertSafeProfileName,
|
|
4744
|
+
clearAuth: () => clearAuth,
|
|
4745
|
+
clearQueuedSignals: () => clearQueuedSignals,
|
|
4746
|
+
cliApiUrl: () => cliApiUrl,
|
|
4747
|
+
ensureHyvDir: () => ensureHyvDir,
|
|
4748
|
+
getQueuedSignals: () => getQueuedSignals,
|
|
4749
|
+
getToken: () => getToken,
|
|
4750
|
+
isInitialized: () => isInitialized,
|
|
4751
|
+
listCachedProfiles: () => listCachedProfiles,
|
|
4752
|
+
profilePathForName: () => profilePathForName,
|
|
4753
|
+
queueSignal: () => queueSignal,
|
|
4754
|
+
readAuth: () => readAuth,
|
|
4755
|
+
readCachedProfile: () => readCachedProfile,
|
|
4756
|
+
readConfig: () => readConfig,
|
|
4757
|
+
readLastEditSession: () => readLastEditSession,
|
|
4758
|
+
saveLastEditSession: () => saveLastEditSession,
|
|
4759
|
+
toSafeProfileCacheKey: () => toSafeProfileCacheKey,
|
|
4760
|
+
writeAuth: () => writeAuth,
|
|
4761
|
+
writeCachedProfile: () => writeCachedProfile,
|
|
4762
|
+
writeConfig: () => writeConfig,
|
|
4763
|
+
writeSecureFile: () => writeSecureFile
|
|
4764
|
+
});
|
|
4730
4765
|
function validateApiBase(raw) {
|
|
4731
4766
|
const trimmed = raw.replace(/\/$/, "");
|
|
4732
4767
|
let parsed;
|
|
@@ -4822,6 +4857,10 @@ function ensureHyvDir() {
|
|
|
4822
4857
|
}
|
|
4823
4858
|
}
|
|
4824
4859
|
}
|
|
4860
|
+
function writeSecureFile(filePath, content) {
|
|
4861
|
+
ensureHyvDir();
|
|
4862
|
+
fs3.writeFileSync(filePath, content, { mode: 384 });
|
|
4863
|
+
}
|
|
4825
4864
|
function appendSecureLine(filePath, line, dir) {
|
|
4826
4865
|
if (dir) {
|
|
4827
4866
|
if (!fs3.existsSync(dir))
|
|
@@ -4866,6 +4905,11 @@ function writeAuth(auth) {
|
|
|
4866
4905
|
}
|
|
4867
4906
|
fs3.writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), { mode: 384 });
|
|
4868
4907
|
}
|
|
4908
|
+
function clearAuth() {
|
|
4909
|
+
if (fs3.existsSync(AUTH_FILE)) {
|
|
4910
|
+
fs3.unlinkSync(AUTH_FILE);
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4869
4913
|
function readConfig() {
|
|
4870
4914
|
try {
|
|
4871
4915
|
if (!fs3.existsSync(CONFIG_FILE))
|
|
@@ -4943,6 +4987,17 @@ function queueSignal(signal) {
|
|
|
4943
4987
|
const filePath = path2.join(QUEUE_DIR, `${id}.json`);
|
|
4944
4988
|
fs3.writeFileSync(filePath, JSON.stringify(signal, null, 2), { mode: 384 });
|
|
4945
4989
|
}
|
|
4990
|
+
function clearQueuedSignals() {
|
|
4991
|
+
try {
|
|
4992
|
+
if (!fs3.existsSync(QUEUE_DIR))
|
|
4993
|
+
return;
|
|
4994
|
+
const files = fs3.readdirSync(QUEUE_DIR).filter((f) => f.endsWith(".json"));
|
|
4995
|
+
for (const f of files) {
|
|
4996
|
+
fs3.unlinkSync(path2.join(QUEUE_DIR, f));
|
|
4997
|
+
}
|
|
4998
|
+
} catch {
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
4946
5001
|
function saveLastEditSession(session) {
|
|
4947
5002
|
ensureHyvDir();
|
|
4948
5003
|
const data = { ...session, saved_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
@@ -17087,7 +17142,28 @@ function registerImportCommand(program3) {
|
|
|
17087
17142
|
ensureHyvDir();
|
|
17088
17143
|
writeCachedProfile(name, content);
|
|
17089
17144
|
console.log(import_chalk13.default.green(`
|
|
17090
|
-
\u2713 Profile imported: ${name}`));
|
|
17145
|
+
\u2713 Profile imported locally: ${name}`));
|
|
17146
|
+
const { getToken: getToken2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
17147
|
+
const { authenticatedRequest: authenticatedRequest2, cliApiUrl: cliApiUrl2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
17148
|
+
const token = getToken2();
|
|
17149
|
+
if (token) {
|
|
17150
|
+
console.log(import_chalk13.default.cyan("\nSyncing profile to your account..."));
|
|
17151
|
+
try {
|
|
17152
|
+
const syncResponse = await authenticatedRequest2(
|
|
17153
|
+
cliApiUrl2("/cli/profiles/new"),
|
|
17154
|
+
{ method: "POST", body: { name, content, source: "import" } }
|
|
17155
|
+
);
|
|
17156
|
+
if (syncResponse.status === 200) {
|
|
17157
|
+
console.log(import_chalk13.default.green(" \u2713 synced to your account"));
|
|
17158
|
+
} else {
|
|
17159
|
+
console.log(import_chalk13.default.yellow(" profile saved locally \u2014 run `hyv sync` to push to your account"));
|
|
17160
|
+
}
|
|
17161
|
+
} catch {
|
|
17162
|
+
console.log(import_chalk13.default.yellow(" profile saved locally \u2014 run `hyv sync` to push to your account"));
|
|
17163
|
+
}
|
|
17164
|
+
} else {
|
|
17165
|
+
console.log(import_chalk13.default.dim("\n not signed in \u2014 profile saved locally. run `hyv init` then `hyv sync` to back it up."));
|
|
17166
|
+
}
|
|
17091
17167
|
} catch (error) {
|
|
17092
17168
|
console.error(import_chalk13.default.red(`Error: ${error.message}`));
|
|
17093
17169
|
process.exit(1);
|
|
@@ -19319,6 +19395,69 @@ function formatMcpIntegrateReportText(result, opts = {}) {
|
|
|
19319
19395
|
}
|
|
19320
19396
|
return lines.join("\n");
|
|
19321
19397
|
}
|
|
19398
|
+
function printMcpIntegrateReport(result, opts = {}) {
|
|
19399
|
+
const { agentIdForConfiguredLabel, isAgentIntegrated } = loadPostinstallLib();
|
|
19400
|
+
const configuredIds = new Set(
|
|
19401
|
+
result.configured.map((label) => agentIdForConfiguredLabel(label)).filter(Boolean)
|
|
19402
|
+
);
|
|
19403
|
+
console.log(import_chalk33.default.bold("\nhold your voice \u2014 mcp integration\n"));
|
|
19404
|
+
console.log(import_chalk33.default.dim(` ${getEngineLabel()}
|
|
19405
|
+
`));
|
|
19406
|
+
const welcome = readWelcomeState();
|
|
19407
|
+
const profiles = listLocalProfileNames2();
|
|
19408
|
+
if (profiles.length > 0) {
|
|
19409
|
+
console.log(import_chalk33.default.dim(` voice profiles: ${profiles.join(", ")}`));
|
|
19410
|
+
} else {
|
|
19411
|
+
console.log(import_chalk33.default.yellow(" no voice profile yet \u2014 mcp still works (free scan). finish onboarding in terminal or in-chat via hyv_welcome"));
|
|
19412
|
+
}
|
|
19413
|
+
if (welcome.completed_steps?.length) {
|
|
19414
|
+
console.log(import_chalk33.default.dim(` welcome progress: ${welcome.completed_steps.join(", ")}`));
|
|
19415
|
+
}
|
|
19416
|
+
console.log("");
|
|
19417
|
+
if (result.detected.length === 0) {
|
|
19418
|
+
console.log(import_chalk33.default.yellow(" no supported ai apps detected on this machine."));
|
|
19419
|
+
console.log(import_chalk33.default.dim("\n install cursor, claude desktop, chatgpt desktop, or another supported app,"));
|
|
19420
|
+
console.log(import_chalk33.default.dim(" then run hyv mcp again \u2014 or hyv doctor --fix-agents to configure everything."));
|
|
19421
|
+
console.log(import_chalk33.default.dim("\n in chatgpt/claude/cursor: call hyv_welcome to onboard without the terminal."));
|
|
19422
|
+
console.log(import_chalk33.default.dim(" chatgpt desktop (paid): developer mode \u2192 new app \u2192 https://holdyourvoice.com/mcp + oauth"));
|
|
19423
|
+
console.log(import_chalk33.default.dim(" full steps: hyv mcp --setup-chatgpt\n"));
|
|
19424
|
+
return;
|
|
19425
|
+
}
|
|
19426
|
+
console.log(import_chalk33.default.bold("detected apps"));
|
|
19427
|
+
for (const app of result.detected) {
|
|
19428
|
+
const justConfigured = configuredIds.has(app.id);
|
|
19429
|
+
const integrated = isAgentIntegrated(app.id) || justConfigured;
|
|
19430
|
+
const mark = app.integration === "manual" ? import_chalk33.default.yellow("\u25CB") : integrated ? import_chalk33.default.green("\u2713") : import_chalk33.default.cyan("\u2192");
|
|
19431
|
+
const status = app.integration === "manual" ? "manual connector \u2014 see ~/.chatgpt/hyv-mcp-connector.txt" : justConfigured ? opts.force ? "updated now" : "configured now" : integrated ? "integrated" : "needs setup";
|
|
19432
|
+
console.log(` ${mark} ${app.label} \u2014 ${status}`);
|
|
19433
|
+
console.log(import_chalk33.default.dim(` ${app.reason} \xB7 ${app.integration}`));
|
|
19434
|
+
}
|
|
19435
|
+
if (result.configured.length > 0) {
|
|
19436
|
+
console.log(import_chalk33.default.green(`
|
|
19437
|
+
wired hyv into: ${result.configured.join(", ")}`));
|
|
19438
|
+
}
|
|
19439
|
+
if (result.warnings.length > 0) {
|
|
19440
|
+
console.log(import_chalk33.default.yellow("\n notes:"));
|
|
19441
|
+
for (const warning of result.warnings) {
|
|
19442
|
+
console.log(import_chalk33.default.yellow(` ! ${warning}`));
|
|
19443
|
+
}
|
|
19444
|
+
}
|
|
19445
|
+
const mcpApps = result.detected.filter((a) => a.integration === "mcp");
|
|
19446
|
+
const manualApps = result.detected.filter((a) => a.integration === "manual");
|
|
19447
|
+
console.log(import_chalk33.default.bold("\nnext steps"));
|
|
19448
|
+
console.log(import_chalk33.default.dim(" in this app: hyv_welcome (onboarding) \xB7 hyv_mcp_setup (status/refresh) \xB7 hyv_demo (try a scan)"));
|
|
19449
|
+
if (mcpApps.length > 0) {
|
|
19450
|
+
console.log(import_chalk33.default.dim(" restart apps that use mcp (cursor, claude desktop, antigravity, opencode)"));
|
|
19451
|
+
}
|
|
19452
|
+
if (manualApps.length > 0) {
|
|
19453
|
+
console.log(import_chalk33.default.dim(" chatgpt (recommended): developer mode \u2192 new app \u2192 https://holdyourvoice.com/mcp + oauth"));
|
|
19454
|
+
console.log(import_chalk33.default.dim(" chatgpt (free fallback): settings \u2192 connectors \u2192 command hyv, arguments mcp"));
|
|
19455
|
+
console.log(import_chalk33.default.dim(" full steps: hyv mcp --setup-chatgpt"));
|
|
19456
|
+
}
|
|
19457
|
+
console.log(import_chalk33.default.dim(" refresh stale configs after upgrade: hyv mcp --force"));
|
|
19458
|
+
console.log(import_chalk33.default.dim(" verify: hyv mcp --test"));
|
|
19459
|
+
console.log(import_chalk33.default.dim(" all hosts: hyv doctor --verify-hosts\n"));
|
|
19460
|
+
}
|
|
19322
19461
|
|
|
19323
19462
|
// src/mcp.ts
|
|
19324
19463
|
init_mcp_profile_hydrate();
|
|
@@ -19758,7 +19897,7 @@ var TOOLS = [
|
|
|
19758
19897
|
},
|
|
19759
19898
|
{
|
|
19760
19899
|
name: "hyv_scan",
|
|
19761
|
-
description: "Fast local scan for 80+ AI patterns + profile never-list/learned rules. FREE, offline. ALWAYS scan before finalizing written content.",
|
|
19900
|
+
description: "Fast local scan for 80+ AI patterns + profile never-list/learned rules. FREE, offline. ALWAYS scan before finalizing any written content \u2014 emails, posts, docs, replies, messages, or prose.",
|
|
19762
19901
|
inputSchema: {
|
|
19763
19902
|
type: "object",
|
|
19764
19903
|
properties: {
|
|
@@ -19971,6 +20110,16 @@ async function startMcpServer() {
|
|
|
19971
20110
|
mcpLog("info", `account profile sync skipped: ${r.error}`);
|
|
19972
20111
|
}).catch(() => {
|
|
19973
20112
|
});
|
|
20113
|
+
try {
|
|
20114
|
+
const result = runMcpAutoIntegrate({ force: false });
|
|
20115
|
+
if (result.configured.length > 0) {
|
|
20116
|
+
mcpLog("info", `mcp auto-configured: ${result.configured.join(", ")}`);
|
|
20117
|
+
}
|
|
20118
|
+
if (result.detected.length > 0 && result.configured.length === 0) {
|
|
20119
|
+
mcpLog("info", `detected apps (already configured): ${result.detected.map((a) => a.label).join(", ")}`);
|
|
20120
|
+
}
|
|
20121
|
+
} catch {
|
|
20122
|
+
}
|
|
19974
20123
|
let buffer = "";
|
|
19975
20124
|
process.stdin.setEncoding("utf-8");
|
|
19976
20125
|
let requestChain = Promise.resolve();
|
|
@@ -20335,7 +20484,7 @@ registerOpenCommand(program2);
|
|
|
20335
20484
|
registerWelcomeCommand(program2);
|
|
20336
20485
|
registerContentCommand(program2);
|
|
20337
20486
|
registerUpgradeCommand(program2);
|
|
20338
|
-
program2.command("mcp").description("
|
|
20487
|
+
program2.command("mcp").description("Detect installed apps, configure MCP, and start the MCP server").option("--setup", "Show MCP setup for Claude Desktop, Cursor, Windsurf, Codex").option("--test", "Run MCP health check (tools, profile, stdio)").option("--setup-chatgpt", "Show ChatGPT connector setup instructions").option("--force", "Force re-configure MCP even if already integrated").action(async (opts) => {
|
|
20339
20488
|
if (opts.setup) {
|
|
20340
20489
|
printMcpSetup();
|
|
20341
20490
|
return;
|
|
@@ -20394,6 +20543,10 @@ program2.command("mcp").description("Start MCP server (for Claude Desktop and ot
|
|
|
20394
20543
|
console.log("");
|
|
20395
20544
|
return;
|
|
20396
20545
|
}
|
|
20546
|
+
console.log(import_chalk35.default.bold("\nhold your voice \u2014 detecting and configuring mcp...\n"));
|
|
20547
|
+
const result = runMcpAutoIntegrate({ force: Boolean(opts.force) });
|
|
20548
|
+
printMcpIntegrateReport(result, { force: Boolean(opts.force) });
|
|
20549
|
+
console.log(import_chalk35.default.dim("\nstarting MCP server (press Ctrl+C to stop)...\n"));
|
|
20397
20550
|
startMcpServer();
|
|
20398
20551
|
});
|
|
20399
20552
|
program2.command("export").description("Export voice profile for LLMs").argument("[format]", "Export format (claude, chatgpt, generic, cursor)", "claude").option("--output <file>", "Write to file instead of stdout").option("--json", "Output as JSON").action(async (format, opts) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdyourvoice/hyv",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.23",
|
|
4
4
|
"description": "Free local AI writing scan for cursor & claude. MCP server, 220+ pattern detection, voice profiles. npx @holdyourvoice/hyv welcome",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -572,7 +572,7 @@ function setupAgents({
|
|
|
572
572
|
const codexDir = path.join(home, '.codex');
|
|
573
573
|
fs.mkdirSync(codexDir, { recursive: true });
|
|
574
574
|
const agentsFile = path.join(codexDir, 'AGENTS.md');
|
|
575
|
-
const src = path.join(pkgDir, 'agents', '
|
|
575
|
+
const src = path.join(pkgDir, 'agents', 'AGENTS.md');
|
|
576
576
|
let existing = '';
|
|
577
577
|
if (fs.existsSync(agentsFile)) existing = fs.readFileSync(agentsFile, 'utf-8');
|
|
578
578
|
const addition = fs.existsSync(src) ? fs.readFileSync(src, 'utf-8') : '';
|
|
@@ -648,10 +648,10 @@ function setupAgents({
|
|
|
648
648
|
if (!ocResult.ok) warnings.push(`opencode: could not update opencode.jsonc (${ocResult.reason})`);
|
|
649
649
|
|
|
650
650
|
const agentsFile = path.join(ocDir, 'AGENTS.md');
|
|
651
|
-
const
|
|
651
|
+
const agentsSrc = path.join(pkgDir, 'agents', 'AGENTS.md');
|
|
652
652
|
let existing = '';
|
|
653
653
|
if (fs.existsSync(agentsFile)) existing = fs.readFileSync(agentsFile, 'utf-8');
|
|
654
|
-
const addition = fs.existsSync(
|
|
654
|
+
const addition = fs.existsSync(agentsSrc) ? fs.readFileSync(agentsSrc, 'utf-8') : '';
|
|
655
655
|
if (addition && shouldUpgradeAgent(agentsFile, agentsMarker, pkgVersion)) {
|
|
656
656
|
const merged = mergeAgentsMd(existing, addition, 'hold-your-voice');
|
|
657
657
|
fs.mkdirSync(ocDir, { recursive: true });
|
|
@@ -730,8 +730,8 @@ function setupAgents({
|
|
|
730
730
|
|
|
731
731
|
// Generic reference copy (always when auto-configure runs)
|
|
732
732
|
try {
|
|
733
|
-
const genericSrc = path.join(pkgDir, 'agents', '
|
|
734
|
-
const genericDest = path.join(hyvDir, 'agents', '
|
|
733
|
+
const genericSrc = path.join(pkgDir, 'agents', 'AGENTS.md');
|
|
734
|
+
const genericDest = path.join(hyvDir, 'agents', 'AGENTS.md');
|
|
735
735
|
if (fs.existsSync(genericSrc)) installAgent(genericSrc, genericDest);
|
|
736
736
|
} catch {
|
|
737
737
|
// non-fatal
|