ccnew 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +107 -0
  2. package/build/icon.ico +0 -0
  3. package/build/icon.png +0 -0
  4. package/core/apply.js +152 -0
  5. package/core/backup.js +53 -0
  6. package/core/constants.js +78 -0
  7. package/core/desktop-service.js +403 -0
  8. package/core/desktop-state.js +1021 -0
  9. package/core/index.js +1468 -0
  10. package/core/paths.js +99 -0
  11. package/core/presets.js +171 -0
  12. package/core/probe.js +70 -0
  13. package/core/routing.js +334 -0
  14. package/core/store.js +218 -0
  15. package/core/utils.js +225 -0
  16. package/core/writers/codex.js +102 -0
  17. package/core/writers/index.js +16 -0
  18. package/core/writers/openclaw.js +93 -0
  19. package/core/writers/opencode.js +91 -0
  20. package/desktop/assets/fml-icon.png +0 -0
  21. package/desktop/assets/march-mark.svg +26 -0
  22. package/desktop/main.js +275 -0
  23. package/desktop/preload.cjs +67 -0
  24. package/desktop/preload.js +49 -0
  25. package/desktop/renderer/app.js +327 -0
  26. package/desktop/renderer/index.html +130 -0
  27. package/desktop/renderer/styles.css +490 -0
  28. package/package.json +111 -0
  29. package/scripts/build-web.mjs +95 -0
  30. package/scripts/desktop-dev.mjs +90 -0
  31. package/scripts/desktop-pack-win.mjs +81 -0
  32. package/scripts/postinstall.mjs +49 -0
  33. package/scripts/prepublish-check.mjs +57 -0
  34. package/scripts/serve-site.mjs +51 -0
  35. package/site/app.js +10 -0
  36. package/site/assets/fml-icon.png +0 -0
  37. package/site/assets/march-mark.svg +26 -0
  38. package/site/index.html +337 -0
  39. package/site/styles.css +840 -0
  40. package/src/App.tsx +1557 -0
  41. package/src/components/layout/app-sidebar.tsx +103 -0
  42. package/src/components/layout/top-toolbar.tsx +44 -0
  43. package/src/components/layout/workspace-tabs.tsx +32 -0
  44. package/src/components/providers/inspector-panel.tsx +84 -0
  45. package/src/components/providers/metric-strip.tsx +26 -0
  46. package/src/components/providers/provider-editor.tsx +87 -0
  47. package/src/components/providers/provider-table.tsx +85 -0
  48. package/src/components/ui/logo-mark.tsx +32 -0
  49. package/src/features/mcp/mcp-view.tsx +45 -0
  50. package/src/features/prompts/prompts-view.tsx +40 -0
  51. package/src/features/providers/providers-view.tsx +40 -0
  52. package/src/features/providers/types.ts +26 -0
  53. package/src/features/skills/skills-view.tsx +44 -0
  54. package/src/hooks/use-control-workspace.ts +235 -0
  55. package/src/index.css +22 -0
  56. package/src/lib/client.ts +726 -0
  57. package/src/lib/query-client.ts +3 -0
  58. package/src/lib/workspace-sections.ts +34 -0
  59. package/src/main.tsx +14 -0
  60. package/src/types.ts +137 -0
  61. package/src/vite-env.d.ts +64 -0
  62. package/src-tauri/README.md +11 -0
