Class ::nsmcp::CodeUpstreamTool (public)
::nx::Class ::nsmcp::CodeUpstreamTool
Defined in /usr/local/ns/tcl/nsmcp/code-upstream.tcl
- Testcases:
- No testcase defined.
Source code: :property {name code_upstream_compare} :property {permission diagnostics.code.read} :property {description {Compare an installed Tcl/NX/XOTcl procedure or method with literal source declarations in administrator-mapped public GitHub repositories. Returns immutable commit/file links, body and argument comparisons, bounded source excerpts and recent file commits. Optional configured baseline distinguishes differences from a declared installation baseline; differences alone do not prove a bug or an upstream fix. Never evaluates remote code or sends local source to GitHub. Requires enableCodeTools and enableCodeUpstream. Unsupported/dynamic/ambiguous source is unavailable, never equal.}} :property {inputSchema {{"type":"object","properties":{"name":{"type":"string"},"ref":{"type":"string","description":"Optional branch, tag or commit within the configured repository; defaults to the mapping ref."}},"required":["name"],"additionalProperties":false}}} :public method describe {} { set description [next]; set fields {} foreach {key type value} [lindex $description 2] { if {$key eq "annotations"} { set value {readOnlyHint boolean true destructiveHint boolean false openWorldHint boolean true} } lappend fields $key $type $value } return [list {} object $fields] } :method options {arguments} { set opts {name {} ref {}} foreach {key value} [:jsonArguments $arguments] {dict set opts [string range $key 1 end] $value} if {[dict get $opts name] eq {} || [string length [dict get $opts name]]>1024 || [regexp {[\x00\r\n]} [dict get $opts name]]} {error "Invalid definition name"} if {[dict get $opts ref] ne {}} {::nsmcp::codeUpstreamRef [dict get $opts ref]} return $opts } :public method validate {arguments} { if {[catch {:options $arguments} message]} {return -code error -errorcode {NSMCP RPC -32602} $message} } :method mappings {} {return [ns_config ns/server/[ns_info server]/module/nsmcp codeUpstreamMappings {}]} :method http {url accept} { set headers [ns_set create Accept $accept User-Agent nsmcp-code-upstream Accept-Encoding identity X-GitHub-Api-Version 2022-11-28] try { # No redirect following, cookies, bearer token or arbitrary URL. # Fail closed on runtimes without bounded response support. set reply [ns_http run -method GET -headers $headers -binary -timeout 3s -expire 5s -maxresponse 1MiB $url] try { if {[dict get $reply status]==200} { set bytes [dict get $reply body] set decoded [encoding convertfrom utf-8 $bytes] if {[encoding convertto utf-8 $decoded] ne $bytes} {error "invalid-upstream-utf8"} dict set reply body $decoded } return [dict remove $reply headers] } finally { if {[dict exists $reply headers]} {ns_set free [dict get $reply headers]} } } finally {ns_set free $headers} } :method get {endpoint accept} { if {![regexp {^/repos/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+/(commits|contents)(/|\?)} $endpoint] || [regexp {[\r\n]} $endpoint]} {error "invalid-github-endpoint"} if {[incr :requests]>5} {error "upstream-request-limit"} set url https://api.github.com$endpoint # Small successful-response cache, server-local and size bounded. set cache nsmcp:upstream-cache:[ns_info server] set key [ns_crypto::md string -digest sha256 -- [list $url $accept]] if {[nsv_exists $cache $key]} { set cached [nsv_get $cache $key] if {[clock seconds]-[dict get $cached at]<60} {return [dict get $cached body]} } if {[catch {:http $url $accept} reply]} {error "github-transport-failed"} set status [dict get $reply status] if {$status!=200} {error "github-http-$status"} set body [dict get $reply body] if {[string bytelength $body]>1048576} {error "github-response-too-large"} if {[llength [nsv_array names $cache]]>=16} {nsv_unset -nocomplain $cache} nsv_set $cache $key [dict create at [clock seconds] body $body] return $body } :method commit {repo ref} { set ref [ns_urlencode $ref] set sha [string trim [:get /repos/$repo/commits/$ref application/vnd.github.sha]] if {![regexp {^[a-f0-9]{40}$} $sha]} {error "invalid-github-commit"} return $sha } :method source {repo sha path} { set encoded {}; foreach segment [split $path /] {lappend encoded [ns_urlencode $segment]} return [:get /repos/$repo/contents/[join $encoded /]?ref=$sha application/vnd.github.raw+json] } :method comparison {local remote} { set args [::nsmcp::codeCanonicalArguments [dict get $remote arguments]] set body [dict get $remote body] set sameArgs [expr {[dict get $local arguments] eq $args}] set sameBody [expr {[dict get $local body] eq $body}] set normalized [expr {[dict exists $local comparisonBody] ? [dict get $local comparisonBody] : [dict get $local body]}] set normalizedSame [expr {$normalized eq $body}] return [list identical boolean [expr {$sameArgs && $sameBody}] argumentsIdentical boolean $sameArgs bodyIdentical boolean $sameBody normalizedIdentical boolean [expr {$sameArgs && $normalizedSame}] normalizedBodyIdentical boolean $normalizedSame bodySha256 string [ns_crypto::md string -digest sha256 -- $body] arguments string [string range $args 0 4095] argumentsTruncated boolean [expr {[string length $args]>4096}]] } :method selectDefinition {source name local} { set state [::nsmcp::codeStaticDefinitions $source $name] set candidates [dict get $state matches] set conditional false foreach candidate $candidates {if {[llength [dict get $candidate conditions]]} {set conditional true}} if {[llength $candidates]>1 && !$conditional} {error "upstream-definition-missing-or-ambiguous"} if {!$conditional} { return [dict create selected true selection unique-literal-declaration remote [dict merge [lindex $candidates 0] [dict remove $state matches]] candidates $candidates] } set normalizedMatches {}; set index 0 foreach candidate $candidates { set comparison {}; foreach {key type value} [:comparison $local $candidate] {dict set comparison $key $value} if {[dict get $comparison normalizedIdentical]} {lappend normalizedMatches $index} incr index } set matches $normalizedMatches if {[llength $matches]!=1} { return [dict create selected false selection unresolved-conditional-variants candidates $candidates matchingCandidates $matches] } set index [lindex $matches 0] return [dict create selected true selection matching-loaded-conditional-variant selectedCandidate $index remote [dict merge [lindex $candidates $index] [dict remove $state matches]] candidates $candidates] } :method candidates {selection local} { set rows {}; set i 0; set list [dict get $selection candidates] set budget [expr {max(1,8192/[llength $list])}] foreach candidate $list { set conditions {}; set j 0 foreach condition [dict get $candidate conditions] {lappend conditions $j string $condition; incr j} set body [dict get $candidate body] lappend rows $i object [list candidate number $i form string [dict get $candidate form] conditions array $conditions comparison object [:comparison $local $candidate] bodyExcerpt string [string range $body 0 [expr {$budget-1}]] bodyExcerptTruncated boolean [expr {[string length $body]>$budget}]] incr i } return $rows } :public method execute {context arguments} { set opts [:options $arguments] try { return [:compare $context $opts] } on error {message options} { # Return a bounded diagnostic, not SQL, transport details or remote # response bodies. Unavailable is distinct from an equal comparison. set reason upstream-comparison-unavailable if {[regexp {^(upstream-[a-z-]+|github-(?:http-[0-9]{3}|transport-failed|response-too-large)|invalid-(?:upstream-[a-z-]+|github-[a-z-]+)|local-(?:source-file-metadata-unavailable|definition-not-scripted))$} $message]} {set reason $message} return [list {} object [list available boolean false name string [dict get $opts name] server string [$context server] observedAt number [clock seconds] reason string $reason upstreamFixVerified boolean false comparisonPerformed boolean false]] } } :method compare {context opts} { set name [dict get $opts name] set doc [::nsmcp::codeMetadata $name] if {$doc eq {} && [string first :: $name]==0} {set doc [::nsmcp::codeMetadata [string range $name 2 end]]} if {![dict exists $doc script]} {error "local-source-file-metadata-unavailable"} set path [string trimleft [dict get $doc script] /] set mapping [::nsmcp::codeUpstreamMapping $path [:mappings]] set local [::nsmcp::codeLocalComparable $name $doc] set localObservedAt [clock seconds] set repo [dict get $mapping repository]; set file [dict get $mapping path] set ref [dict get $opts ref]; if {$ref eq {}} {set ref [dict get $mapping ref]} set :requests 0 set sha [:commit $repo $ref] set source [:source $repo $sha $file] set selection [:selectDefinition $source $name $local] set candidates [:candidates $selection $local] set normalizations {}; set ni 0 foreach normalization [dict get $local normalizations] {lappend normalizations $ni string $normalization; incr ni} if {![dict get $selection selected]} { return [list {} object [list available boolean false comparisonPerformed boolean false reason string upstream-conditional-variant-unresolved name string $name sourceFile string $path repository string $repo upstreamPath string $file commit string $sha upstreamUrl string https://github.com/$repo/blob/$sha/$file localDefinitionSha256 string [dict get $local definitionSha256] localNormalizations array $normalizations candidateCount number [llength [dict get $selection candidates]] candidates array $candidates conditionsEvaluated boolean false selectedCandidate null {} matchingCandidateCount number [llength [dict get $selection matchingCandidates]] upstreamFixVerified boolean false limitations string {The loaded definition does not uniquely identify one literal upstream conditional variant. Conditions were not evaluated. Candidate comparisons are evidence, not proof of the active upstream implementation or a local modification.}]] } set remote [dict get $selection remote] set comparison [:comparison $local $remote] set baseline {}; set status unknown-no-baseline if {[dict exists $mapping baselineRef] && [dict get $mapping baselineRef] ne {}} { set baseSha [:commit $repo [dict get $mapping baselineRef]] set baseSelection [:selectDefinition [:source $repo $baseSha $file] $name $local] if {[dict get $baseSelection selected]} { set baseCompare [:comparison $local [dict get $baseSelection remote]] set baseDict {}; foreach {k t v} $baseCompare {dict set baseDict $k $v} set status [expr {[dict get $baseDict normalizedIdentical] ? "matches-configured-baseline" : "differs-from-configured-baseline"}] set baseline [list available boolean true commit string $baseSha url string https://github.com/$repo/blob/$baseSha/$file comparison object $baseCompare] } else { set status unknown-baseline-variant set baseline [list available boolean false reason string upstream-conditional-variant-unresolved commit string $baseSha url string https://github.com/$repo/blob/$baseSha/$file candidates array [:candidates $baseSelection $local]] } } # File history supplies candidates, not proof that each commit changes # this procedure or fixes the diagnosed failure. set history {}; set historyAvailable true if {[catch { set records [ns_json parse [:get /repos/$repo/commits?sha=$sha&path=[ns_urlencode $file]&per_page=5 application/vnd.github+json]] set i 0 foreach record [lrange $records 0 4] { set hash [dict get $record sha] if {![regexp {^[a-f0-9]{40}$} $hash]} {error "invalid-github-commit"} set parents {}; set j 0; set parentsAvailable [dict exists $record parents] if {$parentsAvailable} { foreach parent [lrange [dict get $record parents] 0 1] { set parentSha [dict get $parent sha] if {![regexp {^[a-f0-9]{40}$} $parentSha]} {error "invalid-github-commit"} lappend parents $j object [list commit string $parentSha url string https://github.com/$repo/commit/$parentSha] incr j } } set parentsComplete [expr {$parentsAvailable && [llength [dict get $record parents]]<=2}] lappend history $i object [list commit string $hash url string https://github.com/$repo/commit/$hash message string [string range [dict get $record commit message] 0 2047] parents array $parents parentsComplete boolean $parentsComplete] incr i } }]} {set historyAvailable false} set localBody [dict get $local body]; set remoteBody [dict get $remote body] set first 0; set a [split $localBody \n]; set b [split $remoteBody \n] while {$first<min([llength $a],[llength $b]) && [lindex $a $first] eq [lindex $b $first]} {incr first} set localExcerpt [string range [join [lrange $a [expr {max(0,$first-3)}] [expr {$first+30}]] \n] 0 8191] set remoteExcerpt [string range [join [lrange $b [expr {max(0,$first-3)}] [expr {$first+30}]] \n] 0 8191] return [list {} object [list available boolean true comparisonPerformed boolean true resolutionCacheSeconds number 60 comparisonScope string literal-source localNormalizations array $normalizations localComparisonBodySha256 string [ns_crypto::md string -digest sha256 -- [dict get $local comparisonBody]] candidateCount number [llength [dict get $selection candidates]] selectedCandidate number [expr {[dict exists $selection selectedCandidate] ? [dict get $selection selectedCandidate] : 0}] candidates array $candidates conditionsEvaluated boolean false server string [$context server] observedAt number [clock seconds] name string $name sourceFile string $path repository string $repo upstreamPath string $file requestedRef string $ref commit string $sha upstreamUrl string https://github.com/$repo/blob/$sha/$file localObservedAt number $localObservedAt localArguments string [dict get $local arguments] localDefinitionSha256 string [dict get $local definitionSha256] localBodySha256 string [ns_crypto::md string -digest sha256 -- $localBody] upstreamFileSha256 string [ns_crypto::md string -digest sha256 -- $source] comparison object $comparison baseline object $baseline localModificationStatus string $status upstreamFixVerified boolean false firstDifferentBodyLine number [expr {$localBody eq $remoteBody ? 0 : $first+1}] excerptStartBodyLine number [expr {max(0,$first-3)+1}] localExcerpt string $localExcerpt upstreamExcerpt string $remoteExcerpt excerptsComplete boolean [expr {$localExcerpt eq $localBody && $remoteExcerpt eq $remoteBody}] extraction object [list form string [dict get $remote form] dynamicCommands number [dict get $remote dynamicCommands] unsupportedCommands number [dict get $remote unsupportedCommands] selection string [dict get $selection selection]] recentFileCommits array $history historyAvailable boolean $historyAvailable historyLimit number 5 diskCompared boolean false limitations string {Conditional selection identifies a unique literal definition matching loaded code; it does not evaluate guards or establish the active implementation in an upstream installation. Raw identical/bodyIdentical comparisons preserve all bytes. normalizedIdentical/normalizedBodyIdentical separately account for explicitly reported NSF-generated preambles. Equality compares exact bodies and canonical argument lists, not semantics or full object state. Generated wrappers, formatting and framework versions can cause differences. A configured baseline is an administrator assertion, not verified installation provenance. File history is bounded and not procedure-specific. Excerpts may omit other changes. An upstream fix requires connecting code changes to the observed failure; commit messages alone are insufficient. No local source was uploaded and no remote code was executed.}]] }XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)