blacksmith-organization-system 0.4.2 → 1.0.0-dev.3
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/.claude-plugin/marketplace.json +17 -0
- package/.claude-plugin/mcp.json +8 -0
- package/.claude-plugin/plugin.json +16 -0
- package/AGENTS.md +114 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +1 -1
- package/README.md +74 -57
- package/bin/bos +3 -0
- package/hooks/hooks.json +40 -0
- package/package.json +82 -22
- package/resources/house/HOUSE.md +22 -0
- package/resources/house/bloodlines.json +35 -0
- package/resources/house/children/deepseeks-of-anubis.json +4 -0
- package/resources/house/children/eon.json +7 -0
- package/resources/house/children/hermetic-officer.json +1 -0
- package/resources/house/children/ifrit.json +1 -0
- package/resources/house/children/license-keepers.json +4 -0
- package/resources/house/children/sebas.json +10 -0
- package/resources/house/children/shakespeare.json +10 -0
- package/resources/house/orders/ravensarmy.json +6 -0
- package/resources/house/orders/seiaic-ucdi.json +5 -0
- package/resources/ravens/skryba.md +19 -0
- package/resources/workshop-root/AGENTS.md +92 -0
- package/resources/workshop-root/CLAUDE.md +1 -0
- package/resources/workshop.default.json +6 -0
- package/skills/bos-archive/SKILL.md +28 -0
- package/skills/bos-craftbook/SKILL.md +32 -0
- package/skills/bos-craftset/SKILL.md +36 -0
- package/skills/bos-devarmory/SKILL.md +34 -0
- package/skills/bos-exhibit/SKILL.md +28 -0
- package/skills/bos-forge/SKILL.md +28 -0
- package/skills/bos-house/SKILL.md +52 -0
- package/skills/bos-project/SKILL.md +27 -0
- package/skills/bos-sarcophag/SKILL.md +26 -0
- package/skills/bos-scope/SKILL.md +33 -0
- package/skills/bos-sheme/SKILL.md +38 -0
- package/skills/bos-throwbox/SKILL.md +27 -0
- package/skills/bos-workshop/SKILL.md +65 -0
- package/{config/README.md → skills/bos-workshop/assets/.gitkeep} +0 -0
- package/skills/bos-workshop/references/bos-codebase.md +116 -0
- package/skills/bos-workshop/references/bos-concept.md +121 -0
- package/skills/bos-workshop/scripts/find-workshop.sh +30 -0
- package/src/agent-hook.mjs +28 -0
- package/src/bridge/_index.mjs +24 -0
- package/src/bridge/bos-instances-link/_index.mjs +18 -0
- package/src/bridge/docker-host/_index.mjs +43 -0
- package/src/bridge/docker-host/container.mjs +32 -0
- package/src/bridge/docker-host/image.mjs +23 -0
- package/src/bridge/docker-host/volume.mjs +12 -0
- package/src/bridge/docker-publish/_index.mjs +24 -0
- package/src/bridge/git-client/_index.mjs +121 -0
- package/src/bridge/git-client/author.mjs +26 -0
- package/src/bridge/gitea-api/_index.mjs +62 -0
- package/src/bridge/github-api/_index.mjs +45 -0
- package/src/bridge/npm-publish/_index.mjs +19 -0
- package/src/bridge/ollama-link/_index.mjs +93 -0
- package/src/bridge/ollama-link/ravens.mjs +29 -0
- package/src/bridge/ssh-link/_index.mjs +33 -0
- package/src/bridge/subprocess-runner/_index.mjs +33 -0
- package/src/cli.mjs +29 -0
- package/src/commands/_index.mjs +51 -0
- package/src/commands/bootstrap/exec.mjs +7 -0
- package/src/commands/bootstrap/help.md +5 -0
- package/src/commands/bootstrap/index.json +7 -0
- package/src/commands/close/exec.mjs +4 -0
- package/src/commands/close/help.md +5 -0
- package/src/commands/close/index.json +7 -0
- package/src/commands/describe/exec.mjs +11 -0
- package/src/commands/describe/help.md +5 -0
- package/src/commands/describe/index.json +7 -0
- package/src/commands/help/exec.mjs +6 -0
- package/src/commands/help/help.md +3 -0
- package/src/commands/help/index.json +6 -0
- package/src/commands/hook/exec.mjs +3 -0
- package/src/commands/hook/help.md +4 -0
- package/src/commands/hook/index.json +7 -0
- package/src/commands/hooks/exec.mjs +5 -0
- package/src/commands/hooks/help.md +4 -0
- package/src/commands/hooks/index.json +7 -0
- package/src/commands/house/exec.mjs +8 -0
- package/src/commands/house/help.md +8 -0
- package/src/commands/house/index.json +7 -0
- package/src/commands/locate/exec.mjs +2 -0
- package/src/commands/locate/help.md +6 -0
- package/src/commands/locate/index.json +6 -0
- package/src/commands/mode/exec.mjs +17 -0
- package/src/commands/mode/help.md +14 -0
- package/src/commands/mode/index.json +8 -0
- package/src/commands/mode/repl.mjs +18 -0
- package/src/commands/open/exec.mjs +5 -0
- package/src/commands/open/help.md +4 -0
- package/src/commands/open/index.json +7 -0
- package/src/commands/promote/exec.mjs +5 -0
- package/src/commands/promote/help.md +6 -0
- package/src/commands/promote/index.json +7 -0
- package/src/commands/repl/exec.mjs +3 -0
- package/src/commands/repl/help.md +4 -0
- package/src/commands/repl/index.json +6 -0
- package/src/commands/seal/exec.mjs +8 -0
- package/src/commands/seal/help.md +4 -0
- package/src/commands/seal/index.json +7 -0
- package/src/commands/sink/exec.mjs +2 -0
- package/src/commands/sink/help.md +6 -0
- package/src/commands/sink/index.json +7 -0
- package/src/commands/skills/exec.mjs +5 -0
- package/src/commands/skills/help.md +5 -0
- package/src/commands/skills/index.json +7 -0
- package/src/commands/status/exec.mjs +2 -0
- package/src/commands/status/help.md +6 -0
- package/src/commands/status/index.json +7 -0
- package/src/commands/status/repl.mjs +14 -0
- package/src/commands/verify/exec.mjs +9 -0
- package/src/commands/verify/help.md +4 -0
- package/src/commands/verify/index.json +7 -0
- package/src/controllers/_index.mjs +5 -0
- package/src/controllers/skills-controll.mjs +13 -0
- package/src/controllers/workshop-controll.mjs +48 -0
- package/src/core/basic-bridge.mjs +29 -0
- package/src/core/basic-controll.mjs +26 -0
- package/src/core/basic-element.mjs +149 -0
- package/src/core/basic-model.mjs +7 -0
- package/src/core/basic-procedure.mjs +37 -0
- package/src/core/basic-submodule.mjs +21 -0
- package/src/core/basic-view.mjs +21 -0
- package/src/core/self.mjs +10 -0
- package/src/index.mjs +24 -0
- package/src/main.ts +82 -0
- package/src/mcp.mjs +8 -0
- package/src/models/_index.mjs +43 -0
- package/src/models/archive/class.mjs +9 -0
- package/src/models/craftbook/class.mjs +11 -0
- package/src/models/craftbook/hang.scrapnotes.mjs +10 -0
- package/src/models/craftset/class.mjs +14 -0
- package/src/models/devarmory/class.mjs +10 -0
- package/src/models/exhibit/class.mjs +8 -0
- package/src/models/forge/class.mjs +19 -0
- package/src/models/house/bloodlines.mjs +27 -0
- package/src/models/house/class.mjs +53 -0
- package/src/models/house/groups.mjs +38 -0
- package/src/models/project/anatomy.mjs +11 -0
- package/src/models/project/class.mjs +20 -0
- package/src/models/sarcophag/class.mjs +8 -0
- package/src/models/scope/class.mjs +19 -0
- package/src/models/sheme/class.mjs +8 -0
- package/src/models/throwbox/class.mjs +9 -0
- package/src/models/workshop/class.mjs +30 -0
- package/src/models/workshop/hang.data.mjs +10 -0
- package/src/models/workshop/hang.nests.mjs +14 -0
- package/src/models/workshop/hang.setup.mjs +10 -0
- package/src/models/workshop/hang.storylines.logs.mjs +10 -0
- package/src/models/workshop/hang.storylines.manifests.mjs +10 -0
- package/src/models/workshop/hang.storylines.mjs +39 -0
- package/src/models/workshop/hang.storylines.ttystories.mjs +10 -0
- package/src/models/workshop/hang.system.mjs +25 -0
- package/src/models/workshop/host-roles.mjs +9 -0
- package/src/models/workshop/locate.mjs +60 -0
- package/src/models/workshop/modes.mjs +31 -0
- package/src/models/workshop/taskfile.mjs +21 -0
- package/src/procedures/_index.mjs +32 -0
- package/src/procedures/agent-recording/_index.mjs +34 -0
- package/src/procedures/agent-recording/situate.mjs +11 -0
- package/src/procedures/bootstrapping/DESCRIPTION.md +6 -0
- package/src/procedures/bootstrapping/_index.mjs +13 -0
- package/src/procedures/bootstrapping/deploy-guides.mjs +15 -0
- package/src/procedures/bootstrapping/ensure-tree.mjs +4 -0
- package/src/procedures/closing/DESCRIPTION.md +6 -0
- package/src/procedures/closing/_index.mjs +11 -0
- package/src/procedures/closing/capture-ttystory.mjs +14 -0
- package/src/procedures/closing/record-closing.mjs +6 -0
- package/src/procedures/describing/DESCRIPTION.md +23 -0
- package/src/procedures/describing/_index.mjs +15 -0
- package/src/procedures/describing/ask-skryba.mjs +82 -0
- package/src/procedures/describing/compose-message.mjs +25 -0
- package/src/procedures/describing/read-staged.mjs +7 -0
- package/src/procedures/describing/scopes.mjs +38 -0
- package/src/procedures/describing/staged-diff.mjs +25 -0
- package/src/procedures/describing/write-message.mjs +15 -0
- package/src/procedures/gathering/DESCRIPTION.md +13 -0
- package/src/procedures/gathering/_index.mjs +13 -0
- package/src/procedures/gathering/list-served.mjs +9 -0
- package/src/procedures/gathering/merge-residents.mjs +31 -0
- package/src/procedures/gathering/read-registry.mjs +7 -0
- package/src/procedures/hooking/DESCRIPTION.md +6 -0
- package/src/procedures/hooking/_index.mjs +12 -0
- package/src/procedures/hooking/hooks.mjs +10 -0
- package/src/procedures/hooking/install-hooks.mjs +34 -0
- package/src/procedures/hooking/record-hook.mjs +13 -0
- package/src/procedures/inspecting/DESCRIPTION.md +3 -0
- package/src/procedures/inspecting/_index.mjs +9 -0
- package/src/procedures/loading/DESCRIPTION.md +4 -0
- package/src/procedures/loading/_index.mjs +15 -0
- package/src/procedures/loading/load-config.mjs +16 -0
- package/src/procedures/loading/validate-mode.mjs +8 -0
- package/src/procedures/loading/validate-role.mjs +8 -0
- package/src/procedures/locating/DESCRIPTION.md +6 -0
- package/src/procedures/locating/_index.mjs +13 -0
- package/src/procedures/locating/locate-self.mjs +7 -0
- package/src/procedures/locating/locate-workshop.mjs +16 -0
- package/src/procedures/locating/read-environment.mjs +12 -0
- package/src/procedures/mode-switching/DESCRIPTION.md +7 -0
- package/src/procedures/mode-switching/_index.mjs +10 -0
- package/src/procedures/mode-switching/record-mode.mjs +8 -0
- package/src/procedures/mode-switching/switch-mode.mjs +16 -0
- package/src/procedures/opening/DESCRIPTION.md +6 -0
- package/src/procedures/opening/_index.mjs +8 -0
- package/src/procedures/opening/record-opening.mjs +4 -0
- package/src/procedures/promoting/DESCRIPTION.md +8 -0
- package/src/procedures/promoting/_index.mjs +14 -0
- package/src/procedures/promoting/apply.mjs +28 -0
- package/src/procedures/promoting/branch-flow.mjs +23 -0
- package/src/procedures/promoting/plan.mjs +14 -0
- package/src/procedures/promoting/read-position.mjs +15 -0
- package/src/procedures/sinking/DESCRIPTION.md +8 -0
- package/src/procedures/sinking/_index.mjs +12 -0
- package/src/procedures/sinking/inventory-forge.mjs +18 -0
- package/src/procedures/sinking/inventory-tools.mjs +7 -0
- package/src/procedures/skilling/DESCRIPTION.md +11 -0
- package/src/procedures/skilling/_index.mjs +15 -0
- package/src/procedures/skilling/collect-models.mjs +15 -0
- package/src/procedures/skilling/compose-skill.mjs +49 -0
- package/src/procedures/skilling/glossary.mjs +23 -0
- package/src/procedures/skilling/register-skills.mjs +21 -0
- package/src/procedures/skilling/write-skills.mjs +19 -0
- package/src/views/_index.mjs +23 -0
- package/src/views/agent/_index.mjs +2 -0
- package/src/views/agent/brief.mjs +34 -0
- package/src/views/help/_index.mjs +41 -0
- package/src/views/house/_index.mjs +56 -0
- package/src/views/inventory/_index.mjs +27 -0
- package/src/views/mcp/_index.mjs +31 -0
- package/src/views/mcp/tools.mjs +87 -0
- package/src/views/mode/_index.mjs +34 -0
- package/src/views/mode/chooser.mjs +37 -0
- package/src/views/promotion/_index.mjs +20 -0
- package/src/views/repl/_index.mjs +30 -0
- package/src/views/skills/_index.mjs +24 -0
- package/src/views/status/_index.mjs +57 -0
- package/src/views/status/tree.mjs +19 -0
- package/src/views/terminal/paint.mjs +22 -0
- package/template/SKILL.md +16 -0
- package/docs/README.md +0 -15
- package/docs/devlog.md +0 -20
- package/invoke-api.js +0 -0
- package/invoke-cli.js +0 -105
- package/invoke-desktop.js +0 -0
- package/invoke-exec.js +0 -0
- package/invoke-webapp.js +0 -0
- package/main.js +0 -33
- package/shell-procedures/deploy-new-workshop.sh +0 -15
- package/shell-procedures/new-project.sh +0 -0
- package/shell-procedures/new-sheme.sh +0 -0
- package/shell-procedures/new-superproject.sh +0 -6
- package/shell-procedures/open-project.sh +0 -0
- package/shell-procedures/pack-backup.sh +0 -22
- package/shell-procedures/project-to-sarcophag.sh +0 -0
- package/shell-procedures/publicate.sh +0 -0
- package/shell-procedures/pull-archive.sh +0 -0
- package/shell-procedures/purge-workshop.sh +0 -4
- package/shell-procedures/push-to-bos-server.sh +0 -0
- package/shell-procedures/start-cli-interface.sh +0 -1
- package/shell-procedures/sweep-into-throwbox.sh +0 -0
- package/shell-procedures/synchronize.sh +0 -7
- package/system/bridges/README.md +0 -4
- package/system/bridges/main.js +0 -41
- package/system/commands/README.md +0 -0
- package/system/commands/debug.js +0 -20
- package/system/commands/exit.js +0 -19
- package/system/core/README.md +0 -0
- package/system/core/basic-subject-model.js +0 -200
- package/system/core/config-controll.js +0 -51
- package/system/core/contain-controll.js +0 -28
- package/system/core/event-controll.js +0 -12
- package/system/core/extending-mod.js +0 -145
- package/system/core/main.js +0 -184
- package/system/core/raport-controll.js +0 -10
- package/system/core/static-extender.js +0 -19
- package/system/factors/README.md +0 -0
- package/system/factors/bridge-factory.js +0 -5
- package/system/factors/command-factory.js +0 -45
- package/system/factors/config-factory.js +0 -6
- package/system/factors/controller-factory.js +0 -5
- package/system/factors/interface-factory.js +0 -70
- package/system/factors/model-factory.js +0 -0
- package/system/interfaces/README.md +0 -28
- package/system/interfaces/cli/index.js +0 -96
- package/system/interfaces/cli/init.js +0 -47
- package/system/interfaces/cli/loop.js +0 -7
- package/system/interfaces/cli/on-close.js +0 -17
- package/system/interfaces/cli/on-line.js +0 -24
- package/system/interfaces/cli/on-resume.js +0 -15
- package/system/interfaces/cli/setup.js +0 -8
- package/system/models/README.md +0 -47
- package/system/models/archive/README.md +0 -0
- package/system/models/archive/actions/README.md +0 -0
- package/system/models/archive/class.js +0 -23
- package/system/models/archive/events/README.md +0 -0
- package/system/models/archive/index.json +0 -18
- package/system/models/archive/listeners/README.md +0 -0
- package/system/models/archive/methods/README.md +0 -0
- package/system/models/forge/README.md +0 -0
- package/system/models/forge/actions/README.md +0 -0
- package/system/models/forge/class.js +0 -23
- package/system/models/forge/events/README.md +0 -0
- package/system/models/forge/index.json +0 -18
- package/system/models/forge/listeners/README.md +0 -0
- package/system/models/forge/methods/README.md +0 -0
- package/system/models/project/README.md +0 -0
- package/system/models/project/actions/README.md +0 -0
- package/system/models/project/class.js +0 -23
- package/system/models/project/events/README.md +0 -0
- package/system/models/project/index.json +0 -18
- package/system/models/project/listeners/README.md +0 -0
- package/system/models/project/methods/README.md +0 -0
- package/system/models/sarcophag/README.md +0 -0
- package/system/models/sarcophag/actions/README.md +0 -0
- package/system/models/sarcophag/class.js +0 -22
- package/system/models/sarcophag/events/README.md +0 -0
- package/system/models/sarcophag/index.json +0 -18
- package/system/models/sarcophag/listeners/README.md +0 -0
- package/system/models/sarcophag/methods/README.md +0 -0
- package/system/models/sheme/README.md +0 -0
- package/system/models/sheme/actions/README.md +0 -0
- package/system/models/sheme/class.js +0 -23
- package/system/models/sheme/events/README.md +0 -0
- package/system/models/sheme/index.json +0 -18
- package/system/models/sheme/listeners/README.md +0 -0
- package/system/models/sheme/methods/README.md +0 -0
- package/system/models/superproject/README.md +0 -0
- package/system/models/superproject/actions/README.md +0 -0
- package/system/models/superproject/class.js +0 -23
- package/system/models/superproject/events/README.md +0 -0
- package/system/models/superproject/index.json +0 -18
- package/system/models/superproject/listeners/README.md +0 -0
- package/system/models/superproject/methods/README.md +0 -0
- package/system/models/throwbox/README.md +0 -0
- package/system/models/throwbox/actions/README.md +0 -0
- package/system/models/throwbox/class.js +0 -23
- package/system/models/throwbox/events/README.md +0 -0
- package/system/models/throwbox/index.json +0 -18
- package/system/models/throwbox/listeners/README.md +0 -0
- package/system/models/throwbox/methods/README.md +0 -0
- package/system/models/workshop/README.md +0 -0
- package/system/models/workshop/actions/README.md +0 -0
- package/system/models/workshop/class.js +0 -22
- package/system/models/workshop/events/README.md +0 -0
- package/system/models/workshop/index.json +0 -18
- package/system/models/workshop/listeners/README.md +0 -0
- package/system/models/workshop/methods/README.md +0 -0
- package/system/resources/textarts/big-logo-title.txt +0 -24
- package/system/resources/textarts/big-shortcut-logo-title.txt +0 -10
- package/system/resources/textarts/medium-logo-title.txt +0 -13
- package/system/resources/textarts/minimenu-header.ptxml +0 -13
- package/system/resources/textarts/minimenu-header.txt +0 -11
- package/system/resources/textarts/small-logo-title.txt +0 -10
- package/system/resources/textarts/wellcome.txt +0 -10
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// What an agent learns at the start of a session: the workshop, its role and mode, where it
|
|
2
|
+
// works, the House's boundaries, and the tools BOS gives it. Short: it becomes context.
|
|
3
|
+
import House from "../../models/house/class.mjs";
|
|
4
|
+
import { MODES } from "../../models/workshop/modes.mjs";
|
|
5
|
+
import { situate } from "../../procedures/agent-recording/situate.mjs";
|
|
6
|
+
|
|
7
|
+
export async function brief(input) {
|
|
8
|
+
const context = await situate(input);
|
|
9
|
+
if (!context) return null;
|
|
10
|
+
const { config, defaulted = [], self } = context;
|
|
11
|
+
const mark = (key) => (defaulted.includes(key) ? " (default)" : "");
|
|
12
|
+
const place = context.workshop.placeOf(input.cwd ?? process.cwd());
|
|
13
|
+
const where = !place
|
|
14
|
+
? "outside this workshop"
|
|
15
|
+
: place.area
|
|
16
|
+
? [place.area, place.scope, place.project].filter(Boolean).join(" / ")
|
|
17
|
+
: "workshop root";
|
|
18
|
+
const house = new House();
|
|
19
|
+
const resting = [...house.children(), ...house.orders()]
|
|
20
|
+
.filter((g) => g.state !== "active")
|
|
21
|
+
.map((g) => g.title ?? g.name);
|
|
22
|
+
return [
|
|
23
|
+
"# BOS: Blacksmith Organization System",
|
|
24
|
+
`workshop ${context.workshopRoot} · role ${config.role}${mark("role")} · mode ${MODES[config.mode]?.title ?? config.mode}${mark("mode")} · BOS v${self.version}`,
|
|
25
|
+
`you are in: ${where}`,
|
|
26
|
+
`House of Anubis: ${house.children().length} adopted children, orders: ${house
|
|
27
|
+
.orders()
|
|
28
|
+
.map((o) => o.title ?? o.name)
|
|
29
|
+
.join(", ")}.${resting.length ? ` Resting, never call or prompt: ${resting.join(", ")}.` : ""}`,
|
|
30
|
+
"tools: `bos` CLI on PATH (bos help), MCP tools bos_* (bos_glossary explains any element)",
|
|
31
|
+
"rules: ask the House before calling any ollama model · conventional commits · look before changing the owner's files · the owner works in parallel: re-check git state",
|
|
32
|
+
"",
|
|
33
|
+
].join("\n");
|
|
34
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Help: the list of commands, or one command's help file with light markdown styling.
|
|
2
|
+
import { BOS } from "../../main.ts";
|
|
3
|
+
import { MODES } from "../../models/workshop/modes.mjs";
|
|
4
|
+
import { header, pad, paint } from "../terminal/paint.mjs";
|
|
5
|
+
|
|
6
|
+
const markdown = (text) =>
|
|
7
|
+
text
|
|
8
|
+
.replace(/^#+\s*(.+)$/gm, (_, title) => paint.bold(paint.yellow(title)))
|
|
9
|
+
.replace(/`([^`]+)`/g, (_, code) => paint.cyan(code))
|
|
10
|
+
.replace(/\*\*([^*]+)\*\*/g, (_, strong) => paint.bold(strong));
|
|
11
|
+
|
|
12
|
+
export class HelpView extends BOS.View {
|
|
13
|
+
text({ commands, command, help }) {
|
|
14
|
+
if (command) return markdown(help?.text ?? commands[command]?.info ?? `no help for ${command}`);
|
|
15
|
+
const size = Math.max(...Object.keys(commands).map((name) => name.length)) + 2;
|
|
16
|
+
const line = ([name, c]) => ` ${paint.cyan(pad(name, size))}${c.info ?? ""}${c.repl ? paint.dim(" (repl)") : ""}`;
|
|
17
|
+
const group = (title, entries, always = false) =>
|
|
18
|
+
entries.length || always
|
|
19
|
+
? ["", paint.bold(title), ...(entries.length ? entries.map(line) : [paint.dim(" nothing yet")])]
|
|
20
|
+
: [];
|
|
21
|
+
const all = Object.entries(commands);
|
|
22
|
+
return [
|
|
23
|
+
header("bos <command> [options]"),
|
|
24
|
+
...group(
|
|
25
|
+
"general",
|
|
26
|
+
all.filter(([, c]) => !c.mode),
|
|
27
|
+
),
|
|
28
|
+
...Object.entries(MODES).flatMap(([name, mode]) =>
|
|
29
|
+
group(
|
|
30
|
+
`${mode.digit} ${mode.title}`,
|
|
31
|
+
all.filter(([, c]) => c.mode === name),
|
|
32
|
+
true,
|
|
33
|
+
),
|
|
34
|
+
),
|
|
35
|
+
"",
|
|
36
|
+
paint.dim("options: --json --dry-run --workshop=PATH · bos help <command> · bos mode"),
|
|
37
|
+
].join("\n");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default HelpView;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// The House of Anubis: children (adopted by name), orders (duties), bloodlines (releasers).
|
|
2
|
+
import { BOS } from "../../main.ts";
|
|
3
|
+
import { header, pad, paint } from "../terminal/paint.mjs";
|
|
4
|
+
|
|
5
|
+
const STATE = { active: paint.green, resting: paint.magenta, frozen: paint.blue };
|
|
6
|
+
|
|
7
|
+
const presence = (member) => {
|
|
8
|
+
if (member.state && member.state !== "active") return (STATE[member.state] ?? paint.dim)(`◌ ${member.state}`);
|
|
9
|
+
if (member.present === null) return paint.dim("remote");
|
|
10
|
+
return member.present ? paint.green("● served") : paint.dim("○ absent");
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function group(group) {
|
|
14
|
+
const lines = [
|
|
15
|
+
`${paint.bold(group.title ?? group.name)} ${(STATE[group.state] ?? paint.dim)(group.state)} ${paint.dim(group.description ?? "")}`,
|
|
16
|
+
];
|
|
17
|
+
if (group.state === "resting") lines.push(` ${paint.magenta("rests by its own decision; not called")}`);
|
|
18
|
+
for (const member of group.members) {
|
|
19
|
+
const label =
|
|
20
|
+
member.name && member.model ? `${member.name} ${paint.dim(`(${member.model})`)}` : (member.name ?? member.model);
|
|
21
|
+
const line = member.bloodline ? paint.dim(`${member.bloodline.releaser} ← ${member.bloodline.root}`) : "";
|
|
22
|
+
const about = member.duty ? paint.cyan(member.duty) : paint.dim(member.note ?? "");
|
|
23
|
+
lines.push(` ${pad(label, 46)} ${pad(presence(member), 10)} ${pad(line, 36)} ${about}`);
|
|
24
|
+
}
|
|
25
|
+
return lines.join("\n");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class HouseView extends BOS.View {
|
|
29
|
+
data({ children, orders, bloodlines, catalog }) {
|
|
30
|
+
return { reachable: catalog !== null, children, orders, bloodlines };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
text({ children = [], orders = [], bloodlines = [], catalog, options = {} }) {
|
|
34
|
+
const lines = [header("House of Anubis"), ""];
|
|
35
|
+
if (catalog === null) lines.push(paint.yellow("ollama unreachable: presence and bloodlines unknown"), "");
|
|
36
|
+
lines.push(paint.yellow("Children of Anubis") + paint.dim(" adopted by name"), "");
|
|
37
|
+
for (const child of children) lines.push(group(child), "");
|
|
38
|
+
lines.push(paint.yellow("Orders") + paint.dim(" duties"), "");
|
|
39
|
+
for (const order of orders) lines.push(group(order), "");
|
|
40
|
+
if (bloodlines.length) {
|
|
41
|
+
lines.push(
|
|
42
|
+
paint.yellow("Bloodlines") + paint.dim(" every served model by releaser, through its parent_model"),
|
|
43
|
+
"",
|
|
44
|
+
);
|
|
45
|
+
for (const { releaser, models } of bloodlines) {
|
|
46
|
+
lines.push(
|
|
47
|
+
` ${pad(releaser, 30)} ${paint.bold(models.length)}${options.all ? ` ${paint.dim(models.join(", "))}` : ""}`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
if (!options.all) lines.push(paint.dim(" bos house --all lists every model"));
|
|
51
|
+
}
|
|
52
|
+
return lines.join("\n");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default HouseView;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// What sinking would have to rescue: projects with their state, and ttystories.
|
|
2
|
+
import { BOS } from "../../main.ts";
|
|
3
|
+
import { header, pad, paint } from "../terminal/paint.mjs";
|
|
4
|
+
|
|
5
|
+
export class InventoryView extends BOS.View {
|
|
6
|
+
data({ inventory }) {
|
|
7
|
+
return inventory;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
text({ inventory }) {
|
|
11
|
+
const rows = inventory.projects.map(
|
|
12
|
+
({ scope, project, branch, uncommitted }) =>
|
|
13
|
+
` ${pad(`${scope}/${project}`, 48)} ${paint.cyan(pad(branch ?? "?", 14))} ${uncommitted ? paint.red(`${uncommitted} uncommitted`) : paint.green("clean")}`,
|
|
14
|
+
);
|
|
15
|
+
return [
|
|
16
|
+
header("sinking inventory"),
|
|
17
|
+
"",
|
|
18
|
+
paint.bold(`projects (${rows.length})`),
|
|
19
|
+
...(rows.length ? rows : [paint.dim(" none in forge")]),
|
|
20
|
+
"",
|
|
21
|
+
paint.bold(`ttystories (${inventory.ttystories.length})`),
|
|
22
|
+
...inventory.ttystories.map((name) => ` ${name}`),
|
|
23
|
+
].join("\n");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default InventoryView;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// BOS over the Model Context Protocol (stdio): every TOOLS entry becomes an MCP tool.
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
|
|
5
|
+
import { VERSION } from "../../core/self.mjs";
|
|
6
|
+
import { READ_ONLY, TOOLS } from "./tools.mjs";
|
|
7
|
+
|
|
8
|
+
export function createMcpServer(bos) {
|
|
9
|
+
const server = new McpServer({ name: "bos", version: VERSION });
|
|
10
|
+
for (const tool of TOOLS) {
|
|
11
|
+
server.registerTool(
|
|
12
|
+
tool.name,
|
|
13
|
+
{ description: tool.description, inputSchema: tool.input, annotations: READ_ONLY },
|
|
14
|
+
async (args = {}) => {
|
|
15
|
+
try {
|
|
16
|
+
const output = await tool.run(bos, args);
|
|
17
|
+
return {
|
|
18
|
+
content: [{ type: "text", text: typeof output === "string" ? output : JSON.stringify(output, null, 2) }],
|
|
19
|
+
};
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return { isError: true, content: [{ type: "text", text: `${tool.name}: ${error.message}` }] };
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return server;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function startMcpServer(bos) {
|
|
30
|
+
await createMcpServer(bos).connect(new StdioServerTransport());
|
|
31
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// BOS as MCP tools: what an AI agent may ask the workshop. All read-only: agents look and
|
|
2
|
+
// plan through MCP; changing the workshop stays a conscious act on the command line.
|
|
3
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
import { REPO_ROOT } from "../../core/self.mjs";
|
|
9
|
+
|
|
10
|
+
const GLOSSARY = join(REPO_ROOT, "docs", "glossary");
|
|
11
|
+
const readOnly = { readOnlyHint: true, destructiveHint: false, openWorldHint: false };
|
|
12
|
+
|
|
13
|
+
export const TOOLS = [
|
|
14
|
+
{
|
|
15
|
+
name: "bos_locate",
|
|
16
|
+
description:
|
|
17
|
+
"Active BOS workshop (~/__WORKSHOP or /media/**/__WORKSHOP), the rule that found it, and where BOS itself sits.",
|
|
18
|
+
input: {},
|
|
19
|
+
run: async (bos) => bos.command("locate"),
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "bos_status",
|
|
23
|
+
description:
|
|
24
|
+
"Workshop tree (.BOS, devarmory, forge, craftbook, archive): what exists and what is missing; role and mode of work.",
|
|
25
|
+
input: {},
|
|
26
|
+
run: async (bos) => bos.command("status"),
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "bos_house",
|
|
30
|
+
description:
|
|
31
|
+
"The House of Anubis: adopted children, orders (RavensArmy…), bloodlines of every served model, and each resident's state. Resting residents must never be called.",
|
|
32
|
+
input: { all: z.boolean().optional().describe("also list every model per bloodline") },
|
|
33
|
+
run: async (bos, { all }) => bos.command("house", [], { all: Boolean(all) }),
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "bos_glossary",
|
|
37
|
+
description:
|
|
38
|
+
"Definition of a BOS element (workshop, forge, scope, sheme, sarcophag, mode, house, raven…) from docs/glossary; without a term, the list of pages.",
|
|
39
|
+
input: { term: z.string().optional().describe("element name, e.g. forge") },
|
|
40
|
+
run: async (_bos, { term }) => {
|
|
41
|
+
if (!term)
|
|
42
|
+
return readdirSync(GLOSSARY)
|
|
43
|
+
.filter((f) => f.endsWith(".md"))
|
|
44
|
+
.map((f) => f.slice(0, -3))
|
|
45
|
+
.join("\n");
|
|
46
|
+
const page = join(GLOSSARY, `${term.toLowerCase().replace(/[^a-z0-9-]/g, "")}.md`);
|
|
47
|
+
return existsSync(page) ? readFileSync(page, "utf8") : `no glossary page for "${term}"`;
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "bos_describe",
|
|
52
|
+
description:
|
|
53
|
+
"Conventional-commit draft for what is staged in a git repository (deterministic; Skryba the scribe raven only when asked, it may take up to 90 s).",
|
|
54
|
+
input: {
|
|
55
|
+
cwd: z.string().describe("path inside the repository"),
|
|
56
|
+
skryba: z.boolean().optional().describe("let Skryba refine the draft through ollama"),
|
|
57
|
+
},
|
|
58
|
+
run: async (bos, { cwd, skryba }) =>
|
|
59
|
+
(await bos.workshop.describe({ cwd, skryba: Boolean(skryba) })).message ?? "nothing staged",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "bos_promote_plan",
|
|
63
|
+
description:
|
|
64
|
+
"Plan (never apply) moving a repository's current branch one station along the flow master → developement → revision → testing → releasing → master.",
|
|
65
|
+
input: { cwd: z.string().describe("path inside the repository"), reject: z.boolean().optional() },
|
|
66
|
+
run: async (bos, { cwd, reject }) => {
|
|
67
|
+
const context = await bos.workshop.run("promoting", { cwd, reject: Boolean(reject), dryRun: true });
|
|
68
|
+
return new bos.views.PromotionView().text(context);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "bos_sink_inventory",
|
|
73
|
+
description:
|
|
74
|
+
"Read-only inventory for the sinking protocol: every forge project with branch and uncommitted changes, and the ttystories.",
|
|
75
|
+
input: {},
|
|
76
|
+
run: async (bos) => bos.command("sink"),
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "bos_help",
|
|
80
|
+
description:
|
|
81
|
+
"BOS commands grouped by mode of work (ALMANAC, CONFORM, SMELTRY, COMMANDORATE, PROVISION), or the help of one command.",
|
|
82
|
+
input: { command: z.string().optional() },
|
|
83
|
+
run: async (bos, { command }) => bos.command("help", command ? [command] : []),
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
export const READ_ONLY = readOnly;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// The modes of work as a menu, and the result of a switch.
|
|
2
|
+
import { BOS } from "../../main.ts";
|
|
3
|
+
import { MODES } from "../../models/workshop/modes.mjs";
|
|
4
|
+
import { header, pad, paint } from "../terminal/paint.mjs";
|
|
5
|
+
|
|
6
|
+
export const modeLabel = (mode) =>
|
|
7
|
+
mode ? `${paint.magenta(MODES[mode].title)} ${paint.dim(MODES[mode].covers)}` : paint.dim("not chosen: bos mode");
|
|
8
|
+
|
|
9
|
+
export class ModeView extends BOS.View {
|
|
10
|
+
data({ config, previousMode, event }) {
|
|
11
|
+
return { mode: config?.mode ?? null, previousMode: previousMode ?? null, event: event ?? null };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// the chooser's menu, current mode marked
|
|
15
|
+
menu(current) {
|
|
16
|
+
return [
|
|
17
|
+
header("mode of work"),
|
|
18
|
+
"",
|
|
19
|
+
...Object.entries(MODES).map(([name, mode]) => {
|
|
20
|
+
const mark = name === current ? paint.green("●") : " ";
|
|
21
|
+
return ` ${mark} ${paint.yellow(mode.digit)} ${pad(paint.bold(mode.title), 14)} ${paint.dim(mode.covers)}`;
|
|
22
|
+
}),
|
|
23
|
+
` ${paint.yellow(0)} ${paint.dim("leave")}`,
|
|
24
|
+
"",
|
|
25
|
+
].join("\n");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
text({ config, previousMode }) {
|
|
29
|
+
if (previousMode === config.mode) return `mode stays ${modeLabel(config.mode)}`;
|
|
30
|
+
return `mode ${paint.dim(previousMode ?? "none")} ${paint.yellow("→")} ${modeLabel(config.mode)}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default ModeView;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// One digit, no Enter: 0…max on a terminal. From a pipe: the first digit of the first line.
|
|
2
|
+
// Anything else, Ctrl+C or end of input counts as 0 (leave).
|
|
3
|
+
import readline from "node:readline";
|
|
4
|
+
|
|
5
|
+
export function chooseDigit(prompt, max, { input = process.stdin, output = process.stdout } = {}) {
|
|
6
|
+
output.write(prompt);
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
const done = (digit) => {
|
|
9
|
+
output.write(`${digit}\n`);
|
|
10
|
+
resolve(digit);
|
|
11
|
+
};
|
|
12
|
+
if (input.isTTY) {
|
|
13
|
+
readline.emitKeypressEvents(input);
|
|
14
|
+
input.setRawMode(true);
|
|
15
|
+
input.resume();
|
|
16
|
+
const onKey = (text, key = {}) => {
|
|
17
|
+
const digit = key.ctrl && key.name === "c" ? 0 : /^\d$/.test(text ?? "") ? Number(text) : null;
|
|
18
|
+
if (digit === null || digit > max) return;
|
|
19
|
+
input.off("keypress", onKey);
|
|
20
|
+
input.setRawMode(false);
|
|
21
|
+
input.pause();
|
|
22
|
+
done(digit);
|
|
23
|
+
};
|
|
24
|
+
input.on("keypress", onKey);
|
|
25
|
+
} else {
|
|
26
|
+
const lines = readline.createInterface({ input });
|
|
27
|
+
let answered = false;
|
|
28
|
+
lines.once("line", (line) => {
|
|
29
|
+
answered = true;
|
|
30
|
+
const digit = Number(line.trim()[0]);
|
|
31
|
+
lines.close();
|
|
32
|
+
done(Number.isInteger(digit) && digit <= max ? digit : 0);
|
|
33
|
+
});
|
|
34
|
+
lines.once("close", () => answered || done(0));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// One station along the branch flow: from → to, and the plan.
|
|
2
|
+
import { BOS } from "../../main.ts";
|
|
3
|
+
import { BRANCHES } from "../../procedures/promoting/branch-flow.mjs";
|
|
4
|
+
import { paint } from "../terminal/paint.mjs";
|
|
5
|
+
|
|
6
|
+
export class PromotionView extends BOS.View {
|
|
7
|
+
data({ from, to, plan, dryRun, pullRequest }) {
|
|
8
|
+
return { from, to, plan, dryRun, pullRequest };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
text({ from, to, plan, dryRun }) {
|
|
12
|
+
return [
|
|
13
|
+
`${paint.cyan(from)} ${paint.yellow("→")} ${paint.cyan(to)} ${paint.dim(BRANCHES[to])}`,
|
|
14
|
+
...plan.map((step) => ` ${paint.dim("•")} ${step}`),
|
|
15
|
+
dryRun ? paint.dim("dry run: add --apply to execute") : paint.green("applied"),
|
|
16
|
+
].join("\n");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default PromotionView;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Interactive BOS: every command at a prompt. A command with its own repl.mjs
|
|
2
|
+
// gets the prompt to ask questions; others print their inline output.
|
|
3
|
+
import readline from "node:readline/promises";
|
|
4
|
+
|
|
5
|
+
import { header, paint } from "../terminal/paint.mjs";
|
|
6
|
+
|
|
7
|
+
export async function startRepl(bos) {
|
|
8
|
+
const io = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
9
|
+
console.log(header("BOS repl"), paint.dim("· help · exit"));
|
|
10
|
+
io.setPrompt(paint.yellow("⚒ bos › "));
|
|
11
|
+
io.prompt();
|
|
12
|
+
for await (const line of io) {
|
|
13
|
+
const [name, ...operands] = line.trim().split(/\s+/).filter(Boolean);
|
|
14
|
+
if (name === "exit" || name === "quit") break;
|
|
15
|
+
if (name) {
|
|
16
|
+
try {
|
|
17
|
+
const command = bos.commands[name];
|
|
18
|
+
if (!command) throw new Error(`unknown command "${name}"`);
|
|
19
|
+
const output = command.repl
|
|
20
|
+
? await command.repl({ bos, operands, flags: bos.options, io })
|
|
21
|
+
: await command.inline({ bos, operands, flags: bos.options });
|
|
22
|
+
if (output) console.log(typeof output === "string" ? output : JSON.stringify(output, null, 2));
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.log(paint.red(error.message));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
io.prompt();
|
|
28
|
+
}
|
|
29
|
+
io.close();
|
|
30
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Which model has a skill, which got a fresh draft.
|
|
2
|
+
import { BOS } from "../../main.ts";
|
|
3
|
+
import { header, pad, paint } from "../terminal/paint.mjs";
|
|
4
|
+
|
|
5
|
+
export class SkillsView extends BOS.View {
|
|
6
|
+
data({ skills, registered, dryRun }) {
|
|
7
|
+
return { skills: skills.map(({ name, created }) => ({ name, created })), registered, dryRun };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
text({ skills, registered = [], dryRun }) {
|
|
11
|
+
const state = (created) => (created ? paint.green(dryRun ? "+ would draft" : "+ drafted") : paint.dim("● exists"));
|
|
12
|
+
return [
|
|
13
|
+
header("skills"),
|
|
14
|
+
"",
|
|
15
|
+
...skills.map(({ name, created }) => ` ${pad(paint.cyan(name), 24)} ${state(created)}`),
|
|
16
|
+
"",
|
|
17
|
+
registered.length
|
|
18
|
+
? `${dryRun ? "would register" : "registered"} ${registered.length} in marketplace.json`
|
|
19
|
+
: paint.dim("marketplace up to date"),
|
|
20
|
+
].join("\n");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default SkillsView;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// The state of a workshop: where it is, its role, where BOS sits, its tree, what changed.
|
|
2
|
+
import { BOS } from "../../main.ts";
|
|
3
|
+
import { HOST_ROLES } from "../../models/workshop/host-roles.mjs";
|
|
4
|
+
import { modeLabel } from "../mode/_index.mjs";
|
|
5
|
+
import { field, header, paint } from "../terminal/paint.mjs";
|
|
6
|
+
import { drawTree } from "./tree.mjs";
|
|
7
|
+
|
|
8
|
+
function place(self) {
|
|
9
|
+
if (!self?.place) return paint.dim("outside the active workshop");
|
|
10
|
+
const { area, scope, project } = self.place;
|
|
11
|
+
return [area, scope, project].filter(Boolean).join(paint.dim(" / ")) || "workshop root";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class StatusView extends BOS.View {
|
|
15
|
+
data(context) {
|
|
16
|
+
const { workshopRoot, workshopSource, workshops, config, defaulted, tree, self, changes, dryRun, event } = context;
|
|
17
|
+
return { workshopRoot, workshopSource, workshops, config, defaulted, tree, self, changes, dryRun, event };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
text(context) {
|
|
21
|
+
const lines = [header("Blacksmith Organization System"), ""];
|
|
22
|
+
lines.push(field("workshop", `${context.workshopRoot} ${paint.dim(`(${context.workshopSource})`)}`));
|
|
23
|
+
if (context.config) {
|
|
24
|
+
const { role } = context.config;
|
|
25
|
+
const byDefault = (key) => (context.defaulted?.includes(key) ? paint.dim(" (default)") : "");
|
|
26
|
+
lines.push(
|
|
27
|
+
field(
|
|
28
|
+
"role",
|
|
29
|
+
(role
|
|
30
|
+
? `${paint.cyan(role)} ${paint.dim(HOST_ROLES[role])}`
|
|
31
|
+
: paint.dim('not set: .BOS/workshop.json "role"')) + byDefault("role"),
|
|
32
|
+
),
|
|
33
|
+
);
|
|
34
|
+
lines.push(field("mode", modeLabel(context.config.mode) + byDefault("mode")));
|
|
35
|
+
}
|
|
36
|
+
lines.push(field("BOS", `${paint.bold(`v${context.self.version}`)} ${paint.dim("·")} ${place(context.self)}`));
|
|
37
|
+
const others = context.workshops.filter((path) => path !== context.workshopRoot);
|
|
38
|
+
if (others.length) lines.push(field("others", others.join("\n ")));
|
|
39
|
+
const snapshot = context.tree ?? context.workshop?.inspect();
|
|
40
|
+
if (snapshot) lines.push("", drawTree(snapshot));
|
|
41
|
+
if (context.changes?.length) {
|
|
42
|
+
lines.push(
|
|
43
|
+
"",
|
|
44
|
+
paint.bold(context.dryRun ? "would create" : "created"),
|
|
45
|
+
...context.changes.map((path) => ` ${paint.green("+")} ${path}`),
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
if (context.event)
|
|
49
|
+
lines.push(
|
|
50
|
+
"",
|
|
51
|
+
field("recorded", `${paint.magenta(context.event.event)} ${paint.dim(`@ ${context.event.unixusat}`)}`),
|
|
52
|
+
);
|
|
53
|
+
return lines.join("\n");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default StatusView;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// The workshop tree drawn with branches and a colored state per area.
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { pad, paint } from "../terminal/paint.mjs";
|
|
5
|
+
|
|
6
|
+
const mark = (node) =>
|
|
7
|
+
node.exists ? paint.green("● ok") : node.mandatory ? paint.red("○ missing") : paint.dim("· not yet");
|
|
8
|
+
|
|
9
|
+
export function drawTree(node, prefix = "", last = true, root = true) {
|
|
10
|
+
const branch = root ? "" : last ? "└── " : "├── ";
|
|
11
|
+
const name = root ? paint.bold(node.path) : basename(node.path);
|
|
12
|
+
const label = pad(`${prefix}${branch}${name}`, root ? 0 : 40);
|
|
13
|
+
const line = root ? label : `${label} ${paint.dim(pad(node.type, 12))} ${mark(node)}`;
|
|
14
|
+
const childPrefix = root ? "" : prefix + (last ? " " : "│ ");
|
|
15
|
+
return [
|
|
16
|
+
line,
|
|
17
|
+
...node.children.map((child, i) => drawTree(child, childPrefix, i === node.children.length - 1, false)),
|
|
18
|
+
].join("\n");
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// ANSI colors for terminals; plain text for pipes, files and NO_COLOR.
|
|
2
|
+
const enabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
3
|
+
const code = (open, close) => (text) => (enabled ? `\x1b[${open}m${text}\x1b[${close}m` : String(text));
|
|
4
|
+
|
|
5
|
+
export const paint = {
|
|
6
|
+
bold: code(1, 22),
|
|
7
|
+
dim: code(2, 22),
|
|
8
|
+
red: code(31, 39),
|
|
9
|
+
green: code(32, 39),
|
|
10
|
+
yellow: code(33, 39),
|
|
11
|
+
blue: code(34, 39),
|
|
12
|
+
magenta: code(35, 39),
|
|
13
|
+
cyan: code(36, 39),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// visible length, ignoring color codes
|
|
17
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: \x1b starts the ANSI color codes this strips
|
|
18
|
+
export const width = (text) => String(text).replace(/\x1b\[\d+m/g, "").length;
|
|
19
|
+
export const pad = (text, size) => text + " ".repeat(Math.max(0, size - width(text)));
|
|
20
|
+
|
|
21
|
+
export const header = (title) => paint.bold(paint.yellow(`⚒ ${title}`));
|
|
22
|
+
export const field = (label, value) => `${paint.dim(pad(label, 10))}${value}`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-name
|
|
3
|
+
description: What this skill does and when an agent should use it. [`TODO`]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill Name
|
|
7
|
+
|
|
8
|
+
[`TODO`] Instructions the agent follows when this skill is active.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
[`TODO`]
|
|
13
|
+
|
|
14
|
+
## Instructions
|
|
15
|
+
|
|
16
|
+
[`TODO`]
|
package/docs/README.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
```
|
|
3
|
-
************************************
|
|
4
|
-
Part of R tier project "ANUBIS"
|
|
5
|
-
______ _____ _____
|
|
6
|
-
| ___ \ | _ | / ___|
|
|
7
|
-
| |_/ / | | | | \ `--.
|
|
8
|
-
| ___ \ | | | | `--. \
|
|
9
|
-
| |_/ / \ \_/ / /\__/ /
|
|
10
|
-
\____(_) \___(_) \____(_)
|
|
11
|
-
|
|
12
|
-
By Sett Sarverott @ 2019-2024
|
|
13
|
-
************************************
|
|
14
|
-
Version: 0.2.0 (PreAlfa_#1)
|
|
15
|
-
```
|
package/docs/devlog.md
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# ENTRY 1:
|
|
2
|
-
this is huge mess, i had overartistic phase about code, because of lack of reasoning in work. now it's time to list things to cutoff:
|
|
3
|
-
- strange require builder in libraries.js: i remember why it was like that - for easy morphing into browser-only service system... but it's dumb implementation of this idea, i had no clear idea how to do that
|
|
4
|
-
- every referencable var in module will be prioritized to be global scoped exclusively in file for reduction of too long reference chains and information noise generation by bad readability caused by text overwhelmnes in result
|
|
5
|
-
- prettification of staff
|
|
6
|
-
-
|
|
7
|
-
|
|
8
|
-
# entry 2:
|
|
9
|
-
model is autodeclaring own internals
|
|
10
|
-
> model directory:
|
|
11
|
-
- **class.js** - declaration of model
|
|
12
|
-
- ~fundation.json~ **index.json** - data structure of model
|
|
13
|
-
- **README.md** - about that type
|
|
14
|
-
- _**actions**_ - _DIR_ commands and available acts
|
|
15
|
-
- _**listeners**_ - _DIR_ all watchers and other stuff
|
|
16
|
-
- _**events**_ - _DIR_ basic behaviour
|
|
17
|
-
- _**extenders**_ - _DIR_ flat extension for every new object, produced by class.js
|
|
18
|
-
- _**methods**_ - _DIR_ synchronous static functions, resulting with return values
|
|
19
|
-
|
|
20
|
-
# entry 3:
|
package/invoke-api.js
DELETED
|
File without changes
|