mesh/delivery merged: source.main moved to novox/mesh-catalog@6d000647de2d
mesh/check being carried to cff1005422c1 on 6d000647de2d | from f9dcbc295723
The one bundle that did everything becomes the manager bundle, which runs long and answers the seat's ten verbs and the three acting tools, and a tools bundle of its own that answers the four reading tools and writes nothing, so they answer while the manager fails to load or stops. Both import the module's one package for the layouts of the kept data and the log entries, the key form, the entries' names and the settings with their validity; the settings file and the account with its directory stay as they are. Builds: design 39 parts §1, §2, §3, §4, §5, §6, §7, §8
71 lines
2.5 KiB
Go
71 lines
2.5 KiB
Go
// claude-licence-manager-tools (design 39 parts §3): the licence manager's tools bundle, loaded by the module's runtime
|
|
// of its own beside the manager bundle. It answers the module's four reading tools and writes nothing: it reads the
|
|
// module's kept data with the runtime's bus-state calls and its two logs with the runtime's log calls, each answered
|
|
// as the module whose bundle asks, and asks mesh-config where each setting was set. The runtime serves the tools of
|
|
// every bundle of a module that loaded, so these answer while the manager bundle fails to load or stops.
|
|
//
|
|
// stdout is the MCP channel; everything this bundle says, it says on stderr.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
|
|
"claude-licence-manager/internal/licences"
|
|
)
|
|
|
|
func main() {
|
|
if err := stdio.Serve("", fromTheRuntime().Tools()); err != nil {
|
|
fmt.Fprintf(os.Stderr, "[claude-licence-manager-tools] %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// fromTheRuntime is the reader of the module's kept data through its runtime, and of its settings file by the word
|
|
// the manager bundle gives the module (MESH_LICENCE_SETTINGS; ADR 0192: the runtime hands a module's words to all
|
|
// its bundles).
|
|
func fromTheRuntime() *Reader {
|
|
node, _ := os.Hostname()
|
|
if n := os.Getenv("MESH_NODE"); n != "" {
|
|
node = n
|
|
}
|
|
r := &Reader{States: map[string]licences.State{}, Logs: map[string]licences.Log{},
|
|
SettingsFile: os.Getenv("MESH_LICENCE_SETTINGS"),
|
|
ConfigLevels: func(context.Context) (map[string]string, error) { return configLevels(node) }}
|
|
for _, name := range licences.States {
|
|
r.States[name] = stdio.State(name)
|
|
}
|
|
for _, name := range licences.Logs {
|
|
r.Logs[name] = stdio.Log(name)
|
|
}
|
|
return r
|
|
}
|
|
|
|
// configLevels asks mesh-config where each of the module's own settings was set on its node (bus-and-switch §40,
|
|
// B18): the source of each resolved value, by its key.
|
|
func configLevels(node string) (map[string]string, error) {
|
|
raw, err := stdio.Ask("seat:mesh-config.config", map[string]any{"action": "list", "module": licences.Publisher,
|
|
"node": node})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var answer struct {
|
|
Resolved []struct {
|
|
Key string `json:"key"`
|
|
Source string `json:"source"`
|
|
} `json:"resolved"`
|
|
}
|
|
if err := json.Unmarshal(raw, &answer); err != nil {
|
|
return nil, fmt.Errorf("mesh-config's answer: %w", err)
|
|
}
|
|
levels := map[string]string{}
|
|
for _, r := range answer.Resolved {
|
|
levels[r.Key] = r.Source
|
|
}
|
|
return levels, nil
|
|
}
|