This is an automated email from the ASF dual-hosted git repository. hsluoyz pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git
commit 0d7932c3f0529df0da1250ad69cc12b2c8cdec25 Author: Yang Luo <[email protected]> AuthorDate: Fri Sep 4 18:23:28 2026 +0800 fix(agents): don't count an agent's own scratch state as an install --- agent/fingerprint.go | 8 ++++++-- agent/fingerprint_load.go | 3 +++ agent/fingerprints/copilot-cli.json | 1 + agent/scan_common.go | 31 +++++++++++++++++++++++++------ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/agent/fingerprint.go b/agent/fingerprint.go index 0ae67e1..6373872 100644 --- a/agent/fingerprint.go +++ b/agent/fingerprint.go @@ -70,6 +70,10 @@ type Fingerprint struct { // StateVersionGlob matches JSONL files under the state directory whose // records carry the version of the agent that wrote them. It is the only // version an installation found by its configuration alone can report. - StateVersionGlob string `json:"stateVersionGlob,omitempty"` - LocalServer *localserver.Server `json:"localServer,omitempty"` + StateVersionGlob string `json:"stateVersionGlob,omitempty"` + // StateIgnore names the entries an agent writes on its own, without being + // installed here: what an app that embeds the agent leaves behind. A state + // directory holding nothing else is not evidence of an installation. + StateIgnore []string `json:"stateIgnore,omitempty"` + LocalServer *localserver.Server `json:"localServer,omitempty"` } diff --git a/agent/fingerprint_load.go b/agent/fingerprint_load.go index 5d971ae..905b6c1 100644 --- a/agent/fingerprint_load.go +++ b/agent/fingerprint_load.go @@ -111,6 +111,9 @@ func validateFingerprint(f Fingerprint, name string) error { if f.StateVersionGlob != "" && f.StateDir == "" { return errors.New("stateVersionGlob has no stateDir to resolve against") } + if len(f.StateIgnore) > 0 && f.StateDir == "" { + return errors.New("stateIgnore has no stateDir to resolve against") + } if err := validateLocalServer(f.LocalServer); err != nil { return err diff --git a/agent/fingerprints/copilot-cli.json b/agent/fingerprints/copilot-cli.json index 82239dc..5ee11b2 100644 --- a/agent/fingerprints/copilot-cli.json +++ b/agent/fingerprints/copilot-cli.json @@ -4,5 +4,6 @@ "installUrl": "https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli", "execName": "copilot", "stateDir": "copilot", + "stateIgnore": ["config.json", "logs"], "npmPackage": "@github/copilot" } diff --git a/agent/scan_common.go b/agent/scan_common.go index 58f3d20..7a93a20 100644 --- a/agent/scan_common.go +++ b/agent/scan_common.go @@ -189,7 +189,7 @@ func scanStateDirs(fingerprint *Fingerprint, homes []homeDir, found []Installati installations := []Installation{} for _, home := range homes { path := filepath.Join(home.path, "."+fingerprint.StateDir) - if !hasEntries(path) { + if !hasSetupEntries(path, fingerprint.StateIgnore) { continue } installations = append(installations, Installation{ @@ -203,17 +203,36 @@ func scanStateDirs(fingerprint *Fingerprint, homes []homeDir, found []Installati return installations } -// hasEntries reports a directory that holds something. An empty one is what an -// uninstall leaves behind, and is not evidence that the agent was ever set up. -func hasEntries(path string) bool { +// hasSetupEntries reports a directory that holds something the agent only +// writes once it is set up here. An empty one is what an uninstall leaves +// behind, and one holding nothing but ignored entries is what an app that +// embeds the agent leaves behind; neither is evidence of an installation. +func hasSetupEntries(path string, ignore []string) bool { dir, err := os.Open(path) if err != nil { return false } defer dir.Close() - names, err := dir.Readdirnames(1) - return err == nil && len(names) > 0 + names, err := dir.Readdirnames(-1) + if err != nil { + return false + } + for _, name := range names { + if !matchesAny(name, ignore) { + return true + } + } + return false +} + +func matchesAny(name string, candidates []string) bool { + for _, candidate := range candidates { + if strings.EqualFold(name, candidate) { + return true + } + } + return false } // dedupeInstallations returns unique installations ordered by owner and path. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
