claudecode-omc 5.3.0 → 5.5.0
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/.local/guidelines/CLAUDE.md +31 -0
- package/README.md +57 -1
- package/bundled/manifest.json +2 -2
- package/bundled/upstream/oh-my-claudecode/agents/analyst.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/architect.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/code-reviewer.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/code-simplifier.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/critic.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/debugger.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/designer.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/document-specialist.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/executor.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/explore.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/git-master.md +3 -3
- package/bundled/upstream/oh-my-claudecode/agents/planner.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/qa-tester.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/scientist.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/security-reviewer.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/test-engineer.md +1 -75
- package/bundled/upstream/oh-my-claudecode/agents/tracer.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/verifier.md +1 -1
- package/bundled/upstream/oh-my-claudecode/agents/writer.md +1 -1
- package/bundled/upstream/oh-my-claudecode/hooks/hooks.json +21 -1
- package/bundled/upstream/oh-my-claudecode/skills/AGENTS.md +200 -0
- package/bundled/upstream/oh-my-claudecode/skills/autopilot/SKILL.md +17 -10
- package/bundled/upstream/oh-my-claudecode/skills/autoresearch/SKILL.md +90 -0
- package/bundled/upstream/oh-my-claudecode/skills/cancel/SKILL.md +15 -6
- package/bundled/upstream/oh-my-claudecode/skills/configure-notifications/SKILL.md +12 -12
- package/bundled/upstream/oh-my-claudecode/skills/debug/SKILL.md +35 -0
- package/bundled/upstream/oh-my-claudecode/skills/deep-dive/SKILL.md +4 -0
- package/bundled/upstream/oh-my-claudecode/skills/deep-interview/SKILL.md +23 -18
- package/bundled/upstream/oh-my-claudecode/skills/hud/SKILL.md +23 -101
- package/bundled/upstream/oh-my-claudecode/skills/learner/SKILL.md +27 -2
- package/bundled/upstream/oh-my-claudecode/skills/mcp-setup/SKILL.md +67 -8
- package/bundled/upstream/oh-my-claudecode/skills/omc-doctor/SKILL.md +32 -47
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/SKILL.md +4 -2
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/phases/01-install-claude-md.md +15 -4
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/phases/02-configure.md +9 -9
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/phases/03-integrations.md +13 -13
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/phases/04-welcome.md +3 -3
- package/bundled/upstream/oh-my-claudecode/skills/omc-teams/SKILL.md +28 -0
- package/bundled/upstream/oh-my-claudecode/skills/plan/SKILL.md +1 -0
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/SKILL.md +25 -5
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/lib/config.sh +2 -15
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/lib/providers/github.sh +1 -1
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/lib/session.sh +2 -2
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/lib/tmux.sh +109 -4
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/lib/worktree.sh +26 -0
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/psm.sh +46 -5
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/templates/pr-review.md +5 -2
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/templates/projects.json +1 -1
- package/bundled/upstream/oh-my-claudecode/skills/project-session-manager/tests/test-psm-prompt-injection.sh +336 -0
- package/bundled/upstream/oh-my-claudecode/skills/ralph/SKILL.md +18 -9
- package/bundled/upstream/oh-my-claudecode/skills/ralplan/SKILL.md +2 -0
- package/bundled/upstream/oh-my-claudecode/skills/release/SKILL.md +167 -57
- package/bundled/upstream/oh-my-claudecode/skills/remember/SKILL.md +41 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/SKILL.md +391 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/data_contracts.md +274 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/scripts/plot_progress.py +128 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/scripts/resolve-paths.mjs +192 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/scripts/validate.sh +404 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/si-benchmark-builder.md +79 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/si-goal-clarifier.md +94 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/si-researcher.md +73 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/templates/agent-settings.json +14 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/templates/goal.md +22 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/templates/harness.md +18 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/templates/idea.md +5 -0
- package/bundled/upstream/oh-my-claudecode/skills/self-improve/templates/settings.json +23 -0
- package/bundled/upstream/oh-my-claudecode/skills/skill/SKILL.md +46 -77
- package/bundled/upstream/oh-my-claudecode/skills/skillify/SKILL.md +53 -0
- package/bundled/upstream/oh-my-claudecode/skills/team/SKILL.md +83 -11
- package/bundled/upstream/oh-my-claudecode/skills/trace/SKILL.md +1 -0
- package/bundled/upstream/oh-my-claudecode/skills/ultraqa/SKILL.md +1 -0
- package/bundled/upstream/oh-my-claudecode/skills/ultrawork/SKILL.md +1 -0
- package/bundled/upstream/oh-my-claudecode/skills/verify/SKILL.md +37 -0
- package/bundled/upstream/oh-my-claudecode/skills/wiki/SKILL.md +67 -0
- package/package.json +3 -1
- package/src/cli/artifact.js +63 -2
- package/src/cli/guidelines.js +83 -0
- package/src/cli/index.js +13 -1
- package/src/cli/setup.js +48 -18
- package/src/cli/source.js +35 -1
- package/src/config/artifact-types.js +12 -2
- package/src/config/paths.js +95 -4
- package/src/config/sources.js +29 -5
- package/src/guidelines/apply.js +152 -0
- package/src/guidelines/optimizer.js +325 -0
- package/src/merge/claude-md-merger.js +35 -12
- package/templates/merge-config.json +12 -1
- package/bundled/upstream/oh-my-claudecode/skills/omc-doctor/skill-debugger.md +0 -101
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Progress visualization for the self-improvement loop.
|
|
4
|
+
Reads raw_data.json and generates progress.png.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
python3 plot_progress.py --data /path/to/raw_data.json --output /path/to/progress.png
|
|
8
|
+
python3 plot_progress.py --tracking-dir /path/to/<self-improve-root>/tracking/
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import json
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def load_data(data_path: str) -> list:
|
|
18
|
+
path = Path(data_path)
|
|
19
|
+
if not path.exists():
|
|
20
|
+
print(f"Warning: {data_path} not found. No visualization generated.")
|
|
21
|
+
return []
|
|
22
|
+
with open(path) as f:
|
|
23
|
+
return json.load(f)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def plot_with_matplotlib(data: list, output_path: str):
|
|
27
|
+
try:
|
|
28
|
+
import matplotlib
|
|
29
|
+
matplotlib.use('Agg')
|
|
30
|
+
import matplotlib.pyplot as plt
|
|
31
|
+
except ImportError:
|
|
32
|
+
print("Warning: matplotlib not available. Generating text summary instead.")
|
|
33
|
+
generate_text_summary(data, output_path)
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
iterations = sorted(set(d['iteration'] for d in data))
|
|
37
|
+
winners = [d for d in data if d.get('is_winner')]
|
|
38
|
+
losers = [d for d in data if not d.get('is_winner')]
|
|
39
|
+
|
|
40
|
+
fig, ax = plt.subplots(figsize=(12, 6))
|
|
41
|
+
|
|
42
|
+
if losers:
|
|
43
|
+
ax.scatter(
|
|
44
|
+
[d['iteration'] for d in losers],
|
|
45
|
+
[d['benchmark_score'] for d in losers],
|
|
46
|
+
c='lightgray', alpha=0.5, s=30, label='Candidates', zorder=2
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if winners:
|
|
50
|
+
ax.plot(
|
|
51
|
+
[d['iteration'] for d in winners],
|
|
52
|
+
[d['benchmark_score'] for d in winners],
|
|
53
|
+
'b-o', linewidth=2, markersize=8, label='Winners', zorder=3
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
families = list(set(d.get('approach_family', 'unknown') for d in winners))
|
|
57
|
+
colors = plt.cm.Set2(range(len(families)))
|
|
58
|
+
family_color = dict(zip(families, colors))
|
|
59
|
+
for d in winners:
|
|
60
|
+
family = d.get('approach_family', 'unknown')
|
|
61
|
+
ax.annotate(
|
|
62
|
+
family[:4],
|
|
63
|
+
(d['iteration'], d['benchmark_score']),
|
|
64
|
+
textcoords="offset points", xytext=(0, 10),
|
|
65
|
+
fontsize=7, ha='center', color=family_color.get(family, 'black')
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
ax.set_xlabel('Iteration')
|
|
69
|
+
ax.set_ylabel('Benchmark Score')
|
|
70
|
+
ax.set_title('Self-Improvement Progress')
|
|
71
|
+
ax.legend(loc='best')
|
|
72
|
+
ax.grid(True, alpha=0.3)
|
|
73
|
+
|
|
74
|
+
plt.tight_layout()
|
|
75
|
+
plt.savefig(output_path, dpi=150)
|
|
76
|
+
plt.close()
|
|
77
|
+
print(f"Visualization saved to: {output_path}")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def generate_text_summary(data: list, output_path: str):
|
|
81
|
+
"""Fallback when matplotlib is not available."""
|
|
82
|
+
winners = [d for d in data if d.get('is_winner')]
|
|
83
|
+
summary_path = Path(output_path).with_suffix('.txt')
|
|
84
|
+
|
|
85
|
+
lines = ["Self-Improvement Progress Summary", "=" * 40, ""]
|
|
86
|
+
for w in winners:
|
|
87
|
+
lines.append(
|
|
88
|
+
f"Iteration {w['iteration']}: score={w['benchmark_score']:.4f} "
|
|
89
|
+
f"family={w.get('approach_family', '?')} plan={w.get('plan_id', '?')}"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
if winners:
|
|
93
|
+
scores = [w['benchmark_score'] for w in winners]
|
|
94
|
+
lines.append("")
|
|
95
|
+
lines.append(f"Best: {max(scores):.4f} Worst: {min(scores):.4f} "
|
|
96
|
+
f"Delta: {max(scores) - min(scores):.4f}")
|
|
97
|
+
|
|
98
|
+
with open(summary_path, 'w') as f:
|
|
99
|
+
f.write('\n'.join(lines))
|
|
100
|
+
print(f"Text summary saved to: {summary_path}")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def main():
|
|
104
|
+
parser = argparse.ArgumentParser(description='Self-improvement progress visualization')
|
|
105
|
+
parser.add_argument('--data', help='Path to raw_data.json')
|
|
106
|
+
parser.add_argument('--output', help='Path to output image')
|
|
107
|
+
parser.add_argument('--tracking-dir', help='Path to tracking/ directory (auto-discovers data and output)')
|
|
108
|
+
args = parser.parse_args()
|
|
109
|
+
|
|
110
|
+
if args.tracking_dir:
|
|
111
|
+
data_path = str(Path(args.tracking_dir) / 'raw_data.json')
|
|
112
|
+
output_path = str(Path(args.tracking_dir) / 'progress.png')
|
|
113
|
+
elif args.data and args.output:
|
|
114
|
+
data_path = args.data
|
|
115
|
+
output_path = args.output
|
|
116
|
+
else:
|
|
117
|
+
print("Usage: plot_progress.py --tracking-dir /path/ OR --data /path/raw_data.json --output /path/progress.png")
|
|
118
|
+
sys.exit(1)
|
|
119
|
+
|
|
120
|
+
data = load_data(data_path)
|
|
121
|
+
if not data:
|
|
122
|
+
sys.exit(0)
|
|
123
|
+
|
|
124
|
+
plot_with_matplotlib(data, output_path)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == '__main__':
|
|
128
|
+
main()
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_TOPIC_SLUG = 'default';
|
|
7
|
+
const TOPICS_DIR = 'topics';
|
|
8
|
+
|
|
9
|
+
function slugify(value) {
|
|
10
|
+
const normalized = String(value ?? '')
|
|
11
|
+
.normalize('NFKD')
|
|
12
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
13
|
+
.replace(/[^A-Za-z0-9\s_-]/g, ' ')
|
|
14
|
+
.trim()
|
|
15
|
+
.toLowerCase()
|
|
16
|
+
.replace(/[\s_]+/g, '-')
|
|
17
|
+
.replace(/-+/g, '-')
|
|
18
|
+
.replace(/^-+|-+$/g, '');
|
|
19
|
+
return normalized || DEFAULT_TOPIC_SLUG;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function parseArgs(argv) {
|
|
23
|
+
const result = {
|
|
24
|
+
projectRoot: process.cwd(),
|
|
25
|
+
topic: '',
|
|
26
|
+
slug: '',
|
|
27
|
+
format: 'json',
|
|
28
|
+
ensureDirs: false,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
32
|
+
const arg = argv[index];
|
|
33
|
+
const next = argv[index + 1];
|
|
34
|
+
|
|
35
|
+
if (arg === '--project-root' && next) {
|
|
36
|
+
result.projectRoot = next;
|
|
37
|
+
index += 1;
|
|
38
|
+
} else if (arg.startsWith('--project-root=')) {
|
|
39
|
+
result.projectRoot = arg.slice('--project-root='.length);
|
|
40
|
+
} else if (arg === '--topic' && next) {
|
|
41
|
+
result.topic = next;
|
|
42
|
+
index += 1;
|
|
43
|
+
} else if (arg.startsWith('--topic=')) {
|
|
44
|
+
result.topic = arg.slice('--topic='.length);
|
|
45
|
+
} else if (arg === '--slug' && next) {
|
|
46
|
+
result.slug = next;
|
|
47
|
+
index += 1;
|
|
48
|
+
} else if (arg.startsWith('--slug=')) {
|
|
49
|
+
result.slug = arg.slice('--slug='.length);
|
|
50
|
+
} else if (arg === '--format' && next) {
|
|
51
|
+
result.format = next;
|
|
52
|
+
index += 1;
|
|
53
|
+
} else if (arg.startsWith('--format=')) {
|
|
54
|
+
result.format = arg.slice('--format='.length);
|
|
55
|
+
} else if (arg === '--ensure-dirs') {
|
|
56
|
+
result.ensureDirs = true;
|
|
57
|
+
} else if (arg === '--help' || arg === '-h') {
|
|
58
|
+
result.help = true;
|
|
59
|
+
} else {
|
|
60
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!['json', 'shell'].includes(result.format)) {
|
|
65
|
+
throw new Error(`Unsupported format: ${result.format}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function hasLegacyLayout(baseRoot) {
|
|
72
|
+
return existsSync(join(baseRoot, 'config', 'settings.json'))
|
|
73
|
+
|| existsSync(join(baseRoot, 'state', 'agent-settings.json'));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function buildPaths(root, projectRoot, topicSlug, scopeMode) {
|
|
77
|
+
const configDir = join(root, 'config');
|
|
78
|
+
const stateDir = join(root, 'state');
|
|
79
|
+
const trackingDir = join(root, 'tracking');
|
|
80
|
+
const paths = {
|
|
81
|
+
project_root: projectRoot,
|
|
82
|
+
base_root: join(projectRoot, '.omc', 'self-improve'),
|
|
83
|
+
topic_slug: topicSlug,
|
|
84
|
+
scope_mode: scopeMode,
|
|
85
|
+
root,
|
|
86
|
+
config_dir: configDir,
|
|
87
|
+
state_dir: stateDir,
|
|
88
|
+
plans_dir: join(root, 'plans'),
|
|
89
|
+
tracking_dir: trackingDir,
|
|
90
|
+
settings_path: join(configDir, 'settings.json'),
|
|
91
|
+
goal_path: join(configDir, 'goal.md'),
|
|
92
|
+
harness_path: join(configDir, 'harness.md'),
|
|
93
|
+
idea_path: join(configDir, 'idea.md'),
|
|
94
|
+
agent_settings_path: join(stateDir, 'agent-settings.json'),
|
|
95
|
+
iteration_state_path: join(stateDir, 'iteration_state.json'),
|
|
96
|
+
research_briefs_dir: join(stateDir, 'research_briefs'),
|
|
97
|
+
iteration_history_dir: join(stateDir, 'iteration_history'),
|
|
98
|
+
merge_reports_dir: join(stateDir, 'merge_reports'),
|
|
99
|
+
plan_archive_dir: join(stateDir, 'plan_archive'),
|
|
100
|
+
raw_data_path: join(trackingDir, 'raw_data.json'),
|
|
101
|
+
baseline_path: join(trackingDir, 'baseline.json'),
|
|
102
|
+
events_path: join(trackingDir, 'events.json'),
|
|
103
|
+
progress_path: join(trackingDir, 'progress.png'),
|
|
104
|
+
};
|
|
105
|
+
return paths;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function ensureDirs(paths) {
|
|
109
|
+
for (const dirPath of [
|
|
110
|
+
paths.config_dir,
|
|
111
|
+
paths.state_dir,
|
|
112
|
+
paths.plans_dir,
|
|
113
|
+
paths.tracking_dir,
|
|
114
|
+
paths.research_briefs_dir,
|
|
115
|
+
paths.iteration_history_dir,
|
|
116
|
+
paths.merge_reports_dir,
|
|
117
|
+
paths.plan_archive_dir,
|
|
118
|
+
]) {
|
|
119
|
+
mkdirSync(dirPath, { recursive: true });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function resolveSelfImprovePaths({ projectRoot = process.cwd(), topic = '', slug = '' } = {}) {
|
|
124
|
+
const resolvedProjectRoot = resolve(projectRoot);
|
|
125
|
+
const baseRoot = join(resolvedProjectRoot, '.omc', 'self-improve');
|
|
126
|
+
const explicitSlug = slugify(slug || topic);
|
|
127
|
+
const legacyLayout = hasLegacyLayout(baseRoot);
|
|
128
|
+
const shouldUseLegacyRoot = !slug && !topic && legacyLayout;
|
|
129
|
+
const topicSlug = shouldUseLegacyRoot ? DEFAULT_TOPIC_SLUG : explicitSlug;
|
|
130
|
+
const root = shouldUseLegacyRoot
|
|
131
|
+
? baseRoot
|
|
132
|
+
: join(baseRoot, TOPICS_DIR, topicSlug);
|
|
133
|
+
const scopeMode = shouldUseLegacyRoot
|
|
134
|
+
? 'legacy-flat-root'
|
|
135
|
+
: (slug || topic ? 'topic-scoped' : 'default-scoped');
|
|
136
|
+
|
|
137
|
+
return buildPaths(root, resolvedProjectRoot, topicSlug, scopeMode);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function renderShell(paths) {
|
|
141
|
+
return Object.entries(paths)
|
|
142
|
+
.map(([key, value]) => `${key}=${JSON.stringify(value)}`)
|
|
143
|
+
.join('\n');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function printHelp() {
|
|
147
|
+
process.stdout.write(
|
|
148
|
+
[
|
|
149
|
+
'Usage: node resolve-paths.mjs [--project-root PATH] [--topic TEXT | --slug SLUG] [--ensure-dirs] [--format json|shell]',
|
|
150
|
+
'',
|
|
151
|
+
'Resolves self-improve artifact paths.',
|
|
152
|
+
'- New runs default to .omc/self-improve/topics/<topic-slug>/',
|
|
153
|
+
'- Legacy flat .omc/self-improve/ is preserved only when no topic/slug is supplied and a flat layout already exists',
|
|
154
|
+
'',
|
|
155
|
+
].join('\n'),
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function main() {
|
|
160
|
+
const args = parseArgs(process.argv.slice(2));
|
|
161
|
+
if (args.help) {
|
|
162
|
+
printHelp();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const paths = resolveSelfImprovePaths({
|
|
167
|
+
projectRoot: args.projectRoot,
|
|
168
|
+
topic: args.topic,
|
|
169
|
+
slug: args.slug,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
if (args.ensureDirs) {
|
|
173
|
+
ensureDirs(paths);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (args.format === 'shell') {
|
|
177
|
+
process.stdout.write(`${renderShell(paths)}\n`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
process.stdout.write(`${JSON.stringify(paths, null, 2)}\n`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
185
|
+
try {
|
|
186
|
+
main();
|
|
187
|
+
} catch (error) {
|
|
188
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
189
|
+
process.stderr.write(`${message}\n`);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|