feat(arcrun): mira wiki page with tag filter + accumulated WIP

- landing/app/mira/wiki: tag=mira-wiki list now shows all wiki paragraphs
  (depends on KBDB tag filter exposed in matrix/kbdb commit, separate repo)
- landing: app/mira hub + feed split + various WIP from prior sessions
- registry/components: claude_api / kbdb_create_block / kbdb_get / km_writer /
  platform_crypto / auth_oauth2 contracts + main.go (accumulated)
- .component-builds: pkg-lock updates + index.ts adjustments (WIP)
- .agents/specs/arcrun/frontend-redesign: design notes
- docs/test_credentials, docs/user_requirements/arcrun-landing-page: WIP docs
- cypher-executor: auth-dispatcher / wasi-shim adjustments (WIP)

Includes accumulated work from prior sessions plus the wiki UI tag-filter
update that surfaces the AI-generated wiki paragraphs at /mira/wiki.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-07 16:52:01 +08:00
parent e8fca33f80
commit 519423cb0d
127 changed files with 23909 additions and 264 deletions
@@ -0,0 +1,155 @@
// kbdb_patch_block — PATCH 一個既有 block 的部分欄位
// 對應 KBDB endpoint: PATCH /blocks/{id}
// SDD: matrix/kbdb/.agents/specs/blocks-edit-api/design.md §2
//
//go:build tinygo
package main
import (
"encoding/json"
"io"
"os"
"unsafe"
)
//go:wasmimport u6u http_request
func hostHttpRequest(
urlPtr uintptr, urlLen uint32,
methodPtr uintptr, methodLen uint32,
headersPtr uintptr, headersLen uint32,
bodyPtr uintptr, bodyLen uint32,
outPtr uintptr, outLenPtr uintptr,
) uint32
type Input struct {
KBDBUrl string `json:"kbdb_url"` // optional
APIKey string `json:"api_key"` // 必填
BlockID string `json:"block_id"` // 必填
Content *string `json:"content"` // optionalpointer 區分「未傳」vs「設空字串」)
Tags []string `json:"tags"` // optional 完整覆寫
Refs []string `json:"refs"` // optional 完整覆寫
Source *string `json:"source"` // optional
Metadata map[string]interface{} `json:"metadata_json"` // optional
}
var dummy [1]byte
func safePtr(b []byte) (uintptr, uint32) {
if len(b) == 0 {
return uintptr(unsafe.Pointer(&dummy[0])), 0
}
return uintptr(unsafe.Pointer(&b[0])), uint32(len(b))
}
func main() {
raw, err := io.ReadAll(os.Stdin)
if err != nil {
writeError("failed to read stdin: " + err.Error())
return
}
var input Input
if err := json.Unmarshal(raw, &input); err != nil {
writeError("invalid input JSON: " + err.Error())
return
}
if input.APIKey == "" {
writeError("api_key 必填")
return
}
if input.BlockID == "" {
writeError("block_id 必填")
return
}
// 至少要有一個欄位(避免 KBDB 回 400)
if input.Content == nil && input.Tags == nil && input.Refs == nil &&
input.Source == nil && input.Metadata == nil {
writeError("至少要傳一個更新欄位(content / tags / refs / source / metadata_json")
return
}
kbdbURL := input.KBDBUrl
if kbdbURL == "" {
kbdbURL = "https://kbdb.finally.click"
}
// 構造 PATCH body:只放有值的欄位(pointer 控制)
body := make(map[string]interface{})
if input.Content != nil {
body["content"] = *input.Content
}
if input.Tags != nil {
body["tags"] = input.Tags
}
if input.Refs != nil {
body["refs"] = input.Refs
}
if input.Source != nil {
body["source"] = *input.Source
}
if input.Metadata != nil {
body["metadata_json"] = input.Metadata
}
bodyBytes, _ := json.Marshal(body)
headers := map[string]string{
"Content-Type": "application/json",
"Authorization": "Bearer " + input.APIKey,
}
headersBytes, _ := json.Marshal(headers)
url := kbdbURL + "/blocks/" + input.BlockID
urlBytes := []byte(url)
methodBytes := []byte("PATCH")
outBuf := make([]byte, 65536)
var outLen uint32
urlPtr, urlLen := safePtr(urlBytes)
methodPtr, methodLen := safePtr(methodBytes)
headersPtr, headersLen := safePtr(headersBytes)
bodyPtr, bodyLenU := safePtr(bodyBytes)
result := hostHttpRequest(
urlPtr, urlLen,
methodPtr, methodLen,
headersPtr, headersLen,
bodyPtr, bodyLenU,
uintptr(unsafe.Pointer(&outBuf[0])), uintptr(unsafe.Pointer(&outLen)),
)
if result != 0 {
writeError("KBDB PATCH request failed (host_http_request returned non-zero)")
return
}
respStr := string(outBuf[:outLen])
var kbdbResp map[string]interface{}
if err := json.Unmarshal([]byte(respStr), &kbdbResp); err != nil {
writeError("KBDB returned non-JSON: " + respStr)
return
}
if _, hasErr := kbdbResp["error"]; hasErr {
out, _ := json.Marshal(map[string]interface{}{
"success": false,
"error": kbdbResp["error"],
})
os.Stdout.Write(out)
return
}
out, _ := json.Marshal(map[string]interface{}{
"success": true,
"data": kbdbResp,
})
os.Stdout.Write(out)
}
func writeError(msg string) {
out, _ := json.Marshal(map[string]interface{}{"success": false, "error": msg})
os.Stdout.Write(out)
}