@zmzai/agent-framework 0.1.0

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 (126) hide show
  1. package/dist/adapters/fs-workspace.d.ts +7 -0
  2. package/dist/adapters/fs-workspace.d.ts.map +1 -0
  3. package/dist/adapters/fs-workspace.js +91 -0
  4. package/dist/adapters/fs-workspace.js.map +1 -0
  5. package/dist/adapters/index.d.ts +46 -0
  6. package/dist/adapters/index.d.ts.map +1 -0
  7. package/dist/adapters/index.js +14 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/adapters/openai-provider.d.ts +17 -0
  10. package/dist/adapters/openai-provider.d.ts.map +1 -0
  11. package/dist/adapters/openai-provider.js +116 -0
  12. package/dist/adapters/openai-provider.js.map +1 -0
  13. package/dist/adapters/subprocess-sandbox.d.ts +7 -0
  14. package/dist/adapters/subprocess-sandbox.d.ts.map +1 -0
  15. package/dist/adapters/subprocess-sandbox.js +91 -0
  16. package/dist/adapters/subprocess-sandbox.js.map +1 -0
  17. package/dist/adapters/workspace-edit.d.ts +19 -0
  18. package/dist/adapters/workspace-edit.d.ts.map +1 -0
  19. package/dist/adapters/workspace-edit.js +36 -0
  20. package/dist/adapters/workspace-edit.js.map +1 -0
  21. package/dist/cli.d.ts +3 -0
  22. package/dist/cli.d.ts.map +1 -0
  23. package/dist/cli.js +191 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/core/agent/loader.d.ts +17 -0
  26. package/dist/core/agent/loader.d.ts.map +1 -0
  27. package/dist/core/agent/loader.js +148 -0
  28. package/dist/core/agent/loader.js.map +1 -0
  29. package/dist/core/agent/plugin.d.ts +59 -0
  30. package/dist/core/agent/plugin.d.ts.map +1 -0
  31. package/dist/core/agent/plugin.js +125 -0
  32. package/dist/core/agent/plugin.js.map +1 -0
  33. package/dist/core/agent/registry.d.ts +45 -0
  34. package/dist/core/agent/registry.d.ts.map +1 -0
  35. package/dist/core/agent/registry.js +98 -0
  36. package/dist/core/agent/registry.js.map +1 -0
  37. package/dist/core/agent/resolver.d.ts +16 -0
  38. package/dist/core/agent/resolver.d.ts.map +1 -0
  39. package/dist/core/agent/resolver.js +2 -0
  40. package/dist/core/agent/resolver.js.map +1 -0
  41. package/dist/core/events/bus.d.ts +30 -0
  42. package/dist/core/events/bus.d.ts.map +1 -0
  43. package/dist/core/events/bus.js +112 -0
  44. package/dist/core/events/bus.js.map +1 -0
  45. package/dist/core/events/manifest.d.ts +117 -0
  46. package/dist/core/events/manifest.d.ts.map +1 -0
  47. package/dist/core/events/manifest.js +69 -0
  48. package/dist/core/events/manifest.js.map +1 -0
  49. package/dist/core/permission/engine.d.ts +84 -0
  50. package/dist/core/permission/engine.d.ts.map +1 -0
  51. package/dist/core/permission/engine.js +131 -0
  52. package/dist/core/permission/engine.js.map +1 -0
  53. package/dist/core/permission/ruleset.d.ts +30 -0
  54. package/dist/core/permission/ruleset.d.ts.map +1 -0
  55. package/dist/core/permission/ruleset.js +85 -0
  56. package/dist/core/permission/ruleset.js.map +1 -0
  57. package/dist/core/runtime/compaction.d.ts +59 -0
  58. package/dist/core/runtime/compaction.d.ts.map +1 -0
  59. package/dist/core/runtime/compaction.js +108 -0
  60. package/dist/core/runtime/compaction.js.map +1 -0
  61. package/dist/core/runtime/lease-recovery.d.ts +45 -0
  62. package/dist/core/runtime/lease-recovery.d.ts.map +1 -0
  63. package/dist/core/runtime/lease-recovery.js +112 -0
  64. package/dist/core/runtime/lease-recovery.js.map +1 -0
  65. package/dist/core/runtime/loop-guard.d.ts +51 -0
  66. package/dist/core/runtime/loop-guard.d.ts.map +1 -0
  67. package/dist/core/runtime/loop-guard.js +90 -0
  68. package/dist/core/runtime/loop-guard.js.map +1 -0
  69. package/dist/core/runtime/pi-bridge.d.ts +53 -0
  70. package/dist/core/runtime/pi-bridge.d.ts.map +1 -0
  71. package/dist/core/runtime/pi-bridge.js +259 -0
  72. package/dist/core/runtime/pi-bridge.js.map +1 -0
  73. package/dist/core/runtime/runner.d.ts +127 -0
  74. package/dist/core/runtime/runner.d.ts.map +1 -0
  75. package/dist/core/runtime/runner.js +614 -0
  76. package/dist/core/runtime/runner.js.map +1 -0
  77. package/dist/core/session/ids.d.ts +7 -0
  78. package/dist/core/session/ids.d.ts.map +1 -0
  79. package/dist/core/session/ids.js +18 -0
  80. package/dist/core/session/ids.js.map +1 -0
  81. package/dist/core/session/jsonl-store.d.ts +14 -0
  82. package/dist/core/session/jsonl-store.d.ts.map +1 -0
  83. package/dist/core/session/jsonl-store.js +142 -0
  84. package/dist/core/session/jsonl-store.js.map +1 -0
  85. package/dist/core/session/store.d.ts +25 -0
  86. package/dist/core/session/store.d.ts.map +1 -0
  87. package/dist/core/session/store.js +2 -0
  88. package/dist/core/session/store.js.map +1 -0
  89. package/dist/core/session/types.d.ts +142 -0
  90. package/dist/core/session/types.d.ts.map +1 -0
  91. package/dist/core/session/types.js +2 -0
  92. package/dist/core/session/types.js.map +1 -0
  93. package/dist/core/tools/adapter.d.ts +33 -0
  94. package/dist/core/tools/adapter.d.ts.map +1 -0
  95. package/dist/core/tools/adapter.js +87 -0
  96. package/dist/core/tools/adapter.js.map +1 -0
  97. package/dist/core/tools/builtins.d.ts +13 -0
  98. package/dist/core/tools/builtins.d.ts.map +1 -0
  99. package/dist/core/tools/builtins.js +219 -0
  100. package/dist/core/tools/builtins.js.map +1 -0
  101. package/dist/core/tools/context.d.ts +136 -0
  102. package/dist/core/tools/context.d.ts.map +1 -0
  103. package/dist/core/tools/context.js +2 -0
  104. package/dist/core/tools/context.js.map +1 -0
  105. package/dist/core/tools/def.d.ts +27 -0
  106. package/dist/core/tools/def.d.ts.map +1 -0
  107. package/dist/core/tools/def.js +2 -0
  108. package/dist/core/tools/def.js.map +1 -0
  109. package/dist/core/tools/qa-check.d.ts +30 -0
  110. package/dist/core/tools/qa-check.d.ts.map +1 -0
  111. package/dist/core/tools/qa-check.js +50 -0
  112. package/dist/core/tools/qa-check.js.map +1 -0
  113. package/dist/core/tools/task.d.ts +8 -0
  114. package/dist/core/tools/task.d.ts.map +1 -0
  115. package/dist/core/tools/task.js +33 -0
  116. package/dist/core/tools/task.js.map +1 -0
  117. package/dist/index.d.ts +38 -0
  118. package/dist/index.d.ts.map +1 -0
  119. package/dist/index.js +28 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/server/create-server.d.ts +51 -0
  122. package/dist/server/create-server.d.ts.map +1 -0
  123. package/dist/server/create-server.js +29 -0
  124. package/dist/server/create-server.js.map +1 -0
  125. package/openapi.yaml +239 -0
  126. package/package.json +32 -0
