oh-my-claudecode 0.2.8 → 0.2.10
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 +203 -34
- 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 +198 -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 +16 -5
- package/dist/features/yith-archive/providers/embedding/local.d.ts.map +1 -1
- package/dist/features/yith-archive/providers/embedding/local.js +29 -11
- 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 +180 -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,198 @@
|
|
|
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
|
+
// Everything below comes from ONE raw parse of the on-disk KV JSON.
|
|
61
|
+
// Booting the full archive (createYithArchive) rebuilds search indexes
|
|
62
|
+
// over every observation — minutes at 400+ MB, absurd for a stats
|
|
63
|
+
// read. The KV layout is stable: scopes are top-level keys, entries
|
|
64
|
+
// are keys within each scope.
|
|
65
|
+
try {
|
|
66
|
+
const raw = JSON.parse(fs.readFileSync(necronomicon, "utf-8"));
|
|
67
|
+
const scopeSize = (scope) => {
|
|
68
|
+
const value = raw[scope];
|
|
69
|
+
return value && typeof value === "object" ? Object.keys(value).length : 0;
|
|
70
|
+
};
|
|
71
|
+
let observations = 0;
|
|
72
|
+
for (const [scope, value] of Object.entries(raw)) {
|
|
73
|
+
if (scope.startsWith("mem:obs:") && value && typeof value === "object") {
|
|
74
|
+
observations += Object.keys(value).length;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
archiveStats.observations = observations;
|
|
78
|
+
archiveStats.memories = scopeSize("mem:memories");
|
|
79
|
+
archiveStats.sessions = scopeSize("mem:sessions");
|
|
80
|
+
const pendingScope = raw["mem:pending-compression"];
|
|
81
|
+
archiveStats.pendingCompression = pendingScope?.state?.count ?? 0;
|
|
82
|
+
const bindScope = raw["mem:bind-state"];
|
|
83
|
+
if (bindScope?.current?.phases) {
|
|
84
|
+
archiveStats.bound = true;
|
|
85
|
+
for (const [phase, rec] of Object.entries(bindScope.current.phases)) {
|
|
86
|
+
archiveStats.bindPhases[phase] = rec?.status ?? "unknown";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
/* unreadable — leave zeros; doctor reports the error */
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Active embedding provider — constructing the provider object is cheap
|
|
95
|
+
// (the model only loads on a real embed call), so this stays instant.
|
|
96
|
+
try {
|
|
97
|
+
const { detectEmbeddingProvider } = await import("../features/yith-archive/config.js");
|
|
98
|
+
const providerId = detectEmbeddingProvider();
|
|
99
|
+
if (providerId === "local") {
|
|
100
|
+
const { LocalEmbeddingProvider } = await import("../features/yith-archive/providers/embedding/local.js");
|
|
101
|
+
const provider = new LocalEmbeddingProvider();
|
|
102
|
+
archiveStats.embeddingProvider = provider.name;
|
|
103
|
+
archiveStats.embeddingDimensions = provider.dimensions;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
archiveStats.embeddingProvider = providerId;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
/* embedding stack unavailable */
|
|
111
|
+
}
|
|
112
|
+
// ── Capture health ───────────────────────────────────────────────────
|
|
113
|
+
let lastSuccessEpoch = null;
|
|
114
|
+
try {
|
|
115
|
+
lastSuccessEpoch = parseInt(fs.readFileSync(path.join(yithDir, ".last-bind-success"), "utf-8").trim(), 10);
|
|
116
|
+
if (!Number.isFinite(lastSuccessEpoch))
|
|
117
|
+
lastSuccessEpoch = null;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
lastSuccessEpoch = null;
|
|
121
|
+
}
|
|
122
|
+
let cronInstalled = false;
|
|
123
|
+
try {
|
|
124
|
+
cronInstalled = execFileSync("crontab", ["-l"], {
|
|
125
|
+
encoding: "utf-8",
|
|
126
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
127
|
+
}).includes(BIND_CRON_MARKER);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
cronInstalled = false;
|
|
131
|
+
}
|
|
132
|
+
let retentionDays = null;
|
|
133
|
+
try {
|
|
134
|
+
const settings = JSON.parse(fs.readFileSync(path.join(HOME, ".claude", "settings.json"), "utf-8"));
|
|
135
|
+
retentionDays = typeof settings.cleanupPeriodDays === "number" ? settings.cleanupPeriodDays : null;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
retentionDays = null;
|
|
139
|
+
}
|
|
140
|
+
// ── Agents / hooks / config ──────────────────────────────────────────
|
|
141
|
+
const config = loadPluginConfig(projectDirectory);
|
|
142
|
+
const agentsDir = path.join(HOME, ".claude", "agents");
|
|
143
|
+
const disabledAgents = new Set(config.disabled_agents ?? []);
|
|
144
|
+
const agents = Object.entries(AGENT_METADATA_MAP)
|
|
145
|
+
.filter(([name]) => !disabledAgents.has(name))
|
|
146
|
+
.map(([name, meta]) => ({
|
|
147
|
+
name,
|
|
148
|
+
model: config.agents?.[name]?.model ?? DEFAULT_AGENT_MODELS[name] ?? "sonnet",
|
|
149
|
+
installed: fs.existsSync(path.join(agentsDir, `${name}.md`)),
|
|
150
|
+
category: meta.category,
|
|
151
|
+
cost: meta.cost,
|
|
152
|
+
}));
|
|
153
|
+
const hooksDir = path.join(HOME, ".claude", "hooks");
|
|
154
|
+
const disabledHooks = new Set(config.disabled_hooks ?? []);
|
|
155
|
+
const hooks = ALL_HOOK_DEFINITIONS.filter((h) => !disabledHooks.has(h.name)).map((h) => ({
|
|
156
|
+
name: h.name,
|
|
157
|
+
event: h.event,
|
|
158
|
+
installed: fs.existsSync(path.join(hooksDir, path.basename(h.scriptPath))),
|
|
159
|
+
}));
|
|
160
|
+
const configPath = path.join(HOME, ".claude", "oh-my-claudecode.jsonc");
|
|
161
|
+
const { CLI_VERSION } = await import("./version.js");
|
|
162
|
+
return {
|
|
163
|
+
version: CLI_VERSION,
|
|
164
|
+
generatedAt: new Date().toISOString(),
|
|
165
|
+
archive: archiveStats,
|
|
166
|
+
capture: { lastSuccessEpoch, cronInstalled, retentionDays },
|
|
167
|
+
agents,
|
|
168
|
+
hooks,
|
|
169
|
+
config: {
|
|
170
|
+
path: configPath,
|
|
171
|
+
exists: fs.existsSync(configPath),
|
|
172
|
+
disabledAgents: config.disabled_agents ?? [],
|
|
173
|
+
disabledHooks: config.disabled_hooks ?? [],
|
|
174
|
+
webResearch: config.web_research?.enabled !== false,
|
|
175
|
+
typeSafety: config.type_safety?.enabled !== false,
|
|
176
|
+
frontendDesign: config.frontend_design?.enabled !== false,
|
|
177
|
+
},
|
|
178
|
+
doctor: await collectChecks(projectDirectory),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
export async function runStats(options = {}) {
|
|
182
|
+
const snapshot = await collectStats();
|
|
183
|
+
if (options.json) {
|
|
184
|
+
console.log(JSON.stringify(snapshot, null, 2));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Human summary — the dashboard TUI is the rich view.
|
|
188
|
+
const a = snapshot.archive;
|
|
189
|
+
console.log(`\noh-my-claudecode v${snapshot.version}`);
|
|
190
|
+
console.log(` Archive: ${a.memories} memories, ${a.observations} observations, ${a.sessions} sessions`);
|
|
191
|
+
console.log(` Pending: ${a.pendingCompression} observations awaiting compression`);
|
|
192
|
+
console.log(` Disk: ${(a.diskBytes / 1024 / 1024).toFixed(1)} MB archive, ${(a.modelCacheBytes / 1024 / 1024).toFixed(0)} MB model cache`);
|
|
193
|
+
console.log(` Embedding: ${a.embeddingProvider ?? "none"} (${a.embeddingDimensions ?? "?"} dims)`);
|
|
194
|
+
console.log(` Agents: ${snapshot.agents.filter((x) => x.installed).length}/${snapshot.agents.length} installed`);
|
|
195
|
+
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`);
|
|
196
|
+
console.log(`\nRun \`oh-my-claudecode dashboard\` for the full TUI.\n`);
|
|
197
|
+
}
|
|
198
|
+
//# 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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"}
|