@@ -0,0 +1,3 @@
1
+ import { QueryClient } from "@tanstack/react-query";
2
+
3
+ export const queryClient = new QueryClient();
@@ -0,0 +1,34 @@
1
+ import { BrainCircuit, MessageSquareQuote, Network, ShieldEllipsis } from "lucide-react";
2
+
3
+ export const workspaceSections = [
4
+ {
5
+ id: "providers",
6
+ label: "服务商",
7
+ eyebrow: "服务商管理",
8
+ title: "服务商控制台",
9
+ icon: Network
10
+ },
11
+ {
12
+ id: "mcp",
13
+ label: "MCP",
14
+ eyebrow: "模型上下文协议",
15
+ title: "MCP 连接器",
16
+ icon: ShieldEllipsis
17
+ },
18
+ {
19
+ id: "prompts",
20
+ label: "提示词",
21
+ eyebrow: "提示词库",
22
+ title: "提示词预设",
23
+ icon: MessageSquareQuote
24
+ },
25
+ {
26
+ id: "skills",
27
+ label: "技能",
28
+ eyebrow: "技能仓库",
29
+ title: "已安装技能",
30
+ icon: BrainCircuit
31
+ }
32
+ ] as const;
33
+
34
+ export type WorkspaceSectionId = (typeof workspaceSections)[number]["id"];
package/src/main.tsx ADDED
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import { QueryClientProvider } from "@tanstack/react-query";
4
+ import App from "./App";
5
+ import { queryClient } from "./lib/query-client";
6
+ import "./index.css";
7
+
8
+ ReactDOM.createRoot(document.getElementById("root")!).render(
9
+ <React.StrictMode>
10
+ <QueryClientProvider client={queryClient}>
11
+ <App />
12
+ </QueryClientProvider>
13
+ </React.StrictMode>
14
+ );
package/src/types.ts ADDED
@@ -0,0 +1,137 @@
1
+ export type PlatformId = "codex" | "opencode" | "openclaw";
2
+
3
+ export type PromptAppType = PlatformId | "global";
4
+
5
+ export type Provider = {
6
+ id: string;
7
+ name: string;
8
+ baseUrl: string;
9
+ model: string;
10
+ maskedApiKey: string;
11
+ isActive: boolean;
12
+ createdAt?: string | null;
13
+ updatedAt: string;
14
+ health: "unknown" | "healthy" | "degraded" | "offline";
15
+ lastLatency: number | null;
16
+ lastCheckedAt: string | null;
17
+ lastError?: string | null;
18
+ failoverRank: number | null;
19
+ failoverRole: "primary" | "fallback" | "standby";
20
+ costTier: "unknown" | "low" | "medium" | "high";
21
+ };
22
+
23
+ export type PlatformSnapshot = {
24
+ id: PlatformId;
25
+ label: string;
26
+ currentProviderName: string | null;
27
+ providerCount: number;
28
+ targetFiles: string[];
29
+ providers: Provider[];
30
+ };
31
+
32
+ export type McpServer = {
33
+ id: string;
34
+ name: string;
35
+ description: string;
36
+ homepage?: string;
37
+ tags: string[];
38
+ enabledPlatforms: PlatformId[];
39
+ bindings?: PlatformId[];
40
+ transport: "stdio" | "http";
41
+ command?: string;
42
+ args?: string[];
43
+ url?: string;
44
+ cwd?: string;
45
+ env?: Record<string, string>;
46
+ headers?: Record<string, string>;
47
+ updatedAt?: string;
48
+ };
49
+
50
+ export type PromptProfile = {
51
+ id: string;
52
+ appType: PromptAppType;
53
+ name: string;
54
+ content: string;
55
+ description: string;
56
+ enabled: boolean;
57
+ updatedAt: string;
58
+ };
59
+
60
+ export type SkillProfile = {
61
+ id: string;
62
+ name: string;
63
+ description: string;
64
+ directory: string;
65
+ enabledPlatforms: PlatformId[];
66
+ };
67
+
68
+ export type SkillRepo = {
69
+ id: string;
70
+ owner: string;
71
+ name: string;
72
+ branch: string;
73
+ enabled: boolean;
74
+ };
75
+
76
+ export type PresetProfile = {
77
+ name: string;
78
+ providerName: string;
79
+ commonBaseUrl: string;
80
+ openclawBaseUrl: string;
81
+ model: string;
82
+ source: "builtin" | "custom";
83
+ readonly: boolean;
84
+ createdAt: string | null;
85
+ updatedAt: string | null;
86
+ };
87
+
88
+ export type RoutingProviderState = {
89
+ providerId: string;
90
+ failoverRank: number;
91
+ role: "primary" | "fallback" | "standby";
92
+ health: "unknown" | "healthy" | "degraded" | "offline";
93
+ lastLatency: number | null;
94
+ lastCheckedAt: string | null;
95
+ lastError?: string | null;
96
+ consecutiveFailures: number;
97
+ costTier: "unknown" | "low" | "medium" | "high";
98
+ };
99
+
100
+ export type PlatformRouting = {
101
+ platform: PlatformId;
102
+ proxyMode: "direct" | "provider-base-url";
103
+ autoFailover: boolean;
104
+ failoverThresholdMs: number;
105
+ maxConsecutiveFailures: number;
106
+ primaryProviderId: string | null;
107
+ fallbackProviderIds: string[];
108
+ lastFailoverAt: string | null;
109
+ providerStates: RoutingProviderState[];
110
+ };
111
+
112
+ export type RoutingSnapshot = {
113
+ budgetMode: "tiered" | "manual";
114
+ monthlyBudgetUsd: number | null;
115
+ platforms: PlatformRouting[];
116
+ };
117
+
118
+ export type AppSnapshot = {
119
+ appName: string;
120
+ version: string;
121
+ generatedAt: string;
122
+ models: string[];
123
+ platforms: PlatformSnapshot[];
124
+ mcpServers: McpServer[];
125
+ prompts: PromptProfile[];
126
+ skills: SkillProfile[];
127
+ skillRepos: SkillRepo[];
128
+ presets: PresetProfile[];
129
+ routing: RoutingSnapshot;
130
+ };
131
+
132
+ export type ProbeResult = {
133
+ baseUrl: string;
134
+ ok: boolean;
135
+ latency: number;
136
+ error?: string;
137
+ };
@@ -0,0 +1,64 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ import type { PlatformId } from "./types";
4
+
5
+ type DesktopSnapshotModel = string | { id?: string };
6
+
7
+ type DesktopBridgePayload = {
8
+ platform?: PlatformId;
9
+ providerId?: string;
10
+ nameOrId?: string;
11
+ baseUrl?: string;
12
+ apiKey?: string;
13
+ model?: string;
14
+ serverId?: string;
15
+ promptId?: string;
16
+ repoId?: string;
17
+ skillId?: string;
18
+ targetPath?: string;
19
+ [key: string]: unknown;
20
+ };
21
+
22
+ type MarchDesktopBridge = {
23
+ getSnapshot: () => Promise<{
24
+ appName?: string;
25
+ version?: string;
26
+ generatedAt?: string;
27
+ models?: DesktopSnapshotModel[];
28
+ platforms: unknown[];
29
+ mcpServers?: unknown[];
30
+ prompts?: unknown[];
31
+ skills?: unknown[];
32
+ skillRepos?: unknown[];
33
+ presets?: unknown[];
34
+ routing?: unknown;
35
+ }>;
36
+ saveProvider: (payload: DesktopBridgePayload) => Promise<unknown>;
37
+ activateProvider: (payload: DesktopBridgePayload) => Promise<unknown>;
38
+ probePlatform: (payload: DesktopBridgePayload) => Promise<{ results?: unknown[] }>;
39
+ probeCandidate: (payload: DesktopBridgePayload) => Promise<{ result?: unknown }>;
40
+ savePreset: (payload: DesktopBridgePayload) => Promise<unknown>;
41
+ deletePreset: (payload: DesktopBridgePayload) => Promise<unknown>;
42
+ applyPreset: (payload: DesktopBridgePayload) => Promise<unknown>;
43
+ importPresets: () => Promise<unknown>;
44
+ exportPresets: () => Promise<unknown>;
45
+ updateRouting: (payload: DesktopBridgePayload) => Promise<unknown>;
46
+ toggleMcp: (payload: DesktopBridgePayload) => Promise<unknown>;
47
+ upsertMcp: (payload: DesktopBridgePayload) => Promise<unknown>;
48
+ deleteMcp: (payload: DesktopBridgePayload) => Promise<unknown>;
49
+ togglePrompt: (payload: DesktopBridgePayload) => Promise<unknown>;
50
+ upsertPrompt: (payload: DesktopBridgePayload) => Promise<unknown>;
51
+ deletePrompt: (payload: DesktopBridgePayload) => Promise<unknown>;
52
+ upsertSkill: (payload: DesktopBridgePayload) => Promise<unknown>;
53
+ deleteSkill: (payload: DesktopBridgePayload) => Promise<unknown>;
54
+ toggleSkillRepo: (payload: DesktopBridgePayload) => Promise<unknown>;
55
+ openPath: (targetPath: string | { targetPath?: string }) => Promise<{ ok?: boolean; targetPath?: string }>;
56
+ };
57
+
58
+ declare global {
59
+ interface Window {
60
+ marchDesktop?: MarchDesktopBridge;
61
+ }
62
+ }
63
+
64
+ export {};
@@ -0,0 +1,11 @@
1
+ This folder is reserved for the Tauri backend layer.
2
+
3
+ The frontend has already been moved to:
4
+
5
+ - `src/` for React + TypeScript + Vite
6
+
7
+ The legacy provider-writing core remains in:
8
+
9
+ - `core/`
10
+
11
+ Rust and Tauri CLI are not installed in the current environment yet, so the actual Tauri command layer has not been generated in this workspace.