oh-my-claudecode 0.2.7 → 0.2.9
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 +170 -68
- package/commands/cthulhu.md +9 -1
- package/commands/invoke-shub.md +8 -2
- package/commands/shoggoth.md +15 -25
- package/commands/yog-sothoth.md +18 -25
- package/dist/agents/render.d.ts +11 -0
- package/dist/agents/render.d.ts.map +1 -0
- package/dist/agents/render.js +69 -0
- package/dist/agents/render.js.map +1 -0
- package/dist/cli/dashboard.d.ts +12 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/dashboard.js +58 -0
- package/dist/cli/dashboard.js.map +1 -0
- package/dist/cli/doctor.d.ts +11 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +163 -9
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.js +72 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/install.d.ts +6 -0
- package/dist/cli/install.d.ts.map +1 -1
- package/dist/cli/install.js +211 -44
- package/dist/cli/install.js.map +1 -1
- package/dist/cli/lint.d.ts +26 -0
- package/dist/cli/lint.d.ts.map +1 -0
- package/dist/cli/lint.js +86 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/stats.d.ts +56 -0
- package/dist/cli/stats.d.ts.map +1 -0
- package/dist/cli/stats.js +197 -0
- package/dist/cli/stats.js.map +1 -0
- package/dist/cli/sync.d.ts +44 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +154 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/config/schema.d.ts +337 -331
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +14 -10
- package/dist/config/schema.js.map +1 -1
- package/dist/features/block-summarizer/index.js +1 -0
- package/dist/features/block-summarizer/index.js.map +1 -1
- package/dist/features/yith-archive/config.d.ts.map +1 -1
- package/dist/features/yith-archive/config.js +11 -15
- package/dist/features/yith-archive/config.js.map +1 -1
- package/dist/features/yith-archive/eval/schemas.d.ts +2 -2
- package/dist/features/yith-archive/functions/migrate.d.ts.map +1 -1
- package/dist/features/yith-archive/functions/migrate.js +7 -3
- package/dist/features/yith-archive/functions/migrate.js.map +1 -1
- package/dist/features/yith-archive/functions/opencode-import.d.ts.map +1 -1
- package/dist/features/yith-archive/functions/opencode-import.js +54 -27
- package/dist/features/yith-archive/functions/opencode-import.js.map +1 -1
- package/dist/features/yith-archive/functions/smart-search.js.map +1 -1
- package/dist/features/yith-archive/functions/temporal-graph.d.ts.map +1 -1
- package/dist/features/yith-archive/functions/temporal-graph.js +1 -0
- package/dist/features/yith-archive/functions/temporal-graph.js.map +1 -1
- package/dist/features/yith-archive/providers/embedding/local.d.ts +17 -6
- package/dist/features/yith-archive/providers/embedding/local.d.ts.map +1 -1
- package/dist/features/yith-archive/providers/embedding/local.js +32 -14
- package/dist/features/yith-archive/providers/embedding/local.js.map +1 -1
- package/dist/features/yith-archive/state/fake-sdk.d.ts.map +1 -1
- package/dist/features/yith-archive/state/fake-sdk.js.map +1 -1
- package/dist/features/yith-archive/state/reranker.d.ts.map +1 -1
- package/dist/features/yith-archive/state/reranker.js +9 -2
- package/dist/features/yith-archive/state/reranker.js.map +1 -1
- package/dist/features/yith-archive/state/vector-index.d.ts.map +1 -1
- package/dist/features/yith-archive/state/vector-index.js +1 -0
- package/dist/features/yith-archive/state/vector-index.js.map +1 -1
- package/dist/hooks/agent-sync.d.ts +16 -0
- package/dist/hooks/agent-sync.d.ts.map +1 -0
- package/dist/hooks/agent-sync.js +42 -0
- package/dist/hooks/agent-sync.js.map +1 -0
- package/dist/hooks/comment-checker.d.ts +1 -1
- package/dist/hooks/comment-checker.d.ts.map +1 -1
- package/dist/hooks/comment-checker.js +10 -0
- package/dist/hooks/comment-checker.js.map +1 -1
- package/dist/hooks/cthulhu-auto.d.ts +1 -1
- package/dist/hooks/cthulhu-auto.d.ts.map +1 -1
- package/dist/hooks/cthulhu-auto.js +77 -8
- package/dist/hooks/cthulhu-auto.js.map +1 -1
- package/dist/hooks/cthulhu-preflight.d.ts.map +1 -1
- package/dist/hooks/cthulhu-preflight.js +6 -5
- package/dist/hooks/cthulhu-preflight.js.map +1 -1
- package/dist/hooks/design-detector-hook.d.ts +6 -5
- package/dist/hooks/design-detector-hook.d.ts.map +1 -1
- package/dist/hooks/design-detector-hook.js +27 -8
- package/dist/hooks/design-detector-hook.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +43 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/web-research-hook.d.ts +6 -5
- package/dist/hooks/web-research-hook.d.ts.map +1 -1
- package/dist/hooks/web-research-hook.js +30 -9
- package/dist/hooks/web-research-hook.js.map +1 -1
- package/dist/hooks/write-guard.d.ts +1 -1
- package/dist/hooks/write-guard.d.ts.map +1 -1
- package/dist/hooks/write-guard.js +10 -0
- package/dist/hooks/write-guard.js.map +1 -1
- package/dist/hooks/yith-capture.d.ts +9 -3
- package/dist/hooks/yith-capture.d.ts.map +1 -1
- package/dist/hooks/yith-capture.js +43 -14
- package/dist/hooks/yith-capture.js.map +1 -1
- package/dist/index.d.ts +12 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/linters/type-safety-ast.d.ts.map +1 -1
- package/dist/linters/type-safety-ast.js +42 -24
- package/dist/linters/type-safety-ast.js.map +1 -1
- package/dist/shared/ascii-logo.d.ts +24 -0
- package/dist/shared/ascii-logo.d.ts.map +1 -0
- package/dist/shared/ascii-logo.js +77 -0
- package/dist/shared/ascii-logo.js.map +1 -0
- package/dist/shared/model-resolution.d.ts +19 -6
- package/dist/shared/model-resolution.d.ts.map +1 -1
- package/dist/shared/model-resolution.js +25 -12
- package/dist/shared/model-resolution.js.map +1 -1
- package/package.json +9 -6
- package/tui/dashboard.tsx +504 -0
- package/tui/data.ts +178 -0
- package/tui/theme.ts +51 -0
- package/tui/tsconfig.json +15 -0
- package/tui/wizard.tsx +219 -0
- package/dist/plugin-handlers/config-handler.d.ts +0 -21
- package/dist/plugin-handlers/config-handler.d.ts.map +0 -1
- package/dist/plugin-handlers/config-handler.js +0 -33
- package/dist/plugin-handlers/config-handler.js.map +0 -1
- package/dist/plugin-handlers/index.d.ts +0 -2
- package/dist/plugin-handlers/index.d.ts.map +0 -1
- package/dist/plugin-handlers/index.js +0 -2
- package/dist/plugin-handlers/index.js.map +0 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { collectChecks } from "./doctor.js";
|
|
5
|
+
import { BIND_CRON_MARKER } from "./bind-cron.js";
|
|
6
|
+
import { loadPluginConfig } from "../plugin-config.js";
|
|
7
|
+
import { AGENT_METADATA_MAP } from "../agents/builtin-agents.js";
|
|
8
|
+
import { ALL_HOOK_DEFINITIONS } from "../hooks/index.js";
|
|
9
|
+
import { DEFAULT_AGENT_MODELS } from "../shared/model-resolution.js";
|
|
10
|
+
function home() {
|
|
11
|
+
return process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
12
|
+
}
|
|
13
|
+
function dirSize(dir) {
|
|
14
|
+
let total = 0;
|
|
15
|
+
try {
|
|
16
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
17
|
+
const p = path.join(dir, entry.name);
|
|
18
|
+
if (entry.isDirectory())
|
|
19
|
+
total += dirSize(p);
|
|
20
|
+
else if (entry.isFile())
|
|
21
|
+
total += fs.statSync(p).size;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* unreadable — report what we have */
|
|
26
|
+
}
|
|
27
|
+
return total;
|
|
28
|
+
}
|
|
29
|
+
export async function collectStats(projectDirectory = process.cwd()) {
|
|
30
|
+
const HOME = home();
|
|
31
|
+
const yithDir = path.join(HOME, ".oh-my-claudecode", "yith");
|
|
32
|
+
const necronomicon = path.join(yithDir, "necronomicon.json");
|
|
33
|
+
// ── Archive ──────────────────────────────────────────────────────────
|
|
34
|
+
const archiveStats = {
|
|
35
|
+
bound: false,
|
|
36
|
+
memories: 0,
|
|
37
|
+
observations: 0,
|
|
38
|
+
sessions: 0,
|
|
39
|
+
pendingCompression: 0,
|
|
40
|
+
diskBytes: 0,
|
|
41
|
+
modelCacheBytes: 0,
|
|
42
|
+
embeddingProvider: null,
|
|
43
|
+
embeddingDimensions: null,
|
|
44
|
+
bindPhases: {},
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
archiveStats.diskBytes = fs.statSync(necronomicon).size;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* not bound yet */
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const { localModelCacheDir } = await import("../features/yith-archive/providers/embedding/local.js");
|
|
54
|
+
archiveStats.modelCacheBytes = dirSize(localModelCacheDir());
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* embedding stack unavailable */
|
|
58
|
+
}
|
|
59
|
+
if (fs.existsSync(necronomicon)) {
|
|
60
|
+
// Observations are stored per-session (one `mem:obs:<sessionId>` scope
|
|
61
|
+
// each) — count them straight off the on-disk KV JSON rather than
|
|
62
|
+
// probing hundreds of scopes through the archive API.
|
|
63
|
+
try {
|
|
64
|
+
const raw = JSON.parse(fs.readFileSync(necronomicon, "utf-8"));
|
|
65
|
+
let observations = 0;
|
|
66
|
+
for (const [scope, value] of Object.entries(raw)) {
|
|
67
|
+
if (scope.startsWith("mem:obs:") && value && typeof value === "object") {
|
|
68
|
+
observations += Object.keys(value).length;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
archiveStats.observations = observations;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
/* unreadable — leave zero */
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const { createYithArchive } = await import("../features/yith-archive/index.js");
|
|
78
|
+
const archive = createYithArchive();
|
|
79
|
+
try {
|
|
80
|
+
archiveStats.memories = (await archive.kv.list("mem:memories")).length;
|
|
81
|
+
archiveStats.sessions = (await archive.kv.list("mem:sessions")).length;
|
|
82
|
+
const pending = await archive.kv
|
|
83
|
+
.get("mem:pending-compression", "state")
|
|
84
|
+
.catch(() => null);
|
|
85
|
+
archiveStats.pendingCompression = pending?.count ?? 0;
|
|
86
|
+
const bindState = await archive.kv
|
|
87
|
+
.get("mem:bind-state", "current")
|
|
88
|
+
.catch(() => null);
|
|
89
|
+
if (bindState?.phases) {
|
|
90
|
+
archiveStats.bound = true;
|
|
91
|
+
for (const [phase, rec] of Object.entries(bindState.phases)) {
|
|
92
|
+
archiveStats.bindPhases[phase] = rec?.status ?? "unknown";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Report the ACTIVE provider (what new embeddings use), falling
|
|
96
|
+
// back to the index metadata only when no provider is configured.
|
|
97
|
+
const meta = await archive.kv
|
|
98
|
+
.get("mem:index:meta", "current")
|
|
99
|
+
.catch(() => null);
|
|
100
|
+
archiveStats.embeddingProvider = archive.embeddingProvider?.name ?? meta?.embeddingProvider ?? null;
|
|
101
|
+
archiveStats.embeddingDimensions = archive.embeddingProvider?.dimensions ?? meta?.dimensions ?? null;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
await archive.shutdown();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
/* archive unreadable — leave zeros; doctor reports the error */
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// ── Capture health ───────────────────────────────────────────────────
|
|
112
|
+
let lastSuccessEpoch = null;
|
|
113
|
+
try {
|
|
114
|
+
lastSuccessEpoch = parseInt(fs.readFileSync(path.join(yithDir, ".last-bind-success"), "utf-8").trim(), 10);
|
|
115
|
+
if (!Number.isFinite(lastSuccessEpoch))
|
|
116
|
+
lastSuccessEpoch = null;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
lastSuccessEpoch = null;
|
|
120
|
+
}
|
|
121
|
+
let cronInstalled = false;
|
|
122
|
+
try {
|
|
123
|
+
cronInstalled = execFileSync("crontab", ["-l"], {
|
|
124
|
+
encoding: "utf-8",
|
|
125
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
126
|
+
}).includes(BIND_CRON_MARKER);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
cronInstalled = false;
|
|
130
|
+
}
|
|
131
|
+
let retentionDays = null;
|
|
132
|
+
try {
|
|
133
|
+
const settings = JSON.parse(fs.readFileSync(path.join(HOME, ".claude", "settings.json"), "utf-8"));
|
|
134
|
+
retentionDays = typeof settings.cleanupPeriodDays === "number" ? settings.cleanupPeriodDays : null;
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
retentionDays = null;
|
|
138
|
+
}
|
|
139
|
+
// ── Agents / hooks / config ──────────────────────────────────────────
|
|
140
|
+
const config = loadPluginConfig(projectDirectory);
|
|
141
|
+
const agentsDir = path.join(HOME, ".claude", "agents");
|
|
142
|
+
const disabledAgents = new Set(config.disabled_agents ?? []);
|
|
143
|
+
const agents = Object.entries(AGENT_METADATA_MAP)
|
|
144
|
+
.filter(([name]) => !disabledAgents.has(name))
|
|
145
|
+
.map(([name, meta]) => ({
|
|
146
|
+
name,
|
|
147
|
+
model: config.agents?.[name]?.model ?? DEFAULT_AGENT_MODELS[name] ?? "sonnet",
|
|
148
|
+
installed: fs.existsSync(path.join(agentsDir, `${name}.md`)),
|
|
149
|
+
category: meta.category,
|
|
150
|
+
cost: meta.cost,
|
|
151
|
+
}));
|
|
152
|
+
const hooksDir = path.join(HOME, ".claude", "hooks");
|
|
153
|
+
const disabledHooks = new Set(config.disabled_hooks ?? []);
|
|
154
|
+
const hooks = ALL_HOOK_DEFINITIONS.filter((h) => !disabledHooks.has(h.name)).map((h) => ({
|
|
155
|
+
name: h.name,
|
|
156
|
+
event: h.event,
|
|
157
|
+
installed: fs.existsSync(path.join(hooksDir, path.basename(h.scriptPath))),
|
|
158
|
+
}));
|
|
159
|
+
const configPath = path.join(HOME, ".claude", "oh-my-claudecode.jsonc");
|
|
160
|
+
const { CLI_VERSION } = await import("./version.js");
|
|
161
|
+
return {
|
|
162
|
+
version: CLI_VERSION,
|
|
163
|
+
generatedAt: new Date().toISOString(),
|
|
164
|
+
archive: archiveStats,
|
|
165
|
+
capture: { lastSuccessEpoch, cronInstalled, retentionDays },
|
|
166
|
+
agents,
|
|
167
|
+
hooks,
|
|
168
|
+
config: {
|
|
169
|
+
path: configPath,
|
|
170
|
+
exists: fs.existsSync(configPath),
|
|
171
|
+
disabledAgents: config.disabled_agents ?? [],
|
|
172
|
+
disabledHooks: config.disabled_hooks ?? [],
|
|
173
|
+
webResearch: config.web_research?.enabled !== false,
|
|
174
|
+
typeSafety: config.type_safety?.enabled !== false,
|
|
175
|
+
frontendDesign: config.frontend_design?.enabled !== false,
|
|
176
|
+
},
|
|
177
|
+
doctor: await collectChecks(projectDirectory),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
export async function runStats(options = {}) {
|
|
181
|
+
const snapshot = await collectStats();
|
|
182
|
+
if (options.json) {
|
|
183
|
+
console.log(JSON.stringify(snapshot, null, 2));
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Human summary — the dashboard TUI is the rich view.
|
|
187
|
+
const a = snapshot.archive;
|
|
188
|
+
console.log(`\noh-my-claudecode v${snapshot.version}`);
|
|
189
|
+
console.log(` Archive: ${a.memories} memories, ${a.observations} observations, ${a.sessions} sessions`);
|
|
190
|
+
console.log(` Pending: ${a.pendingCompression} observations awaiting compression`);
|
|
191
|
+
console.log(` Disk: ${(a.diskBytes / 1024 / 1024).toFixed(1)} MB archive, ${(a.modelCacheBytes / 1024 / 1024).toFixed(0)} MB model cache`);
|
|
192
|
+
console.log(` Embedding: ${a.embeddingProvider ?? "none"} (${a.embeddingDimensions ?? "?"} dims)`);
|
|
193
|
+
console.log(` Agents: ${snapshot.agents.filter((x) => x.installed).length}/${snapshot.agents.length} installed`);
|
|
194
|
+
console.log(` Doctor: ${snapshot.doctor.filter((d) => d.status === "ok").length} ok, ${snapshot.doctor.filter((d) => d.status === "warn").length} warn, ${snapshot.doctor.filter((d) => d.status === "error").length} error`);
|
|
195
|
+
console.log(`\nRun \`oh-my-claudecode dashboard\` for the full TUI.\n`);
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/cli/stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `oh-my-claudecode sync` — render the Elder God agent definitions into
|
|
3
|
+
* Claude Code's user-level custom-agent directory (~/.claude/agents/).
|
|
4
|
+
*
|
|
5
|
+
* This is what makes `Agent(subagent_type: "shoggoth")` & friends resolve
|
|
6
|
+
* at runtime. It is idempotent and config-driven: user overrides from
|
|
7
|
+
* ~/.claude/oh-my-claudecode.jsonc (model, prompt_append, tools,
|
|
8
|
+
* disabled_agents, per-agent disable) are applied before rendering, so
|
|
9
|
+
* editing the config and re-running sync is the supported customization
|
|
10
|
+
* path. The installer runs it automatically; a SessionStart hook re-runs
|
|
11
|
+
* it in the background so config edits propagate without manual steps.
|
|
12
|
+
*
|
|
13
|
+
* Ownership rules: sync only ever touches `*.md` files directly inside
|
|
14
|
+
* ~/.claude/agents/ that carry the oh-my-claudecode generated marker.
|
|
15
|
+
* Hand-written agents (no marker) and agents in subdirectories are never
|
|
16
|
+
* modified or removed.
|
|
17
|
+
*/
|
|
18
|
+
export interface SyncOptions {
|
|
19
|
+
/** Report drift without writing anything. */
|
|
20
|
+
check?: boolean;
|
|
21
|
+
/** Suppress console output (hook/background mode). */
|
|
22
|
+
quiet?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Project directory. When the project is OMC-activated (.elder-gods/)
|
|
25
|
+
* and has a project-level config with agent overrides, the agents whose
|
|
26
|
+
* effective config differs from the user-level render are additionally
|
|
27
|
+
* written to `<project>/.claude/agents/` — Claude Code's project agents
|
|
28
|
+
* shadow user agents of the same name, which is how project config
|
|
29
|
+
* overrides user config for agents.
|
|
30
|
+
*/
|
|
31
|
+
projectDir?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface SyncOutcome {
|
|
34
|
+
/** True when the directory already matched the desired state. */
|
|
35
|
+
inSync: boolean;
|
|
36
|
+
written: string[];
|
|
37
|
+
removed: string[];
|
|
38
|
+
unchanged: string[];
|
|
39
|
+
agentsDir: string;
|
|
40
|
+
}
|
|
41
|
+
/** Compute the desired agent-file set from definitions + user config. */
|
|
42
|
+
export declare function computeDesiredAgentFiles(): Map<string, string>;
|
|
43
|
+
export declare function runSync(options?: SyncOptions): Promise<SyncOutcome>;
|
|
44
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,sDAAsD;IACtD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AA0BD,yEAAyE;AACzE,wBAAgB,wBAAwB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAM9D;AAmFD,wBAAsB,OAAO,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CA8C7E"}
|
package/dist/cli/sync.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { buildBuiltinAgents } from "../agents/builtin-agents.js";
|
|
4
|
+
import { renderAgentMarkdown, GENERATED_MARKER } from "../agents/render.js";
|
|
5
|
+
import { detectConfigFile, loadPluginConfig } from "../plugin-config.js";
|
|
6
|
+
import { CLI_VERSION } from "./version.js";
|
|
7
|
+
function home() {
|
|
8
|
+
return process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
9
|
+
}
|
|
10
|
+
/** Render the desired agent-file set for a given (already merged) config. */
|
|
11
|
+
function desiredFilesFor(config) {
|
|
12
|
+
const disabled = new Set(config.disabled_agents ?? []);
|
|
13
|
+
for (const [name, override] of Object.entries(config.agents ?? {})) {
|
|
14
|
+
if (override?.disable)
|
|
15
|
+
disabled.add(name);
|
|
16
|
+
}
|
|
17
|
+
const agents = buildBuiltinAgents({
|
|
18
|
+
disabledAgents: [...disabled],
|
|
19
|
+
agentOverrides: config.agents ?? {},
|
|
20
|
+
useTaskSystem: config.cthulhu_agent?.use_task_system ?? false,
|
|
21
|
+
});
|
|
22
|
+
const files = new Map();
|
|
23
|
+
for (const [name, agent] of Object.entries(agents)) {
|
|
24
|
+
files.set(`${name}.md`, renderAgentMarkdown(agent, CLI_VERSION));
|
|
25
|
+
}
|
|
26
|
+
return files;
|
|
27
|
+
}
|
|
28
|
+
/** Compute the desired agent-file set from definitions + user config. */
|
|
29
|
+
export function computeDesiredAgentFiles() {
|
|
30
|
+
// User-level config only: generated agents are global (one set per
|
|
31
|
+
// machine), so per-project config must not leak into them. Passing
|
|
32
|
+
// HOME as the "project" makes the project-level lookup resolve to the
|
|
33
|
+
// same user config file — an idempotent self-merge.
|
|
34
|
+
return desiredFilesFor(loadPluginConfig(home()));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Reconcile one agents directory against a desired file set: write what
|
|
38
|
+
* differs, delete generated files no longer desired, never touch files
|
|
39
|
+
* without the ownership marker. Pure mechanics shared by the user-level
|
|
40
|
+
* and project-level passes.
|
|
41
|
+
*/
|
|
42
|
+
function reconcileAgentsDir(agentsDir, desired, check, acc) {
|
|
43
|
+
if (!check && desired.size > 0) {
|
|
44
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
for (const [filename, content] of desired) {
|
|
47
|
+
const target = path.join(agentsDir, filename);
|
|
48
|
+
let existing = null;
|
|
49
|
+
try {
|
|
50
|
+
existing = fs.readFileSync(target, "utf-8");
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
existing = null;
|
|
54
|
+
}
|
|
55
|
+
if (existing === content) {
|
|
56
|
+
acc.unchanged.push(filename);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (!check) {
|
|
60
|
+
fs.writeFileSync(target, content, "utf-8");
|
|
61
|
+
}
|
|
62
|
+
acc.written.push(filename);
|
|
63
|
+
}
|
|
64
|
+
let entries = [];
|
|
65
|
+
try {
|
|
66
|
+
entries = fs.readdirSync(agentsDir).filter((f) => f.endsWith(".md"));
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
entries = [];
|
|
70
|
+
}
|
|
71
|
+
for (const filename of entries) {
|
|
72
|
+
if (desired.has(filename))
|
|
73
|
+
continue;
|
|
74
|
+
const target = path.join(agentsDir, filename);
|
|
75
|
+
let content = "";
|
|
76
|
+
try {
|
|
77
|
+
if (!fs.statSync(target).isFile())
|
|
78
|
+
continue;
|
|
79
|
+
content = fs.readFileSync(target, "utf-8");
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (!content.includes(GENERATED_MARKER))
|
|
85
|
+
continue;
|
|
86
|
+
if (!check) {
|
|
87
|
+
fs.unlinkSync(target);
|
|
88
|
+
}
|
|
89
|
+
acc.removed.push(filename);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Compute the project-level agent file set: agents whose effective config
|
|
94
|
+
* under the merged user+project config differs from the user-level render.
|
|
95
|
+
* Empty unless the project is OMC-activated and has its own config file.
|
|
96
|
+
*/
|
|
97
|
+
function projectDesiredFiles(projectDir, userDesired) {
|
|
98
|
+
const desired = new Map();
|
|
99
|
+
if (!fs.existsSync(path.join(projectDir, ".elder-gods")))
|
|
100
|
+
return desired;
|
|
101
|
+
const projectConfig = detectConfigFile(path.join(projectDir, ".claude"));
|
|
102
|
+
if (!projectConfig.exists)
|
|
103
|
+
return desired;
|
|
104
|
+
const merged = desiredFilesFor(loadPluginConfig(projectDir));
|
|
105
|
+
for (const [filename, content] of merged) {
|
|
106
|
+
if (userDesired.get(filename) !== content) {
|
|
107
|
+
desired.set(filename, content);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return desired;
|
|
111
|
+
}
|
|
112
|
+
export async function runSync(options = {}) {
|
|
113
|
+
const agentsDir = path.join(home(), ".claude", "agents");
|
|
114
|
+
const desired = computeDesiredAgentFiles();
|
|
115
|
+
const acc = {
|
|
116
|
+
written: [],
|
|
117
|
+
removed: [],
|
|
118
|
+
unchanged: [],
|
|
119
|
+
};
|
|
120
|
+
reconcileAgentsDir(agentsDir, desired, options.check ?? false, acc);
|
|
121
|
+
// Project-level overrides: shadow user agents inside the project's own
|
|
122
|
+
// .claude/agents/ directory. Reconciliation also cleans up generated
|
|
123
|
+
// project agents whose override was removed from the project config.
|
|
124
|
+
if (options.projectDir && fs.existsSync(options.projectDir)) {
|
|
125
|
+
const projectAgentsDir = path.join(options.projectDir, ".claude", "agents");
|
|
126
|
+
const projectDesired = projectDesiredFiles(options.projectDir, desired);
|
|
127
|
+
if (projectDesired.size > 0 || fs.existsSync(projectAgentsDir)) {
|
|
128
|
+
reconcileAgentsDir(projectAgentsDir, projectDesired, options.check ?? false, acc);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const { written, removed, unchanged } = acc;
|
|
132
|
+
const inSync = written.length === 0 && removed.length === 0;
|
|
133
|
+
if (!options.quiet) {
|
|
134
|
+
if (options.check) {
|
|
135
|
+
if (inSync) {
|
|
136
|
+
console.log(` Agents in sync — ${unchanged.length} definitions in ${agentsDir}`);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
console.log(` Agents out of sync — ${written.length} to write, ${removed.length} to remove. ` +
|
|
140
|
+
`Run: oh-my-claudecode sync`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
for (const f of written)
|
|
145
|
+
console.log(` Installed agent: ${f.replace(/\.md$/, "")} → ${path.join(agentsDir, f)}`);
|
|
146
|
+
for (const f of removed)
|
|
147
|
+
console.log(` Removed stale agent: ${f}`);
|
|
148
|
+
console.log(` ${desired.size} agent definitions in ${agentsDir} ` +
|
|
149
|
+
`(${written.length} updated, ${unchanged.length} unchanged, ${removed.length} removed)`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { inSync, written, removed, unchanged, agentsDir };
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"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"}
|