docs(flows): DoD obligatorio con user-facing surface + abrir issues 0100-0103 (taxonomia, frontmatter migration, dev_console, work dashboard)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,8 @@ func cmdDoctor(args []string) {
|
||||
}
|
||||
case "app-location":
|
||||
doctorAppLocation(r, jsonOut)
|
||||
case "modules":
|
||||
doctorModules(r, jsonOut)
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "unknown doctor subcommand: %s\n", sub)
|
||||
doctorUsage()
|
||||
@@ -87,6 +89,7 @@ Subcommands:
|
||||
copied-code Detecta cuerpos de funcion del registry copiados en apps sin import (issue 0085k)
|
||||
capabilities Drift entre docs/capabilities/INDEX.md, tags de funciones, y paginas <grupo>.md (issue 0086)
|
||||
app-location Detecta artefactos (apps/analysis) en carpetas de lenguaje (cpp/apps/, etc.) - issue 0096
|
||||
modules Drift entre uses_modules (app.md) y fn_module_<x> link calls (CMakeLists.txt) - issue 0097
|
||||
|
||||
Flags:
|
||||
--json Salida JSON (para scripting/agentes)
|
||||
@@ -539,3 +542,49 @@ func doctorAppLocation(root string, jsonOut bool) {
|
||||
w.Flush()
|
||||
fmt.Printf("\n%d violation(s): move artefact to apps/<name>/ or projects/<p>/apps/<name>/ (issue 0096).\n", len(violations))
|
||||
}
|
||||
|
||||
func doctorModules(root string, jsonOut bool) {
|
||||
checks, err := infra.AuditModulesDrift(root)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if jsonOut {
|
||||
emit(checks)
|
||||
return
|
||||
}
|
||||
|
||||
bad := 0
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||
fmt.Fprintln(w, "STATUS\tAPP\tDECLARED\tLINKED\tMISSING\tEXTRA")
|
||||
for _, c := range checks {
|
||||
status := "OK"
|
||||
if !c.OK {
|
||||
status = "DRIFT"
|
||||
bad++
|
||||
}
|
||||
decl := strings.Join(c.Declared, ",")
|
||||
if decl == "" {
|
||||
decl = "-"
|
||||
}
|
||||
link := strings.Join(c.Linked, ",")
|
||||
if link == "" {
|
||||
link = "-"
|
||||
}
|
||||
missing := strings.Join(c.MissingLinks, ",")
|
||||
if missing == "" {
|
||||
missing = "-"
|
||||
}
|
||||
extra := strings.Join(c.ExtraLinks, ",")
|
||||
if extra == "" {
|
||||
extra = "-"
|
||||
}
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", status, c.AppID, decl, link, missing, extra)
|
||||
}
|
||||
w.Flush()
|
||||
fmt.Printf("\n%d/%d apps with module drift.\n", bad, len(checks))
|
||||
if bad > 0 {
|
||||
fmt.Println("Fix: align uses_modules in app.md with target_link_libraries(fn_module_*) in CMakeLists.txt.")
|
||||
}
|
||||
}
|
||||
|
||||
+37
-2
@@ -143,8 +143,8 @@ func cmdIndex() {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Indexed %d functions, %d types, %d apps, %d analysis, %d projects, %d vaults, %d unit_tests\n",
|
||||
result.Functions, result.Types, result.Apps, result.Analysis, result.Projects, result.Vaults, result.UnitTests)
|
||||
fmt.Printf("Indexed %d functions, %d types, %d apps, %d analysis, %d projects, %d vaults, %d modules, %d unit_tests\n",
|
||||
result.Functions, result.Types, result.Apps, result.Analysis, result.Projects, result.Vaults, result.Modules, result.UnitTests)
|
||||
for _, e := range result.ValidationErrors {
|
||||
fmt.Fprintf(os.Stderr, " INVALID: %s\n", e)
|
||||
}
|
||||
@@ -420,10 +420,42 @@ func cmdShow(args []string) {
|
||||
return
|
||||
}
|
||||
|
||||
m, errM := db.GetModule(id)
|
||||
if errM == nil {
|
||||
printModule(m)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "not found: %s\n", id)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func printModule(m *registry.Module) {
|
||||
fmt.Printf("ID: %s\n", m.ID)
|
||||
fmt.Printf("Name: %s\n", m.Name)
|
||||
fmt.Printf("Version: %s\n", m.Version)
|
||||
fmt.Printf("Lang: %s\n", m.Lang)
|
||||
fmt.Printf("Description: %s\n", m.Description)
|
||||
if len(m.Members) > 0 {
|
||||
fmt.Printf("Members: %s\n", strings.Join(m.Members, ", "))
|
||||
}
|
||||
if len(m.Tags) > 0 {
|
||||
fmt.Printf("Tags: %s\n", strings.Join(m.Tags, ", "))
|
||||
}
|
||||
if m.DirPath != "" {
|
||||
fmt.Printf("DirPath: %s\n", m.DirPath)
|
||||
}
|
||||
if m.RepoURL != "" {
|
||||
fmt.Printf("RepoURL: %s\n", m.RepoURL)
|
||||
}
|
||||
if m.Documentation != "" {
|
||||
fmt.Printf("\nDocumentation:\n%s\n", m.Documentation)
|
||||
}
|
||||
if m.Notes != "" {
|
||||
fmt.Printf("\nNotes:\n%s\n", m.Notes)
|
||||
}
|
||||
}
|
||||
|
||||
func printFunction(f *registry.Function) {
|
||||
fmt.Printf("ID: %s\n", f.ID)
|
||||
fmt.Printf("Name: %s\n", f.Name)
|
||||
@@ -540,6 +572,9 @@ func printApp(a *registry.App) {
|
||||
if len(a.UsesTypes) > 0 {
|
||||
fmt.Printf("Uses types: %s\n", strings.Join(a.UsesTypes, ", "))
|
||||
}
|
||||
if len(a.UsesModules) > 0 {
|
||||
fmt.Printf("Uses mods: %s\n", strings.Join(a.UsesModules, ", "))
|
||||
}
|
||||
if a.Notes != "" {
|
||||
fmt.Printf("\nNotes:\n%s\n", a.Notes)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ type syncRequest struct {
|
||||
Analysis []registry.Analysis `json:"analysis"`
|
||||
Projects []registry.Project `json:"projects"`
|
||||
Vaults []registry.Vault `json:"vaults"`
|
||||
Modules []registry.Module `json:"modules"`
|
||||
Proposals []registry.Proposal `json:"proposals"`
|
||||
Locations []registry.PcLocation `json:"locations"`
|
||||
}
|
||||
@@ -37,6 +38,7 @@ type syncResponse struct {
|
||||
Analysis []registry.Analysis `json:"analysis"`
|
||||
Projects []registry.Project `json:"projects"`
|
||||
Vaults []registry.Vault `json:"vaults"`
|
||||
Modules []registry.Module `json:"modules"`
|
||||
Proposals []registry.Proposal `json:"proposals"`
|
||||
Locations []registry.PcLocation `json:"locations"`
|
||||
Stats struct {
|
||||
@@ -100,6 +102,7 @@ func syncPushPull() {
|
||||
analysis, _ := db.AllAnalysis()
|
||||
projects, _ := db.ListAllProjects()
|
||||
vaults, _ := db.AllVaults()
|
||||
modules, _ := db.AllModules()
|
||||
proposals, _ := db.AllProposals()
|
||||
|
||||
// 2. Scan local directories and build pc_locations
|
||||
@@ -112,6 +115,7 @@ func syncPushPull() {
|
||||
Analysis: analysis,
|
||||
Projects: projects,
|
||||
Vaults: vaults,
|
||||
Modules: modules,
|
||||
Proposals: proposals,
|
||||
Locations: locations,
|
||||
}
|
||||
@@ -203,6 +207,14 @@ func applySync(db *registry.DB, resp syncResponse) int {
|
||||
}
|
||||
}
|
||||
|
||||
for _, m := range resp.Modules {
|
||||
existing, err := db.GetModule(m.ID)
|
||||
if err != nil || m.UpdatedAt.After(existing.UpdatedAt) {
|
||||
db.InsertModule(&m)
|
||||
imported++
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range resp.Proposals {
|
||||
existing, err := db.GetProposal(p.ID)
|
||||
if err != nil || p.UpdatedAt.After(existing.UpdatedAt) {
|
||||
@@ -329,6 +341,7 @@ func syncStatus() {
|
||||
analysis, _ := db.AllAnalysis()
|
||||
projects, _ := db.ListAllProjects()
|
||||
vaults, _ := db.AllVaults()
|
||||
modules, _ := db.AllModules()
|
||||
proposals, _ := db.AllProposals()
|
||||
locs, _ := db.ListAllPcLocations()
|
||||
|
||||
@@ -337,6 +350,7 @@ func syncStatus() {
|
||||
fmt.Printf(" analysis: %d\n", len(analysis))
|
||||
fmt.Printf(" projects: %d\n", len(projects))
|
||||
fmt.Printf(" vaults: %d\n", len(vaults))
|
||||
fmt.Printf(" modules: %d\n", len(modules))
|
||||
fmt.Printf(" proposals: %d\n", len(proposals))
|
||||
fmt.Printf(" locations: %d\n", len(locs))
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"fn-registry/functions/browser"
|
||||
)
|
||||
|
||||
func main() {
|
||||
port := flag.Int("port", 9222, "CDP debug port")
|
||||
headless := flag.Bool("headless", false, "headless mode")
|
||||
chromePath := flag.String("chrome-path", "", "explicit chrome.exe path (optional)")
|
||||
userDataDir := flag.String("user-data-dir", "", "user-data-dir (optional; WSL2 auto-translates)")
|
||||
flag.Parse()
|
||||
|
||||
pid, err := browser.ChromeLaunch(browser.ChromeLaunchOpts{
|
||||
Port: *port,
|
||||
Headless: *headless,
|
||||
ChromePath: *chromePath,
|
||||
UserDataDir: *userDataDir,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "chrome_launch failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("OK pid=%d port=%d\n", pid, *port)
|
||||
}
|
||||
Reference in New Issue
Block a user