package/dist/cli.js ADDED
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+ /** zmzai-agent CLI (M5 §5): run the framework standalone with zero product
3
+ * coupling — JSONL store, FS workspace, subprocess sandbox, OpenAI provider.
4
+ *
5
+ * zmzai-agent serve [--port 3011] [--data-dir ./.fw-data] [--workspace ./ws]
6
+ * zmzai-agent run "<prompt>" [--workspace ./ws] [--agent default] [--model gpt-4o]
7
+ */
8
+ import { createServer, createJsonlSessionStore, createMemoryEventLog, subscribeEventLog } from "./index.js";
9
+ import { createFsWorkspaceFiles } from "./adapters/fs-workspace.js";
10
+ import { createOpenAiModelProvider } from "./adapters/openai-provider.js";
11
+ import { createSubprocessSandbox } from "./adapters/subprocess-sandbox.js";
12
+ function parseArgs(argv) {
13
+ const out = {};
14
+ for (let index = 0; index < argv.length; index++) {
15
+ const arg = argv[index];
16
+ if (arg.startsWith("--")) {
17
+ const key = arg.slice(2);
18
+ const next = argv[index + 1];
19
+ out[key] = next && !next.startsWith("--") ? next : "true";
20
+ if (next && !next.startsWith("--"))
21
+ index++;
22
+ }
23
+ }
24
+ return out;
25
+ }
26
+ function buildServer(args) {
27
+ const dataDir = args["data-dir"] ?? "./.fw-data";
28
+ const workspaceRoot = args["workspace"] ?? "./.fw-workspace";
29
+ const store = createJsonlSessionStore({ dataDir });
30
+ const eventLog = createMemoryEventLog();
31
+ const modelProvider = createOpenAiModelProvider();
32
+ const workspaceFor = () => createFsWorkspaceFiles({ root: workspaceRoot });
33
+ return createServer({
34
+ store,
35
+ eventLog,
36
+ modelProvider,
37
+ workspaceFor,
38
+ sandbox: createSubprocessSandbox(),
39
+ subagentDepth: 1,
40
+ });
41
+ }
42
+ async function runOnce(args) {
43
+ const prompt = args._prompt ?? args.prompt;
44
+ if (!prompt) {
45
+ console.error("用法: zmzai-agent run \"<prompt>\" [--workspace ./ws] [--agent default]");
46
+ process.exit(1);
47
+ }
48
+ const fw = buildServer(args);
49
+ const session = await fw.createSession({
50
+ userId: "cli",
51
+ workspaceId: "cli",
52
+ agent: args.agent ?? "default",
53
+ model: { providerId: "openai", modelId: args.model ?? process.env.OPENAI_MODEL ?? "gpt-4o" },
54
+ });
55
+ console.log(`[session] ${session.id}`);
56
+ const events = [];
57
+ const collectPromise = (async () => {
58
+ for await (const event of subscribeEventLog(fw.eventLog, session.id)) {
59
+ if (event.type === "message.part.delta") {
60
+ const delta = event.data.delta ?? "";
61
+ if (delta)
62
+ process.stdout.write(delta);
63
+ }
64
+ if (event.type === "session.status") {
65
+ const status = event.data.status;
66
+ if (status === "idle")
67
+ events.push("idle");
68
+ }
69
+ if (event.type === "session.error")
70
+ events.push("error");
71
+ }
72
+ })();
73
+ await fw.runner.prompt(session.id, { text: prompt, agent: args.agent });
74
+ // Wait for the run to settle: subscribeEventLog streams forever, so watch
75
+ // for the idle/error status events, then let the collector finish flushing.
76
+ while (!events.includes("idle") && !events.includes("error")) {
77
+ await new Promise((resolve) => setTimeout(resolve, 100));
78
+ }
79
+ await new Promise((resolve) => setTimeout(resolve, 500));
80
+ void collectPromise;
81
+ console.log(events.includes("error") ? "\n[run] 失败" : "\n[run] 完成");
82
+ process.exit(events.includes("error") ? 1 : 0);
83
+ }
84
+ async function serve(args) {
85
+ const port = Number.parseInt(args.port ?? "3011", 10);
86
+ const fw = buildServer(args);
87
+ const { createServer: createHttp } = await import("node:http");
88
+ const server = createHttp(async (req, res) => {
89
+ const url = new URL(req.url ?? "/", `http://localhost:${port}`);
90
+ const sessionIdMatch = /^\/sessions\/([^/]+)$/.exec(url.pathname);
91
+ const promptMatch = /^\/sessions\/([^/]+)\/prompt$/.exec(url.pathname);
92
+ const eventsMatch = /^\/sessions\/([^/]+)\/events$/.exec(url.pathname);
93
+ const cors = {
94
+ "access-control-allow-origin": "*",
95
+ "access-control-allow-methods": "GET, POST, OPTIONS",
96
+ "access-control-allow-headers": "content-type",
97
+ };
98
+ if (req.method === "OPTIONS") {
99
+ res.writeHead(204, cors);
100
+ res.end();
101
+ return;
102
+ }
103
+ const json = (status, body) => {
104
+ res.writeHead(status, { ...cors, "content-type": "application/json" });
105
+ res.end(JSON.stringify(body));
106
+ };
107
+ // POST /sessions { workspaceId, model, prompt? }
108
+ if (req.method === "POST" && url.pathname === "/sessions") {
109
+ const body = JSON.parse(await readBody(req));
110
+ const session = await fw.createSession({
111
+ userId: "cli",
112
+ workspaceId: body.workspaceId ?? "cli",
113
+ agent: body.agent,
114
+ model: { providerId: "openai", modelId: body.model ?? process.env.OPENAI_MODEL ?? "gpt-4o" },
115
+ });
116
+ if (body.prompt) {
117
+ await fw.runner.prompt(session.id, { text: body.prompt, agent: body.agent });
118
+ }
119
+ json(201, { session });
120
+ return;
121
+ }
122
+ // GET /sessions/:id
123
+ if (req.method === "GET" && sessionIdMatch) {
124
+ const session = await fw.store.getSession(sessionIdMatch[1]);
125
+ const messages = await fw.store.getMessages(sessionIdMatch[1]);
126
+ json(200, { session, messages });
127
+ return;
128
+ }
129
+ // POST /sessions/:id/prompt
130
+ if (req.method === "POST" && promptMatch) {
131
+ const body = JSON.parse(await readBody(req));
132
+ const result = await fw.runner.prompt(promptMatch[1], { text: body.text, agent: body.agent });
133
+ json(202, result);
134
+ return;
135
+ }
136
+ // GET /sessions/:id/events (SSE)
137
+ if (req.method === "GET" && eventsMatch) {
138
+ res.writeHead(200, {
139
+ ...cors,
140
+ "content-type": "text/event-stream",
141
+ "cache-control": "no-store",
142
+ connection: "keep-alive",
143
+ });
144
+ const sessionId = eventsMatch[1];
145
+ const controller = new AbortController();
146
+ const signal = controller.signal;
147
+ req.on("close", () => controller.abort());
148
+ (async () => {
149
+ for await (const event of subscribeEventLog(fw.eventLog, sessionId, { signal })) {
150
+ res.write(`event: ${event.type}\ndata: ${JSON.stringify(event.data)}\n\n`);
151
+ }
152
+ res.end();
153
+ })();
154
+ return;
155
+ }
156
+ json(404, { error: "not found" });
157
+ });
158
+ server.listen(port, () => {
159
+ console.log(`zmzai-agent serve: http://localhost:${port}`);
160
+ console.log(` 数据目录: ${args["data-dir"] ?? "./.fw-data"} workspace: ${args["workspace"] ?? "./.fw-workspace"}`);
161
+ });
162
+ }
163
+ function readBody(req) {
164
+ return new Promise((resolve, reject) => {
165
+ let data = "";
166
+ req.on("data", (chunk) => {
167
+ data += chunk;
168
+ });
169
+ req.on("end", () => resolve(data));
170
+ req.on("error", reject);
171
+ });
172
+ }
173
+ async function main() {
174
+ const [command, ...rest] = process.argv.slice(2);
175
+ const args = parseArgs(rest);
176
+ const positional = rest.find((arg) => !arg.startsWith("--"));
177
+ if (positional)
178
+ args["_prompt"] = positional;
179
+ if (command === "serve") {
180
+ await serve(args);
181
+ }
182
+ else if (command === "run") {
183
+ await runOnce(args);
184
+ }
185
+ else {
186
+ console.error("用法: zmzai-agent <serve|run> [options]");
187
+ process.exit(1);
188
+ }
189
+ }
190
+ void main();
191
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC5G,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC;QACzB,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC7B,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1D,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,KAAK,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,IAA4B;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,iBAAiB,CAAC;IAC7D,MAAM,KAAK,GAAG,uBAAuB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,oBAAoB,EAAE,CAAC;IACxC,MAAM,aAAa,GAAG,yBAAyB,EAAE,CAAC;IAClD,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IAC3E,OAAO,YAAY,CAAC;QAClB,KAAK;QACL,QAAQ;QACR,aAAa;QACb,YAAY;QACZ,OAAO,EAAE,uBAAuB,EAAE;QAClC,aAAa,EAAE,CAAC;KACjB,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAA4B;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;QACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC;QACrC,MAAM,EAAE,KAAK;QACb,WAAW,EAAE,KAAK;QAClB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;QAC9B,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,EAAE;KAC7F,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IACvC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;QACjC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YACrE,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;gBACxC,MAAM,KAAK,GAAI,KAAK,CAAC,IAA2B,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC7D,IAAI,KAAK;oBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACpC,MAAM,MAAM,GAAI,KAAK,CAAC,IAA4B,CAAC,MAAM,CAAC;gBAC1D,IAAI,MAAM,KAAK,MAAM;oBAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe;gBAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACxE,0EAA0E;IAC1E,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IACzD,KAAK,cAAc,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACpE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,IAA4B;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IAE/D,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClE,MAAM,WAAW,GAAG,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvE,MAAM,IAAI,GAAG;YACX,6BAA6B,EAAE,GAAG;YAClC,8BAA8B,EAAE,oBAAoB;YACpD,8BAA8B,EAAE,cAAc;SAC/C,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACzB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,IAAa,EAAE,EAAE;YAC7C,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACvE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC;QACF,iDAAiD;QACjD,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,CAA8E,CAAC;YAC1H,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC;gBACrC,MAAM,EAAE,KAAK;gBACb,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK;gBACtC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,EAAE;aAC7F,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC/E,CAAC;YACD,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,cAAc,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAE,CAAC,CAAC;YAC9D,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAE,CAAC,CAAC;YAChE,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QACD,4BAA4B;QAC5B,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,WAAW,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAqC,CAAC;YACjF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC/F,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAClB,OAAO;QACT,CAAC;QACD,iCAAiC;QACjC,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,WAAW,EAAE,CAAC;YACxC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,GAAG,IAAI;gBACP,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,UAAU;gBAC3B,UAAU,EAAE,YAAY;aACzB,CAAC,CAAC;YACH,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC;YAClC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;YACjC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1C,CAAC,KAAK,IAAI,EAAE;gBACV,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;oBAChF,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC7E,CAAC;gBACD,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC,CAAC,EAAE,CAAC;YACL,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QACvB,OAAO,CAAC,GAAG,CAAC,uCAAuC,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,IAAI,YAAY,gBAAgB,IAAI,CAAC,WAAW,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IACnH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,GAAwC;IACxD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,IAAI,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,IAAI,UAAU;QAAE,IAAI,CAAC,SAAS,CAAC,GAAG,UAAU,CAAC;IAC7C,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { WorkspaceFiles } from "../tools/context.js";
2
+ import type { AgentInfo } from "../agent/registry.js";
3
+ /** Custom agent loader (spec §6.3): workspace agents live at `.zmzai/agents/*.md`
4
+ * with YAML-ish frontmatter and the body as the system prompt. Frontmatter is
5
+ * parsed with a small zero-dependency reader (no js-yaml in the dep tree) —
6
+ * it supports the flat keys we need plus a nested `permission:` map. */
7
+ export type LoadedAgent = {
8
+ fileName: string;
9
+ agent: AgentInfo;
10
+ };
11
+ /** Loads `.zmzai/agents/*.md` from the workspace. Unreadable files are skipped
12
+ * silently; malformed files raise a descriptive error (surfaced to the user). */
13
+ export declare function loadCustomAgents(workspace: WorkspaceFiles): Promise<{
14
+ agents: AgentInfo[];
15
+ errors: string[];
16
+ }>;
17
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/agent/loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;yEAGyE;AAEzE,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAuIjE;kFACkF;AAClF,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAmBpH"}
@@ -0,0 +1,148 @@
1
+ import { rulesetFromConfig } from "../permission/ruleset.js";
2
+ const FRONTMATTER_RE = /^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n?/;
3
+ /** Minimal frontmatter parser: `key: value` scalars + one level of
4
+ * `permission:\n key: value` nesting. Values are strings, numbers, or
5
+ * booleans. Quoted strings are unwrapped. Not a general YAML parser. */
6
+ function parseFrontmatter(text) {
7
+ const match = FRONTMATTER_RE.exec(text);
8
+ if (!match)
9
+ return null;
10
+ const raw = match[1];
11
+ const body = text.slice(match[0].length);
12
+ const data = {};
13
+ const lines = raw.split(/\r?\n/);
14
+ let inPermission = false;
15
+ for (const line of lines) {
16
+ if (!line.trim() || line.trimStart().startsWith("#"))
17
+ continue;
18
+ const indent = line.length - line.trimStart().length;
19
+ if (indent === 0) {
20
+ inPermission = false;
21
+ const idx = line.indexOf(":");
22
+ if (idx === -1)
23
+ continue;
24
+ const key = line.slice(0, idx).trim();
25
+ const value = line.slice(idx + 1).trim();
26
+ if (key === "permission") {
27
+ if (value === "") {
28
+ inPermission = true;
29
+ data.permission = {};
30
+ }
31
+ else {
32
+ // inline single action: `permission: ask`
33
+ data.permission = { "*": unquote(value) };
34
+ }
35
+ continue;
36
+ }
37
+ assign(data, key, value);
38
+ }
39
+ else if (inPermission) {
40
+ const idx = line.indexOf(":");
41
+ if (idx === -1)
42
+ continue;
43
+ const key = line.slice(0, idx).trim();
44
+ const value = line.slice(idx + 1).trim();
45
+ (data.permission ??= {})[key] = unquote(value);
46
+ }
47
+ }
48
+ return { data, body };
49
+ }
50
+ function unquote(value) {
51
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
52
+ return value.slice(1, -1);
53
+ }
54
+ return value;
55
+ }
56
+ function assign(data, key, value) {
57
+ const v = unquote(value);
58
+ switch (key) {
59
+ case "name":
60
+ data.name = v;
61
+ break;
62
+ case "description":
63
+ data.description = v;
64
+ break;
65
+ case "mode":
66
+ data.mode = v;
67
+ break;
68
+ case "model":
69
+ data.model = v;
70
+ break;
71
+ case "temperature":
72
+ data.temperature = Number(v);
73
+ break;
74
+ case "top_p":
75
+ data.top_p = Number(v);
76
+ break;
77
+ case "steps":
78
+ data.steps = Number.parseInt(v, 10);
79
+ break;
80
+ case "hidden":
81
+ data.hidden = v === "true" || v === "yes";
82
+ break;
83
+ }
84
+ }
85
+ const VALID_MODES = new Set(["primary", "subagent", "all"]);
86
+ function toAgentInfo(fileName, parsed) {
87
+ const { data, body } = parsed;
88
+ const name = data.name ?? fileName.replace(/\.md$/i, "");
89
+ if (!data.description)
90
+ return { error: `agent ${fileName} 缺少必填的 description` };
91
+ const mode = data.mode && VALID_MODES.has(data.mode) ? data.mode : "primary";
92
+ if (data.mode && !VALID_MODES.has(data.mode))
93
+ return { error: `agent ${fileName} 的 mode 必须是 primary|subagent|all` };
94
+ let permission = [];
95
+ if (data.permission) {
96
+ const config = {};
97
+ for (const [key, value] of Object.entries(data.permission)) {
98
+ config[key] = value;
99
+ }
100
+ permission = rulesetFromConfig(config);
101
+ }
102
+ const model = data.model ? parseModel(data.model) : undefined;
103
+ const agent = {
104
+ name,
105
+ description: data.description,
106
+ mode,
107
+ ...(data.hidden ? { hidden: true } : {}),
108
+ ...(model ? { model } : {}),
109
+ ...(typeof data.temperature === "number" && !Number.isNaN(data.temperature) ? { temperature: data.temperature } : {}),
110
+ ...(typeof data.top_p === "number" && !Number.isNaN(data.top_p) ? { topP: data.top_p } : {}),
111
+ ...(typeof data.steps === "number" && !Number.isNaN(data.steps) ? { steps: data.steps } : {}),
112
+ prompt: body.trim(),
113
+ permission,
114
+ };
115
+ return { fileName, agent };
116
+ }
117
+ function parseModel(value) {
118
+ const idx = value.indexOf("/");
119
+ if (idx === -1)
120
+ return { providerId: "relay", modelId: value };
121
+ return { providerId: value.slice(0, idx), modelId: value.slice(idx + 1) };
122
+ }
123
+ /** Loads `.zmzai/agents/*.md` from the workspace. Unreadable files are skipped
124
+ * silently; malformed files raise a descriptive error (surfaced to the user). */
125
+ export async function loadCustomAgents(workspace) {
126
+ const all = await workspace.list().catch(() => []);
127
+ const agentFiles = all.filter((file) => /^\.zmzai\/agents\/[^/]+\.md$/i.test(file.path));
128
+ const agents = [];
129
+ const errors = [];
130
+ for (const file of agentFiles) {
131
+ const fileName = file.path.split("/").pop();
132
+ const content = await workspace.read(file.path).catch(() => null);
133
+ if (!content)
134
+ continue;
135
+ const parsed = parseFrontmatter(content.content);
136
+ if (!parsed) {
137
+ errors.push(`${fileName} 缺少 frontmatter(--- 包裹的头部)`);
138
+ continue;
139
+ }
140
+ const result = toAgentInfo(fileName, parsed);
141
+ if ("error" in result)
142
+ errors.push(result.error);
143
+ else
144
+ agents.push(result.agent);
145
+ }
146
+ return { agents, errors };
147
+ }
148
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/core/agent/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /** Agent Plugins 1.0 package reader. It intentionally implements only the
2
+ * portable package format: installation, trust, secrets, approval UX, and
3
+ * process execution remain the responsibility of the hosting product. */
4
+ export type PluginManifest = {
5
+ $schema?: string;
6
+ name: string;
7
+ version?: string;
8
+ description?: string;
9
+ author?: string;
10
+ homepage?: string;
11
+ repository?: string;
12
+ license?: string;
13
+ keywords?: string[];
14
+ extensions?: Record<string, unknown>;
15
+ };
16
+ export type PluginSkill = {
17
+ id: string;
18
+ path: string;
19
+ markdown: string;
20
+ };
21
+ export type PluginMcpServer = {
22
+ type: "stdio";
23
+ command: string;
24
+ args?: string[];
25
+ env?: Record<string, string>;
26
+ cwd?: string;
27
+ } | {
28
+ type: "streamable-http";
29
+ url: string;
30
+ headers?: Record<string, string>;
31
+ } | {
32
+ type: "sse";
33
+ url: string;
34
+ headers?: Record<string, string>;
35
+ };
36
+ export type ParsedAgentPlugin = {
37
+ root: string;
38
+ manifest: PluginManifest;
39
+ skills: PluginSkill[];
40
+ mcpServers: Record<string, PluginMcpServer>;
41
+ errors: string[];
42
+ };
43
+ export type PluginFileSystem = {
44
+ read(path: string): Promise<string | null>;
45
+ list(path: string): Promise<{
46
+ path: string;
47
+ isDirectory: boolean;
48
+ }[]>;
49
+ };
50
+ export declare function parsePluginManifest(value: unknown): PluginManifest | null;
51
+ export declare function parsePluginMcp(root: string, value: unknown): {
52
+ servers: Record<string, PluginMcpServer>;
53
+ errors: string[];
54
+ };
55
+ export declare function parseAgentPlugin(input: {
56
+ root: string;
57
+ files: PluginFileSystem;
58
+ }): Promise<ParsedAgentPlugin>;
59
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/core/agent/plugin.ts"],"names":[],"mappings":"AAEA;;0EAE0E;AAE1E,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/F;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC,CAAC;CACvE,CAAC;AA0CF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAWzE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAyC3H;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkBnH"}
@@ -0,0 +1,125 @@
1
+ import { basename, dirname, isAbsolute, normalize, relative, resolve } from "node:path";
2
+ const NAME_RE = /^(?!.*--)(?!.*\.\.)[a-z0-9](?:[a-z0-9.-]{0,62}[a-z0-9])?$/;
3
+ function json(value) {
4
+ if (!value)
5
+ return null;
6
+ try {
7
+ return JSON.parse(value);
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ }
13
+ function object(value) {
14
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
15
+ }
16
+ function stringMap(value) {
17
+ const candidate = object(value);
18
+ if (!candidate || Object.values(candidate).some((item) => typeof item !== "string"))
19
+ return undefined;
20
+ return candidate;
21
+ }
22
+ function pathInside(root, candidate) {
23
+ const target = resolve(root, candidate);
24
+ return relative(resolve(root), target) === "" || !relative(resolve(root), target).startsWith("..");
25
+ }
26
+ function validateRelativePath(root, value) {
27
+ if (!value || !value.startsWith("./") || isAbsolute(value) || !pathInside(root, value))
28
+ return undefined;
29
+ return value;
30
+ }
31
+ /** Agent Plugins 1.0 reserves these values for the hosting client. Parsing
32
+ * validates their placement but deliberately does not expand them: expansion
33
+ * happens only when a trusted host launches an authorized stdio connector. */
34
+ function validatePluginPath(root, value) {
35
+ if (!value)
36
+ return undefined;
37
+ if (value === "${PLUGIN_ROOT}" || value.startsWith("${PLUGIN_ROOT}/") || value === "${PLUGIN_DATA}" || value.startsWith("${PLUGIN_DATA}/"))
38
+ return value;
39
+ return validateRelativePath(root, value);
40
+ }
41
+ export function parsePluginManifest(value) {
42
+ const raw = object(value);
43
+ if (!raw || typeof raw.name !== "string" || !NAME_RE.test(raw.name))
44
+ return null;
45
+ const allowed = new Set(["$schema", "name", "version", "description", "author", "homepage", "repository", "license", "keywords", "extensions"]);
46
+ if (Object.keys(raw).some((key) => !allowed.has(key)))
47
+ return null;
48
+ if (raw.keywords !== undefined && (!Array.isArray(raw.keywords) || raw.keywords.some((word) => typeof word !== "string")))
49
+ return null;
50
+ if (raw.extensions !== undefined && !object(raw.extensions))
51
+ return null;
52
+ for (const key of ["$schema", "version", "description", "author", "homepage", "repository", "license"]) {
53
+ if (raw[key] !== undefined && typeof raw[key] !== "string")
54
+ return null;
55
+ }
56
+ return raw;
57
+ }
58
+ export function parsePluginMcp(root, value) {
59
+ const raw = object(value);
60
+ const entries = object(raw?.mcpServers);
61
+ const servers = {};
62
+ const errors = [];
63
+ if (!entries)
64
+ return { servers, errors };
65
+ for (const [name, candidate] of Object.entries(entries)) {
66
+ const server = object(candidate);
67
+ if (!server || typeof server.type !== "string") {
68
+ errors.push(`MCP ${name} 缺少 type`);
69
+ continue;
70
+ }
71
+ if (server.type === "stdio") {
72
+ const command = typeof server.command === "string" ? server.command : "";
73
+ const commandValid = /^[^\s]+$/.test(command) && (!command.startsWith(".") || Boolean(validateRelativePath(root, command)));
74
+ const args = Array.isArray(server.args) && server.args.every((arg) => typeof arg === "string") ? server.args : undefined;
75
+ const cwd = server.cwd === undefined ? undefined : validatePluginPath(root, typeof server.cwd === "string" ? server.cwd : undefined);
76
+ const env = stringMap(server.env);
77
+ if (!commandValid || (server.args !== undefined && !args) || (server.cwd !== undefined && !cwd) || (server.env !== undefined && !env) || env?.PLUGIN_ROOT !== undefined || env?.PLUGIN_DATA !== undefined) {
78
+ errors.push(`MCP ${name} 的 stdio 配置无效`);
79
+ continue;
80
+ }
81
+ servers[name] = { type: "stdio", command, ...(args ? { args } : {}), ...(env ? { env } : {}), ...(cwd ? { cwd } : {}) };
82
+ continue;
83
+ }
84
+ if (server.type === "streamable-http" || server.type === "sse") {
85
+ const url = typeof server.url === "string" ? server.url : "";
86
+ let parsed = null;
87
+ try {
88
+ parsed = new URL(url);
89
+ }
90
+ catch { /* validation below */ }
91
+ const remoteValid = parsed && (parsed.protocol === "https:" || ["localhost", "127.0.0.1", "::1"].includes(parsed.hostname));
92
+ const headers = stringMap(server.headers);
93
+ if (!remoteValid || (server.headers !== undefined && !headers)) {
94
+ errors.push(`MCP ${name} 的 ${server.type} 配置无效`);
95
+ continue;
96
+ }
97
+ servers[name] = { type: server.type, url, ...(headers ? { headers } : {}) };
98
+ continue;
99
+ }
100
+ errors.push(`MCP ${name} 使用了不支持的 transport: ${server.type}`);
101
+ }
102
+ return { servers, errors };
103
+ }
104
+ export async function parseAgentPlugin(input) {
105
+ const root = normalize(input.root);
106
+ const manifest = parsePluginManifest(json(await input.files.read(`${root}/plugin.json`)));
107
+ if (!manifest)
108
+ throw new Error("plugin.json 不合法或不符合 Agent Plugins 1.0 manifest 约束");
109
+ const errors = [];
110
+ const skills = [];
111
+ for (const entry of await input.files.list(`${root}/skills`).catch(() => [])) {
112
+ if (!entry.isDirectory || dirname(entry.path) !== `${root}/skills`)
113
+ continue;
114
+ const skillPath = `${entry.path}/SKILL.md`;
115
+ const markdown = await input.files.read(skillPath).catch(() => null);
116
+ if (!markdown) {
117
+ errors.push(`Skill ${basename(entry.path)} 缺少 SKILL.md`);
118
+ continue;
119
+ }
120
+ skills.push({ id: `${manifest.name}/${basename(entry.path)}`, path: skillPath, markdown });
121
+ }
122
+ const mcp = parsePluginMcp(root, json(await input.files.read(`${root}/mcp.json`)));
123
+ return { root, manifest, skills, mcpServers: mcp.servers, errors: [...errors, ...mcp.errors] };
124
+ }
125
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/core/agent/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { type PermissionConfig, type Ruleset } from "../permission/ruleset.js";
2
+ import type { ModelRef } from "../session/types.js";
3
+ /** Agent registry (spec §6). Agents are named bundles of (prompt, permission
4
+ * ruleset, model override, step budget). Primary agents answer user prompts;
5
+ * subagents are spawned by the task tool. There is no mode toggle — the
6
+ * presets below replace plan/build (spec §6.2). */
7
+ export type AgentInfo = {
8
+ name: string;
9
+ description?: string;
10
+ mode: "primary" | "subagent" | "all";
11
+ hidden?: boolean;
12
+ model?: ModelRef;
13
+ temperature?: number;
14
+ topP?: number;
15
+ prompt?: string;
16
+ steps?: number;
17
+ permission: Ruleset;
18
+ };
19
+ export type AgentDefinition = Omit<AgentInfo, "permission"> & {
20
+ permission: PermissionConfig;
21
+ };
22
+ export declare const builtinAgents: AgentInfo[];
23
+ /** Built-in baseline applied beneath every agent's own ruleset (spec §5.5). */
24
+ export declare const builtinDefaults: Ruleset;
25
+ export declare class AgentRegistry {
26
+ private readonly agents;
27
+ constructor(customAgents?: AgentInfo[]);
28
+ get(name: string): AgentInfo | null;
29
+ list(filter?: {
30
+ mode?: "primary" | "subagent";
31
+ includeHidden?: boolean;
32
+ }): AgentInfo[];
33
+ /** Effective ruleset stack for a session running this agent, in ascending
34
+ * precedence: builtin defaults → agent preset. Session rules are appended
35
+ * later by the permission engine. */
36
+ rulesetsFor(name: string): Ruleset[];
37
+ /** Returns a NEW registry with additional agents layered on top (workspace
38
+ * custom agents). The base registry is shared/process-wide, so per-run
39
+ * customization must not mutate it — this derive keeps the singleton
40
+ * immutable while letting a session see its workspace's .zmzai/agents. */
41
+ derive(extraAgents: AgentInfo[]): AgentRegistry;
42
+ /** Custom agents registered beyond the builtins (for derive()). */
43
+ get customAgents(): AgentInfo[];
44
+ }
45
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/agent/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;oDAGoD;AAEpD,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG;IAAE,UAAU,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAmB/F,eAAO,MAAM,aAAa,EAAE,SAAS,EAiCpC,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,eAAe,EAAE,OAS5B,CAAC;AAEH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;gBAE3C,YAAY,GAAE,SAAS,EAAO;IAK1C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAInC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,EAAE;IAQtF;;0CAEsC;IACtC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE;IAKpC;;;+EAG2E;IAC3E,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,GAAG,aAAa;IAM/C,mEAAmE;IACnE,IAAI,YAAY,IAAI,SAAS,EAAE,CAE9B;CACF"}