AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A modern, local-first HTTP client & JSON editor for developers
The Postman alternative that lives in your browser. No login, no cloud, no limits.
JSON Weaver is a browser-based, local-first HTTP request builder and JSON editor. Think Postman — but without accounts, cloud sync, or paywalls. Everything stays in your browser's localStorage.
• Unlimited tabs (up to 80) with per-tab undo/redo (50 levels)
• Tab pinning, drag-reorder, rename, close
• Reopen last closed tab (Cmd+Shift+T)
• Visual dirty-state indicator for unsaved changes
• Auto-persisted to localStorage with 500ms debounce查看完整 README ↗A modern, local-first HTTP client & JSON editor for developers
The Postman alternative that lives in your browser. No login, no cloud, no limits.
Live Demo · Report Bug · Request Feature
JSON Weaver is a browser-based, local-first HTTP request builder and JSON editor. Think Postman — but without accounts, cloud sync, or paywalls. Everything stays in your browser's localStorage.
┌──────────────────────────────────────────────────────────────────────┐
│ TabBar · EnvironmentSelector · History · Collections · ⚙️ │
├──────────────────────┬───────────────────────────────────────────────┤
│ │ [GET ▾] https://{{baseUrl}}/api/users Send │
│ JSON Tree Editor ├───────────────────────────────────────────────┤
│ │ Params · Headers · Auth · Body · Scripts │
│ ► { } root │ │
│ ├─ "id": 1 ├───────────────────────────────────────────────┤
│ ├─ "name": "…" │ 200 OK · 142ms · 1.4KB │
│ └─ "tags": […] │ Response · Assertions · Diff · Code │
│ │ │
└──────────────────────┴───────────────────────────────────────────────┘
Cmd+Shift+T)localStorage with 500ms debounce| Feature | Description |
|---|---|
| Visual editing | Click-to-edit tree with expand/collapse |
| Type conversion | string ↔ number ↔ boolean ↔ null ↔ object ↔ array |
| Tree operations | Add, delete, duplicate (deep clone with new UUIDs) |
| Undo / Redo | Full history per tab |
| JSONPath search | Filter nodes using $.path.to[*].value expressions |
| Import / Export | Load/save .json files directly |
| Context menu | Right-click for all operations |
Modes: HTTP · GraphQL · WebSocket
Authentication:
Body types:
application/x-www-form-urlencodedAdvanced:
curl command to auto-populate the formCollections:
Environments:
dev, staging, prod, …{{baseUrl}}, {{apiKey}}, {{userId}}Generate ready-to-run code from any request:
# cURL
curl -X POST 'https://api.example.com/users' \
-H 'Authorization: Bearer {{token}}' \
-H 'Content-Type: application/json' \
-d '{"name":"Alice"}'
// Fetch API (ES6)
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: { 'Authorization': 'Bearer {{token}}', 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Alice' }),
});
const data = await response.json();
# Python requests
import requests
response = requests.post(
'https://api.example.com/users',
headers={'Authorization': 'Bearer {{token}}'},
json={'name': 'Alice'},
)
Also supports: Axios
| Tool | Shortcut | Description |
|---|---|---|
| Command Palette | Cmd+K | Quick access to all commands |
| Request History | — | Last 100 requests, searchable, pinnable |
| Schema Validator | — | Validate request/response against OpenAPI schema |
| Types Generator | — | Generate TypeScript interfaces from JSON/schema |
| Diff Viewer | — | Compare any two JSON responses side-by-side |
| OpenAPI Import | — | Import endpoints from Swagger / OpenAPI 3.0 |
| Collection Runner | — | Execute a batch of requests in sequence |
| Onboarding Tour | — | Interactive step-by-step walkthrough |
flowchart TD
A[User] -->|interacts| B[Index.tsx\n3-panel layout]
B --> C[useTabs\nCentral state]
B --> D[useCollections]
B --> E[useEnvironments]
B --> F[useHistory]
C -->|dispatch| G[JsonEditorPanel\nLeft panel]
C -->|dispatch| H[RequestBuilder\nTop-right panel]
C -->|read| I[JsonPreview\nBottom-right panel]
H -->|HTTP fetch| J[External API]
J -->|response| H
C -->|500ms debounce| K[(localStorage)]
D --> K
E --> K
F --> K
stateDiagram-v2
[*] --> LoadFromStorage : App Start
LoadFromStorage --> ActiveTab : hydrate
ActiveTab --> Editing : user edits tree
Editing --> ActiveTab : dispatch action
ActiveTab --> UndoRedo : Cmd+Z / Cmd+Y
UndoRedo --> ActiveTab : restore snapshot
ActiveTab --> SendRequest : click Send
SendRequest --> ReceivingResponse : HTTP fetch / WS
ReceivingResponse --> ActiveTab : update response state
ActiveTab --> Persist : debounce 500ms
Persist --> localStorage : saveTabs
classDiagram
class JsonNode {
+string id
+string|null key
+NodeType type
+string|number|boolean|null value
+JsonNode[] children
}
class Tab {
+string id
+string name
+JsonNode tree
+RequestConfig request
+boolean pinned
+string savedFingerprint
}
class RequestConfig {
+string url
+HttpMethod method
+HttpHeader[] headers
+QueryParam[] params
+AuthConfig auth
+string body
+string mode
}
class AuthConfig {
+type: bearer|basic|apikey|none
+token string
+username string
+password string
}
Tab --> JsonNode : tree
Tab --> RequestConfig : request
RequestConfig --> AuthConfig : auth
JsonNode --> JsonNode : children
graph LR
subgraph State
UT[useTabs]
UC[useCollections]
UE[useEnvironments]
UH[useHistory]
end
subgraph Lib
JTU[json-tree-utils]
CG[codegen]
CI[curl-import]
EU[env-utils]
GU[graphql-utils]
end
subgraph UI
JEP[JsonEditorPanel]
RB[RequestBuilder]
JP[JsonPreview]
WS[Workspace tools]
end
UT --> JEP
UT --> RB
UT --> JP
UC --> WS
UE --> WS
UH --> WS
JTU --> UT
CG --> RB
CI --> RB
EU --> RB
GU --> RB
npm install -g pnpm
# 1. Clone
git clone https://github.com/your-username/json-weaver.git
cd json-weaver
# 2. Install
pnpm install
# 3. Start dev server → http://localhost:8080
pnpm dev
pnpm build
pnpm preview
https://jsonplaceholder.typicode.com/posts/1
GETbaseUrl = jsonplaceholder.typicode.com
apiKey = my-secret-key
https://{{baseUrl}}/posts/1
Authorization: Bearer {{apiKey}}
curl -X POST https://api.example.com/data \
-H "Authorization: Bearer mytoken" \
-d '{"key":"value"}'
After building any request, click Code in the response panel to export as:
curl shell commandfetch (ES6 async/await)axiosPython requestsGet User by ID)| Layer | Technology | Version |
|---|---|---|
| Framework | React | 18.3 |
| Language | TypeScript | 5.8 |
| Bundler | Vite | 5.4 |
| Styling | Tailwind CSS | 3.4 |
| Components | shadcn/ui + Radix UI | latest |
| Layout | react-resizable-panels | 2.1 |
| Routing | React Router | 6.30 |
| Server state | TanStack Query | 5.83 |
| Validation | Zod | 3.25 |
| Forms | React Hook Form | 7.61 |
| Icons | Lucide React | 0.462 |
| Notifications | Sonner | 1.7 |
| Testing (unit) | Vitest | 3.2 |
| Testing (e2e) | Playwright | 1.58 |
| Package manager | pnpm | 10.28 |
src/
├── pages/
│ └── Index.tsx # Main workspace (3-panel layout orchestrator)
├── components/
│ ├── json-editor/
│ │ ├── JsonEditorPanel.tsx # Left panel: tree editor + controls
│ │ ├── JsonPreview.tsx # Bottom-right: JSON output viewer
│ │ ├── JsonTreeNode.tsx # Recursive node renderer
│ │ └── RequestBuilder/
│ │ ├── index.tsx # Main orchestrator
│ │ ├── constants.ts # HTTP methods, headers, GraphQL templates
│ │ ├── types.ts # RequestTab, RequestBuilderProps
│ │ ├── utils.ts # applyJsonPath, evaluateAssertions, …
│ │ ├── hooks/
│ │ │ ├── useRequestSender.ts # fetch + auth + CORS proxy
│ │ │ ├── useGraphqlSchema.ts # schema introspection + WS subs
│ │ │ ├── useRawBody.ts # raw body formatting/validation
│ │ │ ├── useFormBody.ts # multipart form-data
│ │ │ └── useWebSocket.ts # WebSocket connection management
│ │ └── components/
│ │ ├── UrlBar.tsx # HTTP/GQL/WS toggle + method + URL
│ │ ├── AuthPanel.tsx # Bearer / Basic / API-Key config
│ │ ├── BodyTab.tsx # Tree/Raw/Form body editor
│ │ ├── ResponsePanel.tsx # Status, metrics, assertions, diff
│ │ ├── GraphqlQueryTab.tsx # Query + variables + subscriptions
│ │ ├── CurlImportDialog.tsx # Parse curl → RequestConfig
│ │ └── KeyValueEditor.tsx # Reusable params/headers grid
│ └── workspace/
│ ├── TabBar.tsx # Multi-tab UI with drag-reorder
│ ├── EnvironmentSelector.tsx # Env variables switcher
│ ├── CollectionsSidebar.tsx # Collections browser
│ ├── HistoryDrawer.tsx # Request history (100 items)
│ ├── CodeGenerator.tsx # Multi-language code export
│ ├── DiffViewer.tsx # Side-by-side JSON diff
│ ├── SchemaValidator.tsx # OpenAPI schema validation
│ ├── CollectionRunner.tsx # Batch request execution
│ └── CommandPalette.tsx # Cmd+K quick commands
├── hooks/
│ ├── use-tabs.ts # Central state: tabs, undo/redo, persistence
│ ├── use-collections.ts # Collections CRUD + localStorage
│ ├── use-environments.ts # Environments CRUD + active env
│ └── use-history.ts # 100-item request history stack
├── lib/
│ ├── json-tree-utils.ts # All tree operations (fully immutable)
│ ├── codegen.ts # curl / fetch / axios / python generator
│ ├── curl-import.ts # Parse curl strings → RequestConfig
│ ├── env-utils.ts # {{var}} substitution engine
│ ├── graphql-utils.ts # Schema introspection + TypeScript type gen
│ └── storage.ts # localStorage helpers with debounce
└── types/
└── json-tree.ts # Complete type system (JsonNode, RequestConfig, …)
pnpm dev # Start dev server → http://localhost:8080
pnpm build # Production build
pnpm build:dev # Dev build (with source maps)
pnpm test # Run unit tests (Vitest)
pnpm test:watch # Watch mode
pnpm test:visual # Visual regression (Playwright)
pnpm test:visual:update # Update visual snapshots
pnpm lint # ESLint check
pnpm format # Prettier format
pnpm preview # Preview production build
updateNodeInTree(), never mutate state directlynode.id, not array index@/ maps to src/ throughout the codebasejw-tabs, jw-collections, jw-environments, jw-historypnpm only (npm/yarn not supported)// 1. Add utility in src/lib/json-tree-utils.ts
export function myOperation(root: JsonNode, id: string): JsonNode {
return updateNodeInTree(root, id, (node) => ({
...node,
// your immutable changes here
}));
}
// 2. Add action in the useTabs reducer (src/hooks/use-tabs.ts)
case 'MY_ACTION':
return myOperation(state.tree, action.id);
// 3. Dispatch from any component
const { dispatch } = useTabs();
dispatch({ type: 'MY_ACTION', id: nodeId });
Built with React, TypeScript, and a lot of localStorage