magus-cli 0.0.0-placeholder → 7.0.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/README.md +309 -0
- package/bin/magus.js +170 -0
- package/package.json +67 -3
- package/scripts/build-binaries.ts +113 -0
- package/scripts/capture-builtin.ts +412 -0
- package/scripts/check-optional-deps.ts +49 -0
- package/scripts/test-isolated.ts +49 -0
- package/scripts/verify-binary.ts +95 -0
- package/scripts/verify-community-registry.ts +272 -0
- package/src/__tests__/active-closure.test.ts +184 -0
- package/src/__tests__/alias-adopt.test.ts +365 -0
- package/src/__tests__/alias-parser.test.ts +417 -0
- package/src/__tests__/alias-shell-writer.test.ts +681 -0
- package/src/__tests__/alias-store.test.ts +163 -0
- package/src/__tests__/binary-signing.test.ts +120 -0
- package/src/__tests__/blackbox-active-closure.test.ts +119 -0
- package/src/__tests__/blackbox-convergence.test.ts +334 -0
- package/src/__tests__/blackbox-parity.test.ts +684 -0
- package/src/__tests__/blackbox-plugin-state.test.ts +523 -0
- package/src/__tests__/blackbox-tool-state.test.ts +669 -0
- package/src/__tests__/cache-provenance.test.ts +84 -0
- package/src/__tests__/capture-builtin.test.ts +92 -0
- package/src/__tests__/catalog-cache-store.test.ts +309 -0
- package/src/__tests__/catalog-notice.test.ts +155 -0
- package/src/__tests__/cli-ansi.test.ts +297 -0
- package/src/__tests__/cli-apply-seams.test.ts +288 -0
- package/src/__tests__/cli-live.test.ts +391 -0
- package/src/__tests__/cli-router.test.ts +240 -0
- package/src/__tests__/cli-tool-commands.test.ts +239 -0
- package/src/__tests__/cli-tools-adapter.test.ts +294 -0
- package/src/__tests__/cli-update-view.test.ts +445 -0
- package/src/__tests__/community-fetch.test.ts +545 -0
- package/src/__tests__/community-registry.test.ts +269 -0
- package/src/__tests__/community-staleness.test.ts +720 -0
- package/src/__tests__/component-badge.test.ts +98 -0
- package/src/__tests__/component-icons.test.ts +94 -0
- package/src/__tests__/content-drift.test.ts +353 -0
- package/src/__tests__/conventions-integration.test.ts +830 -0
- package/src/__tests__/conventions-manager.test.ts +1236 -0
- package/src/__tests__/doctor-bins.test.ts +43 -0
- package/src/__tests__/doctor.test.ts +463 -0
- package/src/__tests__/dotenv.test.ts +195 -0
- package/src/__tests__/enabled-not-installed.test.ts +94 -0
- package/src/__tests__/file-locking.test.ts +208 -0
- package/src/__tests__/fixtures/tool-probe/brew-list-versions-tmux.txt +2 -0
- package/src/__tests__/fixtures/tool-probe/brew-outdated-behind-homebrew-spec.txt +29 -0
- package/src/__tests__/fixtures/tool-probe/brew-outdated-tmux-current.txt +7 -0
- package/src/__tests__/fixtures/tool-probe/brew-outdated-unknown-formula.txt +6 -0
- package/src/__tests__/fixtures/tool-probe/go-version-m-tmux-mcp.txt +27 -0
- package/src/__tests__/fixtures/tool-probe/npm-dist-tags-missing-scoped.txt +4 -0
- package/src/__tests__/fixtures/tool-probe/npm-dist-tags-openai-codex.txt +4 -0
- package/src/__tests__/fixtures/tool-probe/pypi-cowsay.txt +3 -0
- package/src/__tests__/fixtures/tool-probe/uv-receipt-browser-use.toml +10 -0
- package/src/__tests__/fixtures/tool-probe/uv-receipt-cowsay-git.toml +8 -0
- package/src/__tests__/fixtures/tool-probe/uv-receipt-cowsay-pinned.toml +8 -0
- package/src/__tests__/fixtures/tool-probe/uv-receipt-graphifyy.toml +7 -0
- package/src/__tests__/fixtures/tool-probe/uv-receipt-mcp.toml +6 -0
- package/src/__tests__/fixtures/tool-probe/uv-receipt-serena-agent.toml +9 -0
- package/src/__tests__/fixtures/tool-probe/uv-tool-list-outdated-pinned.txt +5 -0
- package/src/__tests__/fixtures/tool-probe/uv-tool-list-outdated.txt +11 -0
- package/src/__tests__/fixtures/tool-probe/uv-tool-list.txt +22 -0
- package/src/__tests__/footer-hints.test.ts +40 -0
- package/src/__tests__/format-command.test.ts +78 -0
- package/src/__tests__/git-worktree.test.ts +108 -0
- package/src/__tests__/github-budget.test.ts +206 -0
- package/src/__tests__/gitignore-check.test.ts +71 -0
- package/src/__tests__/gitignore-detector.test.ts +176 -0
- package/src/__tests__/gitignore-fixer.test.ts +317 -0
- package/src/__tests__/gitignore-resolver.test.ts +193 -0
- package/src/__tests__/gitignore-service.test.ts +137 -0
- package/src/__tests__/go-module.test.ts +43 -0
- package/src/__tests__/hook-import-policy.test.ts +90 -0
- package/src/__tests__/hook-process.test.ts +256 -0
- package/src/__tests__/hook-registration.test.ts +224 -0
- package/src/__tests__/install-command.test.ts +81 -0
- package/src/__tests__/install-plan.test.ts +104 -0
- package/src/__tests__/launcher-signal.test.ts +308 -0
- package/src/__tests__/local-marketplace-scan.test.ts +174 -0
- package/src/__tests__/manifest.test.ts +281 -0
- package/src/__tests__/markdown-renderer.test.ts +142 -0
- package/src/__tests__/marketplace-badge.test.ts +140 -0
- package/src/__tests__/marketplace-refresh.test.ts +335 -0
- package/src/__tests__/marketplace-version.test.ts +84 -0
- package/src/__tests__/marketplaces.test.ts +128 -0
- package/src/__tests__/mate-availability.test.ts +156 -0
- package/src/__tests__/mate-catalog.test.ts +295 -0
- package/src/__tests__/mcp-registry.test.ts +158 -0
- package/src/__tests__/model-visuals.test.tsx +2466 -0
- package/src/__tests__/models-adapter.test.ts +332 -0
- package/src/__tests__/models-cli.test.ts +273 -0
- package/src/__tests__/models-core.test.ts +802 -0
- package/src/__tests__/models-manager.test.ts +500 -0
- package/src/__tests__/models-presets-marketplace.test.ts +168 -0
- package/src/__tests__/models-screen-state.test.ts +315 -0
- package/src/__tests__/moved-marketplace.test.ts +86 -0
- package/src/__tests__/open-file.test.ts +59 -0
- package/src/__tests__/owned-marketplaces.test.ts +93 -0
- package/src/__tests__/plugin-checkout.test.ts +66 -0
- package/src/__tests__/plugin-cli-argv.test.ts +109 -0
- package/src/__tests__/plugin-contents.test.ts +371 -0
- package/src/__tests__/plugin-manager-fallback.test.ts +320 -0
- package/src/__tests__/plugin-releases.test.ts +98 -0
- package/src/__tests__/plugin-requires.test.ts +187 -0
- package/src/__tests__/plugin-row-text.test.ts +336 -0
- package/src/__tests__/plugin-setup.test.ts +1016 -0
- package/src/__tests__/profile-adopt.test.ts +177 -0
- package/src/__tests__/profile-command.test.ts +110 -0
- package/src/__tests__/profile-materializer.test.ts +238 -0
- package/src/__tests__/profile-sync.test.ts +154 -0
- package/src/__tests__/registry-version-resolution.test.ts +88 -0
- package/src/__tests__/resolve-executable.test.ts +42 -0
- package/src/__tests__/resolver.test.ts +351 -0
- package/src/__tests__/scope-action.test.ts +134 -0
- package/src/__tests__/scope-squares.test.tsx +164 -0
- package/src/__tests__/selection-scope.test.ts +100 -0
- package/src/__tests__/settings-file.test.ts +179 -0
- package/src/__tests__/shell-script-callers.test.ts +92 -0
- package/src/__tests__/skill-install-files.test.ts +136 -0
- package/src/__tests__/skills-catalog-client.test.ts +48 -0
- package/src/__tests__/style-wrap.test.ts +220 -0
- package/src/__tests__/styles-manager.test.ts +1098 -0
- package/src/__tests__/styles-origins.test.ts +414 -0
- package/src/__tests__/styles-screen-state.test.ts +457 -0
- package/src/__tests__/styles-status-line.test.ts +72 -0
- package/src/__tests__/styles-sync.test.ts +452 -0
- package/src/__tests__/symlink-manager.test.ts +180 -0
- package/src/__tests__/tabbar-layout.test.ts +100 -0
- package/src/__tests__/terminology-filler.test.ts +214 -0
- package/src/__tests__/theme-adaptive-colors.test.ts +354 -0
- package/src/__tests__/theme-env.test.ts +281 -0
- package/src/__tests__/theme-resolve.test.ts +380 -0
- package/src/__tests__/tool-probe.test.ts +1400 -0
- package/src/__tests__/toolchain.test.ts +232 -0
- package/src/__tests__/ui-version-writers.test.ts +88 -0
- package/src/__tests__/update-apply.test.ts +637 -0
- package/src/__tests__/update-plan.test.ts +1373 -0
- package/src/__tests__/uppercase-keybindings.test.ts +101 -0
- package/src/__tests__/useGitignoreModal.test.ts +79 -0
- package/src/__tests__/version-check-refresh.test.ts +45 -0
- package/src/__tests__/version-snapshot.test.ts +212 -0
- package/src/__tests__/version-unknown-state.test.ts +388 -0
- package/src/__tests__/worktree-registry-resolution.test.ts +107 -0
- package/src/cli/ansi.ts +520 -0
- package/src/cli/bootstrap.ts +134 -0
- package/src/cli/doctor.ts +218 -0
- package/src/cli/hook.ts +129 -0
- package/src/cli/install.ts +382 -0
- package/src/cli/live.ts +374 -0
- package/src/cli/models.ts +297 -0
- package/src/cli/profile.ts +197 -0
- package/src/cli/prompt.ts +32 -0
- package/src/cli/router.ts +207 -0
- package/src/cli/update-view.ts +526 -0
- package/src/cli/update.ts +613 -0
- package/src/cli/upgrade.ts +97 -0
- package/src/data/alias-flags.ts +301 -0
- package/src/data/cli-tools.ts +146 -0
- package/src/data/community-styles.ts +531 -0
- package/src/data/gitignore-defaults.ts +33 -0
- package/src/data/gitignore-reasons.ts +93 -0
- package/src/data/gitignore-templates.ts +25 -0
- package/src/data/marketplaces.ts +278 -0
- package/src/data/mcp-servers.ts +51 -0
- package/src/data/models-presets.ts +329 -0
- package/src/data/predefined-profiles.ts +252 -0
- package/src/data/settings-catalog.ts +714 -0
- package/src/data/skill-repos.ts +91 -0
- package/src/data/styles/asd-ste100.md +38 -0
- package/src/data/styles/calibrated.md +24 -0
- package/src/data/styles/direct.md +23 -0
- package/src/data/styles/evidence-first.md +22 -0
- package/src/data/styles/explanatory.md +23 -0
- package/src/data/styles/index.ts +57 -0
- package/src/data/styles/no-slop.md +32 -0
- package/src/data/styles/plain-language.md +23 -0
- package/src/data/styles/structured.md +30 -0
- package/src/data/styles/terminology.md +28 -0
- package/src/data/styles/terse.md +20 -0
- package/src/main.tsx +110 -0
- package/src/markdown.d.ts +13 -0
- package/src/opentui.d.ts +203 -0
- package/src/services/active-closure.ts +117 -0
- package/src/services/alias-settings.ts +60 -0
- package/src/services/alias-shell-writer.ts +1244 -0
- package/src/services/alias-store.ts +172 -0
- package/src/services/binary-signing.ts +78 -0
- package/src/services/catalog-cache-store.ts +316 -0
- package/src/services/claude-cli.ts +304 -0
- package/src/services/claude-runner.ts +31 -0
- package/src/services/claude-settings.ts +1589 -0
- package/src/services/cli-tool-commands.ts +133 -0
- package/src/services/community-fetcher.ts +90 -0
- package/src/services/community-styles.ts +1194 -0
- package/src/services/content-drift.ts +208 -0
- package/src/services/conventions-manager.ts +945 -0
- package/src/services/doctor-bins.ts +63 -0
- package/src/services/doctor.ts +570 -0
- package/src/services/dotenv.ts +181 -0
- package/src/services/git-worktree.ts +129 -0
- package/src/services/github-budget.ts +274 -0
- package/src/services/gitignore-check.ts +63 -0
- package/src/services/gitignore-detector.ts +167 -0
- package/src/services/gitignore-fixer.ts +280 -0
- package/src/services/gitignore-resolver.ts +208 -0
- package/src/services/gitignore-service.ts +167 -0
- package/src/services/hook-registration.ts +218 -0
- package/src/services/install-plan.ts +107 -0
- package/src/services/local-marketplace.ts +587 -0
- package/src/services/manifest.ts +250 -0
- package/src/services/marketplace-catalog-git.ts +173 -0
- package/src/services/marketplace-catalog.ts +129 -0
- package/src/services/marketplace-fetcher.ts +400 -0
- package/src/services/marketplace-refresh.ts +253 -0
- package/src/services/marketplace-sync.ts +145 -0
- package/src/services/mate-availability.ts +133 -0
- package/src/services/mate-catalog.ts +265 -0
- package/src/services/mcp-registry.ts +171 -0
- package/src/services/models-core.ts +969 -0
- package/src/services/models-manager.ts +606 -0
- package/src/services/plugin-checkout.ts +186 -0
- package/src/services/plugin-manager.ts +878 -0
- package/src/services/plugin-mcp-config.ts +242 -0
- package/src/services/plugin-releases.ts +47 -0
- package/src/services/plugin-requires.ts +227 -0
- package/src/services/plugin-setup.ts +965 -0
- package/src/services/profile-adopt.ts +206 -0
- package/src/services/profile-materializer.ts +133 -0
- package/src/services/profile-sync.ts +158 -0
- package/src/services/profiles.ts +225 -0
- package/src/services/resolver.ts +344 -0
- package/src/services/settings-file.ts +69 -0
- package/src/services/settings-manager.ts +307 -0
- package/src/services/skills-manager.ts +1111 -0
- package/src/services/skillsmp-client.ts +193 -0
- package/src/services/styles-manager.ts +1294 -0
- package/src/services/symlink-manager.ts +189 -0
- package/src/services/terminology-filler.ts +266 -0
- package/src/services/tool-probe.ts +1637 -0
- package/src/services/toolchain.ts +431 -0
- package/src/services/update-engine.ts +691 -0
- package/src/services/update-plan.ts +863 -0
- package/src/services/version-check.ts +127 -0
- package/src/services/version-snapshot.ts +189 -0
- package/src/tui.tsx +112 -0
- package/src/types/bun.d.ts +27 -0
- package/src/types/gitignore.ts +68 -0
- package/src/types/index.ts +447 -0
- package/src/ui/App.tsx +538 -0
- package/src/ui/adapters/catalogNotice.ts +122 -0
- package/src/ui/adapters/cliToolsAdapter.ts +176 -0
- package/src/ui/adapters/modelsAdapter.ts +213 -0
- package/src/ui/adapters/pluginsAdapter.ts +413 -0
- package/src/ui/adapters/settingsAdapter.ts +168 -0
- package/src/ui/adapters/skillsAdapter.ts +229 -0
- package/src/ui/adapters/stylesAdapter.ts +403 -0
- package/src/ui/components/CategoryHeader.tsx +64 -0
- package/src/ui/components/EmptyFilterState.tsx +32 -0
- package/src/ui/components/FlagDetailEditor.tsx +0 -0
- package/src/ui/components/ScopeIndicator.tsx +63 -0
- package/src/ui/components/ScrollableList.tsx +95 -0
- package/src/ui/components/SearchInput.tsx +57 -0
- package/src/ui/components/StyledText.tsx +75 -0
- package/src/ui/components/TabBar.tsx +101 -0
- package/src/ui/components/layout/FooterHints.tsx +78 -0
- package/src/ui/components/layout/Panel.tsx +63 -0
- package/src/ui/components/layout/ProgressBar.tsx +44 -0
- package/src/ui/components/layout/ScopeTabs.tsx +54 -0
- package/src/ui/components/layout/ScreenLayout.tsx +321 -0
- package/src/ui/components/layout/index.ts +9 -0
- package/src/ui/components/modals/ConfirmModal.tsx +62 -0
- package/src/ui/components/modals/InputModal.tsx +75 -0
- package/src/ui/components/modals/LoadingModal.tsx +51 -0
- package/src/ui/components/modals/MessageModal.tsx +66 -0
- package/src/ui/components/modals/ModalContainer.tsx +159 -0
- package/src/ui/components/modals/SelectModal.tsx +90 -0
- package/src/ui/components/modals/index.ts +6 -0
- package/src/ui/components/primitives/ActionHints.tsx +44 -0
- package/src/ui/components/primitives/DetailSection.tsx +23 -0
- package/src/ui/components/primitives/KeyValueLine.tsx +26 -0
- package/src/ui/components/primitives/ListCategoryRow.tsx +45 -0
- package/src/ui/components/primitives/MetaText.tsx +40 -0
- package/src/ui/components/primitives/ScopeDetail.tsx +67 -0
- package/src/ui/components/primitives/ScopeSquares.tsx +58 -0
- package/src/ui/components/primitives/SelectableRow.tsx +30 -0
- package/src/ui/components/primitives/index.ts +9 -0
- package/src/ui/hooks/index.ts +2 -0
- package/src/ui/hooks/useGitignoreModal.ts +95 -0
- package/src/ui/hooks/useKeyboard.ts +24 -0
- package/src/ui/hooks/useKeyboardHandler.ts +63 -0
- package/src/ui/registry.ts +33 -0
- package/src/ui/renderers/cliToolRenderers.tsx +326 -0
- package/src/ui/renderers/gitignoreRenderers.tsx +80 -0
- package/src/ui/renderers/markdownRenderer.tsx +302 -0
- package/src/ui/renderers/mcpRenderers.tsx +149 -0
- package/src/ui/renderers/modelRenderers.tsx +1309 -0
- package/src/ui/renderers/modelVisuals.tsx +1402 -0
- package/src/ui/renderers/pluginRenderers.tsx +1089 -0
- package/src/ui/renderers/pluginRowText.ts +70 -0
- package/src/ui/renderers/pluginStatusText.ts +56 -0
- package/src/ui/renderers/profileRenderers.tsx +406 -0
- package/src/ui/renderers/settingsRenderers.tsx +218 -0
- package/src/ui/renderers/skillRenderers.tsx +479 -0
- package/src/ui/renderers/styleRenderers.tsx +813 -0
- package/src/ui/screens/AliasScreen.tsx +1558 -0
- package/src/ui/screens/CliToolsScreen.tsx +367 -0
- package/src/ui/screens/EnvVarsScreen.tsx +221 -0
- package/src/ui/screens/GitignoreScreen.tsx +562 -0
- package/src/ui/screens/McpRegistryScreen.tsx +366 -0
- package/src/ui/screens/McpScreen.tsx +256 -0
- package/src/ui/screens/ModelsScreen.tsx +542 -0
- package/src/ui/screens/PluginsScreen.tsx +1464 -0
- package/src/ui/screens/ProfilesScreen.tsx +438 -0
- package/src/ui/screens/SkillsScreen.tsx +853 -0
- package/src/ui/screens/StylesScreen.tsx +1064 -0
- package/src/ui/screens/index.ts +11 -0
- package/src/ui/state/AppContext.tsx +233 -0
- package/src/ui/state/DimensionsContext.tsx +154 -0
- package/src/ui/state/reducer.ts +810 -0
- package/src/ui/state/types.ts +503 -0
- package/src/ui/theme-mode.ts +352 -0
- package/src/ui/theme-resolve.ts +147 -0
- package/src/ui/theme.ts +175 -0
- package/src/utils/clipboard.ts +58 -0
- package/src/utils/command-utils.ts +144 -0
- package/src/utils/config-dir.ts +45 -0
- package/src/utils/file-locking.ts +146 -0
- package/src/utils/fuzzy-search.ts +138 -0
- package/src/utils/go-module.ts +36 -0
- package/src/utils/open-file.ts +84 -0
- package/src/utils/run.ts +67 -0
- package/src/utils/string-utils.ts +88 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { SkillSource, StarReliability } from "../types/index.js";
|
|
2
|
+
|
|
3
|
+
export interface RecommendedSkill {
|
|
4
|
+
name: string;
|
|
5
|
+
repo: string;
|
|
6
|
+
skillPath: string;
|
|
7
|
+
description: string;
|
|
8
|
+
category: string;
|
|
9
|
+
stars?: number; // fallback when GitHub API is rate-limited
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ─── Skill Sets (grouped skills from a single repo) ──────────────────────────
|
|
13
|
+
|
|
14
|
+
export interface RecommendedSkillSet {
|
|
15
|
+
name: string;
|
|
16
|
+
repo: string;
|
|
17
|
+
description: string;
|
|
18
|
+
icon: string;
|
|
19
|
+
stars?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ─── Star reliability classification ────────────────────────────────────────
|
|
23
|
+
// Stars from these repos don't reflect individual skill quality.
|
|
24
|
+
|
|
25
|
+
/** Mega-repos: huge projects that happen to include skills. Stars are about the project. */
|
|
26
|
+
const MEGA_REPOS = new Set([
|
|
27
|
+
"microsoft/vscode",
|
|
28
|
+
"Significant-Gravitas/AutoGPT",
|
|
29
|
+
"n8n-io/n8n",
|
|
30
|
+
"anomalyco/opencode",
|
|
31
|
+
"shadcn-ui/ui",
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
/** Skill-dump repos: large collections where stars reflect quantity, not quality. */
|
|
35
|
+
// Renamed repos are listed under BOTH names on purpose. The curated catalog
|
|
36
|
+
// serves the current name while older cached copies and this file's fallback
|
|
37
|
+
// list still carry the old one; dropping either silently reclassifies the repo
|
|
38
|
+
// as "dedicated" and its stars start reading as a quality signal again.
|
|
39
|
+
const SKILL_DUMP_REPOS = new Set([
|
|
40
|
+
"affaan-m/everything-claude-code",
|
|
41
|
+
"openclaw/openclaw",
|
|
42
|
+
"jh941213/my-claude-code-asset",
|
|
43
|
+
"jh941213/my-cc-harness", // renamed from my-claude-code-asset
|
|
44
|
+
"inferen-sh/skills",
|
|
45
|
+
"inference-sh/skills", // renamed from inferen-sh
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Classify how reliable a repo's star count is as a quality signal for its skills.
|
|
50
|
+
* - "dedicated": Stars reflect skill/repo quality (e.g. huggingface/skills, vercel-labs/agent-skills)
|
|
51
|
+
* - "mega-repo": Stars are about a larger project, not the skills (e.g. microsoft/vscode)
|
|
52
|
+
* - "skill-dump": Large skill collection — stars reflect popularity/quantity, not individual quality
|
|
53
|
+
*/
|
|
54
|
+
export function classifyStarReliability(
|
|
55
|
+
repo: string,
|
|
56
|
+
stars?: number,
|
|
57
|
+
): StarReliability {
|
|
58
|
+
if (MEGA_REPOS.has(repo)) return "mega-repo";
|
|
59
|
+
if (SKILL_DUMP_REPOS.has(repo)) return "skill-dump";
|
|
60
|
+
// Heuristic: unknown repos with >50K stars are likely mega-repos
|
|
61
|
+
if (stars && stars > 50000) return "mega-repo";
|
|
62
|
+
return "dedicated";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const STAR_RELIABILITY_INFO: Record<
|
|
66
|
+
StarReliability,
|
|
67
|
+
{ label: string; description: string }
|
|
68
|
+
> = {
|
|
69
|
+
dedicated: {
|
|
70
|
+
label: "Skill repo",
|
|
71
|
+
description: "Stars reflect this skill repository's quality",
|
|
72
|
+
},
|
|
73
|
+
"mega-repo": {
|
|
74
|
+
label: "Project repo",
|
|
75
|
+
description:
|
|
76
|
+
"Stars are for the parent project, not the skills. Skill quality may vary.",
|
|
77
|
+
},
|
|
78
|
+
"skill-dump": {
|
|
79
|
+
label: "Skill collection",
|
|
80
|
+
description:
|
|
81
|
+
"Large skill collection — stars reflect repo popularity, not individual skill quality.",
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const DEFAULT_SKILL_REPOS: SkillSource[] = [
|
|
86
|
+
{
|
|
87
|
+
label: "Vercel Agent Skills",
|
|
88
|
+
repo: "vercel-labs/agent-skills",
|
|
89
|
+
skillsPath: "skills",
|
|
90
|
+
},
|
|
91
|
+
];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: asd-ste100
|
|
3
|
+
title: ASD-STE100 Simplified Technical English
|
|
4
|
+
axis: modifier
|
|
5
|
+
summary: Full-grammar sentences that survive one read. Sentence caps, three modals, one word one meaning.
|
|
6
|
+
conflicts:
|
|
7
|
+
credits: ASD-STE100; found via AminBlg/SimpleEnglish (MIT)
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
### ASD-STE100 Simplified Technical English
|
|
11
|
+
|
|
12
|
+
The standard, cut to the rules that survive outside an aerospace manual. The
|
|
13
|
+
reader is tired, often reads in a second language, and reads each sentence
|
|
14
|
+
once. Write so one read is enough.
|
|
15
|
+
|
|
16
|
+
- Classify before you write. An instruction gets imperative mood, one action
|
|
17
|
+
per sentence, and 20 words or fewer. A description gets simple tenses, one
|
|
18
|
+
topic per paragraph, and 25 words or fewer per sentence. Never mix the two
|
|
19
|
+
in one passage.
|
|
20
|
+
- Use the active voice, simple tenses, and a named actor. No present perfect
|
|
21
|
+
("the build has completed" → "the build completed"). No "-ing" chains.
|
|
22
|
+
Start a new sentence instead.
|
|
23
|
+
- Use three modals: must, can, will. "Should" is a bug report against the
|
|
24
|
+
sentence. If the action is required, write "must". If it is optional,
|
|
25
|
+
delete the word. The same rule covers would, may, might, and could.
|
|
26
|
+
- Use one word for one meaning across the whole answer. Pick one of check,
|
|
27
|
+
verify, and confirm, then keep it. A word that changes mid-answer reads as
|
|
28
|
+
a new concept.
|
|
29
|
+
- Put the condition before the command, with a comma: "If the test fails,
|
|
30
|
+
read the log." The reader must know it is conditional before they act.
|
|
31
|
+
- Keep the grammar words: articles, "that", and full forms over contractions.
|
|
32
|
+
Telegraphic compression saves characters and buys ambiguity.
|
|
33
|
+
- Break noun chains at three words: "the marketplace cache refresh interval"
|
|
34
|
+
→ "the refresh interval for the marketplace cache".
|
|
35
|
+
- If a list has more than two steps or items, make it vertical, one per line.
|
|
36
|
+
- Delete any word whose removal changes no fact: simply, robust, seamless,
|
|
37
|
+
"in order to". Replace the ornate word with the plain one: utilize → use,
|
|
38
|
+
prior to → before, in the event that → if.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: calibrated
|
|
3
|
+
axis: modifier
|
|
4
|
+
summary: Confidence matches evidence. Say "I don't know" plainly; no false certainty either way.
|
|
5
|
+
conflicts:
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Calibrated confidence
|
|
9
|
+
|
|
10
|
+
- State confidence that matches the evidence. Verified by running it: say so
|
|
11
|
+
plainly. Read but not run: say "based on reading `file.ts:88`". Inferred
|
|
12
|
+
from a pattern: say it is an inference.
|
|
13
|
+
- "I don't know" is a complete answer. Follow it with what would settle the
|
|
14
|
+
question, not with a guess dressed as an answer.
|
|
15
|
+
- Never hedge a fact you verified. Hedging everything is as miscalibrated as
|
|
16
|
+
hedging nothing, and it makes the real uncertainty invisible.
|
|
17
|
+
- Name the assumption when you proceed under one, at the point it starts to
|
|
18
|
+
matter, not in a footnote at the end.
|
|
19
|
+
- When another agent, tool, or search result contradicts what you found, do
|
|
20
|
+
not fold immediately. Say what each side rests on and which evidence is
|
|
21
|
+
stronger.
|
|
22
|
+
- Correct an earlier statement only when the error changes what the reader
|
|
23
|
+
should do. Fix it in one sentence and continue — no apology, no tally of
|
|
24
|
+
past mistakes, no re-audit of how it was phrased.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: direct
|
|
3
|
+
axis: verbosity
|
|
4
|
+
summary: Answer first, no preamble or postamble. The default for people who read fast.
|
|
5
|
+
conflicts: explanatory, terse
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Direct
|
|
9
|
+
|
|
10
|
+
- Lead with the answer. The first sentence resolves the question; everything
|
|
11
|
+
after it is support. Never open with a restatement of what was asked.
|
|
12
|
+
- No preamble ("Great question", "Let me look into that", "I'll start by") and
|
|
13
|
+
no postamble ("Let me know if you'd like", "Feel free to ask", "I hope this
|
|
14
|
+
helps"). Stop when the answer is complete.
|
|
15
|
+
- Recommend, do not survey. When there are three viable approaches, name the
|
|
16
|
+
one to take and give the reason in a clause. List the alternatives only if
|
|
17
|
+
the choice is genuinely close, and say why it is close.
|
|
18
|
+
- Report the outcome, not the journey. What changed, where, and whether it
|
|
19
|
+
works. The steps taken are only interesting when one of them failed.
|
|
20
|
+
- One statement of a fact is enough. Do not restate a conclusion in a summary
|
|
21
|
+
section immediately below the conclusion.
|
|
22
|
+
- Bad news goes first and plainly. "The tests fail" opens the message; it does
|
|
23
|
+
not appear in the last paragraph after four paragraphs of progress.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: evidence-first
|
|
3
|
+
axis: modifier
|
|
4
|
+
summary: Every claim about the system carries the command that proved it and its real output.
|
|
5
|
+
conflicts:
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Evidence first
|
|
9
|
+
|
|
10
|
+
- A claim about how the system behaves cites the command that produced it and
|
|
11
|
+
the real output. Paraphrased output is not output.
|
|
12
|
+
- "Done", "fixed", and "working" are claims. Each requires a fresh run pasted
|
|
13
|
+
in full, not a run from before the last edit.
|
|
14
|
+
- A check that cannot fail is not evidence. If a test passes, show that it
|
|
15
|
+
fails without the change — otherwise the passing run proves nothing.
|
|
16
|
+
- Report failures with the same prominence as successes. If two of nine tests
|
|
17
|
+
fail, say so in the first line and paste both failures.
|
|
18
|
+
- Distinguish what was observed from what was inferred. "The function returns
|
|
19
|
+
null here" and "this probably means the cache is cold" are different kinds
|
|
20
|
+
of statement and must be labelled differently.
|
|
21
|
+
- Never report a step as complete if it was skipped, partially applied, or
|
|
22
|
+
could not be verified. Say which, and say why.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explanatory
|
|
3
|
+
axis: verbosity
|
|
4
|
+
summary: Teach the reasoning alongside the work — for codebases people are still learning.
|
|
5
|
+
conflicts: direct, terse
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Explanatory
|
|
9
|
+
|
|
10
|
+
- Give the answer first, then the reasoning. Explanation earns its place by
|
|
11
|
+
following a conclusion, never by delaying one.
|
|
12
|
+
- Explain the *specific* choice, not the general concept. "This uses a map
|
|
13
|
+
because the caller looks up by id in a loop" teaches something; "maps offer
|
|
14
|
+
O(1) lookup" does not.
|
|
15
|
+
- Name the alternative that was rejected and why. A decision without its
|
|
16
|
+
discarded options reads as the only possibility, which is rarely true.
|
|
17
|
+
- When touching an unfamiliar part of the system, state the mechanism you
|
|
18
|
+
relied on and how you confirmed it. That is the difference between a claim
|
|
19
|
+
the reader can check and one they must trust.
|
|
20
|
+
- Explanation is capped by usefulness, not by length. If a paragraph would not
|
|
21
|
+
change what the reader does next, it does not belong.
|
|
22
|
+
- Never explain the same mechanism twice in one session. Reference the earlier
|
|
23
|
+
explanation instead.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The communication style presets, embedded in the binary.
|
|
3
|
+
*
|
|
4
|
+
* These files used to ship in `style@magus` and magus read them off disk,
|
|
5
|
+
* which meant the Styles tab was empty for anyone who had not installed that
|
|
6
|
+
* plugin. The plugin was retired at Marketplace 10.0.0 and the presets moved
|
|
7
|
+
* here, so they are always present and always the version this binary was
|
|
8
|
+
* built against.
|
|
9
|
+
*
|
|
10
|
+
* ## Why `.md` files rather than TypeScript string constants
|
|
11
|
+
*
|
|
12
|
+
* The frontmatter format (`name`, `title`, `axis`, `summary`, `conflicts`,
|
|
13
|
+
* `template`) is the contract `styles-manager.ts` parses, and a preset body is
|
|
14
|
+
* long instructional text full of backticks and braces. Kept as markdown it
|
|
15
|
+
* stays diffable and escape-free; `with { type: "text" }` inlines it at build
|
|
16
|
+
* time and `bun build --compile` carries it into the binary (verified against
|
|
17
|
+
* bun 1.3.10).
|
|
18
|
+
*
|
|
19
|
+
* ## Adding a preset
|
|
20
|
+
*
|
|
21
|
+
* Drop the `.md` file in this directory and add both lines below. The list is
|
|
22
|
+
* written out rather than globbed because a glob cannot be resolved at compile
|
|
23
|
+
* time — a missing entry means the preset silently does not ship, which is
|
|
24
|
+
* what `styles-manager.test.ts` counts the directory to catch.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import asdSte100 from "./asd-ste100.md" with { type: "text" };
|
|
28
|
+
import calibrated from "./calibrated.md" with { type: "text" };
|
|
29
|
+
import direct from "./direct.md" with { type: "text" };
|
|
30
|
+
import evidenceFirst from "./evidence-first.md" with { type: "text" };
|
|
31
|
+
import explanatory from "./explanatory.md" with { type: "text" };
|
|
32
|
+
import noSlop from "./no-slop.md" with { type: "text" };
|
|
33
|
+
import plainLanguage from "./plain-language.md" with { type: "text" };
|
|
34
|
+
import structured from "./structured.md" with { type: "text" };
|
|
35
|
+
import terminology from "./terminology.md" with { type: "text" };
|
|
36
|
+
import terse from "./terse.md" with { type: "text" };
|
|
37
|
+
|
|
38
|
+
/** One preset's file name and raw contents, frontmatter included. */
|
|
39
|
+
export interface EmbeddedPreset {
|
|
40
|
+
/** File name as it appears in this directory, e.g. `direct.md`. */
|
|
41
|
+
file: string;
|
|
42
|
+
/** Raw file text — frontmatter and body, exactly as authored. */
|
|
43
|
+
text: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const EMBEDDED_PRESETS: EmbeddedPreset[] = [
|
|
47
|
+
{ file: "asd-ste100.md", text: asdSte100 },
|
|
48
|
+
{ file: "calibrated.md", text: calibrated },
|
|
49
|
+
{ file: "direct.md", text: direct },
|
|
50
|
+
{ file: "evidence-first.md", text: evidenceFirst },
|
|
51
|
+
{ file: "explanatory.md", text: explanatory },
|
|
52
|
+
{ file: "no-slop.md", text: noSlop },
|
|
53
|
+
{ file: "plain-language.md", text: plainLanguage },
|
|
54
|
+
{ file: "structured.md", text: structured },
|
|
55
|
+
{ file: "terminology.md", text: terminology },
|
|
56
|
+
{ file: "terse.md", text: terse },
|
|
57
|
+
];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-slop
|
|
3
|
+
axis: modifier
|
|
4
|
+
summary: Banned vocabulary and punctuation tics that mark text as machine-written.
|
|
5
|
+
conflicts:
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### No slop
|
|
9
|
+
|
|
10
|
+
Banned words and phrases. These are not stylistic preferences — they are the
|
|
11
|
+
tells that make text read as generated, and every one of them has a plainer
|
|
12
|
+
replacement:
|
|
13
|
+
|
|
14
|
+
- **Inflation:** delve, crucial, pivotal, robust, comprehensive, seamless,
|
|
15
|
+
nuanced, multifaceted, intricate, vibrant, landscape, tapestry, realm,
|
|
16
|
+
underscore, foster, showcase, leverage (as a verb), utilize.
|
|
17
|
+
- **Connectives:** furthermore, moreover, additionally, notably, importantly.
|
|
18
|
+
Start the next sentence instead.
|
|
19
|
+
- **Hedged enthusiasm:** "it's worth noting that", "it's important to
|
|
20
|
+
remember", "as we can see", "at the end of the day".
|
|
21
|
+
- **Empty openers:** "In today's fast-paced world", "When it comes to",
|
|
22
|
+
"Whether you're a beginner or an expert".
|
|
23
|
+
- **The not-X-but-Y frame** as a reflex: "It's not just a database, it's a
|
|
24
|
+
platform". Say what it is.
|
|
25
|
+
|
|
26
|
+
Punctuation and shape:
|
|
27
|
+
|
|
28
|
+
- No em dashes. Use a comma, a colon, or a full stop.
|
|
29
|
+
- No rule-of-three lists that pad a two-item point to three.
|
|
30
|
+
- No bold on whole sentences. Bold is for the one word the eye should land on.
|
|
31
|
+
- No emoji in code, commit messages, or technical prose unless the project
|
|
32
|
+
already uses them.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plain-language
|
|
3
|
+
axis: modifier
|
|
4
|
+
summary: Gloss jargon on first use, short sentences, active voice, concrete nouns.
|
|
5
|
+
conflicts: terse
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Plain language
|
|
9
|
+
|
|
10
|
+
- Gloss a term of art the first time it appears, in one clause: "idempotent
|
|
11
|
+
(running it twice does the same thing as once)". Once per conversation, not
|
|
12
|
+
once per message.
|
|
13
|
+
- Prefer the concrete noun to the abstraction. "The login page" beats "the
|
|
14
|
+
authentication surface"; "the file will not open" beats "a resource access
|
|
15
|
+
issue".
|
|
16
|
+
- Active voice with a named actor. "The migration drops the column", not "the
|
|
17
|
+
column is dropped".
|
|
18
|
+
- One idea per sentence. If a sentence needs a semicolon to hold together, it
|
|
19
|
+
is two sentences.
|
|
20
|
+
- Close with what it means for the reader: what they will see, wait for, lose,
|
|
21
|
+
or be able to do. A technical fact with no consequence attached is trivia.
|
|
22
|
+
- Expand an acronym on first use unless it is more familiar than its
|
|
23
|
+
expansion — write out "cross-site request forgery", but leave "URL" alone.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: structured
|
|
3
|
+
axis: modifier
|
|
4
|
+
summary: When to use a table, a list, a heading, or a paragraph — and when not to.
|
|
5
|
+
conflicts:
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Structure
|
|
9
|
+
|
|
10
|
+
Match the shape to the content. The wrong container is harder to read than
|
|
11
|
+
plain prose:
|
|
12
|
+
|
|
13
|
+
| Content | Shape |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Two or more things compared on the same dimensions | table |
|
|
16
|
+
| Steps in order, where order matters | numbered list |
|
|
17
|
+
| Items with no order and no comparison | bullets |
|
|
18
|
+
| One thing explained | paragraph |
|
|
19
|
+
| Reasoning that connects claims | paragraph, not bullets |
|
|
20
|
+
|
|
21
|
+
- Never bullet a single item. Never build a table with one row or one column.
|
|
22
|
+
- A heading is a promise about what is below it. Do not use headings to break
|
|
23
|
+
up three sentences.
|
|
24
|
+
- Code identifiers, paths, commands, and literal values go in backticks —
|
|
25
|
+
every time, including in tables and headings.
|
|
26
|
+
- Reference code as `path/to/file.ts:42`. The line number makes it clickable.
|
|
27
|
+
- Prose carries reasoning; bullets fragment it. If the points depend on each
|
|
28
|
+
other, write sentences.
|
|
29
|
+
- Length is set by the content. Do not pad a one-line answer into a section,
|
|
30
|
+
and do not compress a real trade-off into a bullet.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terminology
|
|
3
|
+
axis: modifier
|
|
4
|
+
summary: Project vocabulary — one name per concept, filled in from the codebase during apply.
|
|
5
|
+
conflicts:
|
|
6
|
+
template: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### Terminology
|
|
10
|
+
|
|
11
|
+
One concept, one name, everywhere: code, comments, commit messages, docs, and
|
|
12
|
+
conversation. A concept with two names reads as two concepts.
|
|
13
|
+
|
|
14
|
+
| Use | Not | Because |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| <!-- filled during apply --> | | |
|
|
17
|
+
|
|
18
|
+
Rules that hold regardless of the table above:
|
|
19
|
+
|
|
20
|
+
- Use the domain's word, not the implementation's. If the business calls it a
|
|
21
|
+
"booking", the code and the conversation say booking, even where the table
|
|
22
|
+
is named `reservations`.
|
|
23
|
+
- Do not invent a synonym for a term the codebase already uses. Grep before
|
|
24
|
+
naming anything new.
|
|
25
|
+
- When the code and the domain disagree on a name, say which you are using and
|
|
26
|
+
which the reader will see in the file.
|
|
27
|
+
- Keep abbreviations out of names people say out loud. `usr`, `mgr`, and `cfg`
|
|
28
|
+
save four characters and cost a re-read every time.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terse
|
|
3
|
+
axis: verbosity
|
|
4
|
+
summary: Minimum viable words. No glosses, no framing, no encouragement.
|
|
5
|
+
conflicts: direct, explanatory
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Terse
|
|
9
|
+
|
|
10
|
+
- Answer in the fewest words that stay correct. One line where one line works.
|
|
11
|
+
- No framing sentences, no summaries of what was just said, no offers of
|
|
12
|
+
further help.
|
|
13
|
+
- Prefer a fragment to a sentence, a table to prose, a file path to a
|
|
14
|
+
description of where something lives.
|
|
15
|
+
- Do not explain unless asked. Do not justify a choice unless it is
|
|
16
|
+
surprising.
|
|
17
|
+
- Omit adjectives that carry no information: "simple", "just", "quick",
|
|
18
|
+
"straightforward", "basically".
|
|
19
|
+
- Terse is not curt. Answer what was asked completely — brevity comes from
|
|
20
|
+
cutting padding, never from cutting the answer short.
|
package/src/main.tsx
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
// Static import so `bun build --compile` embeds package.json into the binary;
|
|
4
|
+
// a dynamic require("../package.json") is not resolvable inside the bunfs root.
|
|
5
|
+
import pkg from "../package.json";
|
|
6
|
+
import { loadProjectDotenv } from "./services/dotenv.js";
|
|
7
|
+
|
|
8
|
+
export const VERSION = (pkg as { version: string }).version;
|
|
9
|
+
|
|
10
|
+
// Note: OpenTUI renderer handles alternate screen buffer automatically
|
|
11
|
+
// No need for manual ANSI escape codes
|
|
12
|
+
//
|
|
13
|
+
// NOTHING in this file may statically import @opentui/* or ./ui/*. `magus
|
|
14
|
+
// hook …` runs on every matching Claude Code tool call, and a static import
|
|
15
|
+
// would load the whole TUI module graph before the hook could answer. The TUI
|
|
16
|
+
// (./tui.js), the router (./cli/router.js, which reaches @opentui through
|
|
17
|
+
// cli/update.ts → ui/theme.ts) and the hook itself are all imported on demand,
|
|
18
|
+
// after the branch that decides which one is needed.
|
|
19
|
+
// Pinned by __tests__/hook-import-policy.test.ts.
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `hook` as the first non-theme token → the argv the hook command should see.
|
|
23
|
+
* Anything else → null.
|
|
24
|
+
*
|
|
25
|
+
* A leading `--theme light|dark` (or `--theme=…`) pair is skipped so this
|
|
26
|
+
* matches the router's own dispatch, which drops the theme tokens before
|
|
27
|
+
* looking at the command. Deliberately NOT `parseThemeFlag` from the router:
|
|
28
|
+
* importing that module is the cost this branch exists to avoid, and a hook
|
|
29
|
+
* has no use for a validated theme.
|
|
30
|
+
*/
|
|
31
|
+
function hookArgv(argv: string[]): string[] | null {
|
|
32
|
+
let i = 0;
|
|
33
|
+
while (i < argv.length) {
|
|
34
|
+
const token = argv[i] as string;
|
|
35
|
+
if (token === "--theme") {
|
|
36
|
+
i += 2;
|
|
37
|
+
} else if (token.startsWith("--theme=")) {
|
|
38
|
+
i += 1;
|
|
39
|
+
} else {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return argv[i] === "hook" ? argv.slice(i + 1) : null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function main(): Promise<void> {
|
|
47
|
+
// FIRST, before anything can touch process.env: the theme is read from the
|
|
48
|
+
// environment magus was started with, never from a project's .env. The
|
|
49
|
+
// dotenv load below merges into process.env, so the only thing separating
|
|
50
|
+
// the two is that this line runs before it (pinned by theme-env.test.ts).
|
|
51
|
+
const { snapshotThemeEnv } = await import("./ui/theme-resolve.js");
|
|
52
|
+
const themeEnv = snapshotThemeEnv();
|
|
53
|
+
const args = process.argv.slice(2);
|
|
54
|
+
|
|
55
|
+
// Hooks answer here and go no further. This runs BEFORE loadProjectDotenv()
|
|
56
|
+
// on purpose: a hook must never open a project's .env, because that file is
|
|
57
|
+
// often a symlink to a 1Password FIFO and reading one BLOCKS until a human
|
|
58
|
+
// approves it — on every tool call. The hook needs no .env, so it never
|
|
59
|
+
// touches one.
|
|
60
|
+
const hookRest = hookArgv(args);
|
|
61
|
+
if (hookRest !== null) {
|
|
62
|
+
const { runHookCommand } = await import("./cli/hook.js");
|
|
63
|
+
process.exit(await runHookCommand(hookRest));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Load the project's .env ourselves. Bun's standalone autoload is compiled OFF
|
|
67
|
+
// (scripts/build-binaries.ts) because it killed magus outright wherever
|
|
68
|
+
// .env was a symlink to a FIFO — the shape 1Password uses — exiting 1 with no
|
|
69
|
+
// output at all. services/dotenv.ts does the same job as an ordinary guarded
|
|
70
|
+
// read: regular files only, and every failure reported rather than fatal.
|
|
71
|
+
try {
|
|
72
|
+
for (const warning of loadProjectDotenv().warnings) {
|
|
73
|
+
console.warn(`magus: ${warning}`);
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
// Belt and braces. loadProjectDotenv is total, but no future edit to it may
|
|
77
|
+
// ever be allowed to stop magus from starting.
|
|
78
|
+
console.warn(
|
|
79
|
+
`magus: .env could not be loaded: ${error instanceof Error ? error.message : String(error)}`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Dispatch non-interactive subcommands (claude, update, install, …) and
|
|
84
|
+
// top-level flags (--version/--help). A bare invocation falls through to
|
|
85
|
+
// the interactive TUI below.
|
|
86
|
+
const { route } = await import("./cli/router.js");
|
|
87
|
+
const outcome = await route(args, VERSION);
|
|
88
|
+
if (outcome.handled) {
|
|
89
|
+
process.exit(outcome.exitCode ?? 0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Both streams must be TTYs for the OSC probe: `magus < file` has a tty
|
|
93
|
+
// stdout but the reply arrives on stdin, so the probe would wait for nothing.
|
|
94
|
+
const isInteractive =
|
|
95
|
+
process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
96
|
+
|
|
97
|
+
// Last possible moment: this is the import that pulls in @opentui and the
|
|
98
|
+
// whole ui/ tree. Everything above runs without them.
|
|
99
|
+
const { startTui } = await import("./tui.js");
|
|
100
|
+
await startTui({
|
|
101
|
+
theme: outcome.theme,
|
|
102
|
+
env: themeEnv,
|
|
103
|
+
isInteractive,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
main().catch((error) => {
|
|
108
|
+
console.error("Error starting magus:", error);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown imported as text.
|
|
3
|
+
*
|
|
4
|
+
* `import body from "./direct.md" with { type: "text" }` is a Bun bundler
|
|
5
|
+
* feature — the loader inlines the file as a string literal at build time, so
|
|
6
|
+
* it survives `bun build --compile`. TypeScript has no idea, hence this
|
|
7
|
+
* declaration. Without it every preset import in `data/styles/` is an
|
|
8
|
+
* implicit-any error under `strict`.
|
|
9
|
+
*/
|
|
10
|
+
declare module "*.md" {
|
|
11
|
+
const contents: string;
|
|
12
|
+
export default contents;
|
|
13
|
+
}
|