@nema-project/nema 0.0.0-stage → 0.1.3

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 (114) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chunks/chunk-HEIQINX3.js +825 -0
  3. package/dist/chunks/chunk-WT3XUFWU.js +86 -0
  4. package/dist/claude/adapter.d.ts +19 -0
  5. package/dist/claude/adapter.js +258 -0
  6. package/dist/claude/events.d.ts +29 -0
  7. package/dist/claude/events.js +75 -0
  8. package/dist/claude/launch.d.ts +22 -0
  9. package/dist/claude/launch.js +80 -0
  10. package/dist/claude/token.d.ts +9 -0
  11. package/dist/claude/token.js +87 -0
  12. package/dist/codex/adapter.d.ts +17 -0
  13. package/dist/codex/adapter.js +151 -0
  14. package/dist/codex/events.d.ts +16 -0
  15. package/dist/codex/events.js +47 -0
  16. package/dist/codex/isolation.d.ts +33 -0
  17. package/dist/codex/isolation.js +115 -0
  18. package/dist/config.d.ts +29 -0
  19. package/dist/config.js +75 -0
  20. package/dist/configCommands.d.ts +13 -0
  21. package/dist/configCommands.js +69 -0
  22. package/dist/daemon/cleanup.d.ts +5 -0
  23. package/dist/daemon/cleanup.js +49 -0
  24. package/dist/daemon/connection.d.ts +22 -0
  25. package/dist/daemon/connection.js +166 -0
  26. package/dist/daemon/rpc.d.ts +14 -0
  27. package/dist/daemon/rpc.js +20 -0
  28. package/dist/daemon/runner.d.ts +34 -0
  29. package/dist/daemon/runner.js +94 -0
  30. package/dist/daemon/setup.d.ts +39 -0
  31. package/dist/daemon/setup.js +95 -0
  32. package/dist/direct/adapter.d.ts +30 -0
  33. package/dist/direct/adapter.js +190 -0
  34. package/dist/direct/authCommands.d.ts +54 -0
  35. package/dist/direct/authCommands.js +268 -0
  36. package/dist/direct/authStore.d.ts +120 -0
  37. package/dist/direct/authStore.js +351 -0
  38. package/dist/direct/byok.d.ts +27 -0
  39. package/dist/direct/byok.js +67 -0
  40. package/dist/direct/codexLogin.d.ts +34 -0
  41. package/dist/direct/codexLogin.js +93 -0
  42. package/dist/direct/jwt.d.ts +4 -0
  43. package/dist/direct/jwt.js +22 -0
  44. package/dist/direct/lock.d.ts +16 -0
  45. package/dist/direct/lock.js +134 -0
  46. package/dist/direct/loop.d.ts +33 -0
  47. package/dist/direct/loop.js +110 -0
  48. package/dist/direct/siwc.d.ts +63 -0
  49. package/dist/direct/siwc.js +403 -0
  50. package/dist/direct/tools.d.ts +17 -0
  51. package/dist/direct/tools.js +104 -0
  52. package/dist/direct/transport.d.ts +177 -0
  53. package/dist/direct/transport.js +437 -0
  54. package/dist/doctor.d.ts +28 -0
  55. package/dist/doctor.js +178 -0
  56. package/dist/extensions/handlers.d.ts +2 -0
  57. package/dist/extensions/handlers.js +10 -0
  58. package/dist/extensions/store.d.ts +11 -0
  59. package/dist/extensions/store.js +132 -0
  60. package/dist/github/client.d.ts +47 -0
  61. package/dist/github/client.js +383 -0
  62. package/dist/github/gh.d.ts +56 -0
  63. package/dist/github/gh.js +385 -0
  64. package/dist/index.d.ts +2 -0
  65. package/dist/index.js +144 -0
  66. package/dist/localSettings.d.ts +8 -0
  67. package/dist/localSettings.js +26 -0
  68. package/dist/mcp/server.d.ts +5 -0
  69. package/dist/mcp/server.js +83 -0
  70. package/dist/ownedProcess.d.ts +39 -0
  71. package/dist/ownedProcess.js +229 -0
  72. package/dist/platform.d.ts +10 -0
  73. package/dist/platform.js +60 -0
  74. package/dist/report/commands.d.ts +41 -0
  75. package/dist/report/commands.js +159 -0
  76. package/dist/report/desktop.d.ts +3 -0
  77. package/dist/report/desktop.js +123 -0
  78. package/dist/report/git.d.ts +5 -0
  79. package/dist/report/git.js +42 -0
  80. package/dist/report/install.d.ts +22 -0
  81. package/dist/report/install.js +183 -0
  82. package/dist/report/send.d.ts +35 -0
  83. package/dist/report/send.js +208 -0
  84. package/dist/report/token.d.ts +5 -0
  85. package/dist/report/token.js +86 -0
  86. package/dist/repos/git.d.ts +48 -0
  87. package/dist/repos/git.js +370 -0
  88. package/dist/repos/graphify.d.ts +32 -0
  89. package/dist/repos/graphify.js +292 -0
  90. package/dist/repos/handlers.d.ts +20 -0
  91. package/dist/repos/handlers.js +255 -0
  92. package/dist/repos/indexState.d.ts +10 -0
  93. package/dist/repos/indexState.js +45 -0
  94. package/dist/repos/pickDirectory.d.ts +11 -0
  95. package/dist/repos/pickDirectory.js +140 -0
  96. package/dist/repos/reportCheck.d.ts +13 -0
  97. package/dist/repos/reportCheck.js +268 -0
  98. package/dist/repos/watcher.d.ts +64 -0
  99. package/dist/repos/watcher.js +202 -0
  100. package/dist/room/client.d.ts +26 -0
  101. package/dist/room/client.js +76 -0
  102. package/dist/secrets/file.d.ts +12 -0
  103. package/dist/secrets/file.js +89 -0
  104. package/dist/secrets/github.d.ts +10 -0
  105. package/dist/secrets/github.js +29 -0
  106. package/dist/secrets/permissions.d.ts +7 -0
  107. package/dist/secrets/permissions.js +86 -0
  108. package/dist/systemGit.d.ts +14 -0
  109. package/dist/systemGit.js +75 -0
  110. package/dist/wp/commands.d.ts +15 -0
  111. package/dist/wp/commands.js +103 -0
  112. package/package.json +26 -4
  113. package/src/report/SKILL.md +21 -0
  114. package/README.md +0 -3
@@ -0,0 +1,825 @@
1
+ // ../../../packages/shared/dist/report.js
2
+ import { z } from "zod";
3
+ var HookSignal = z.object({
4
+ agent: z.string().min(1).max(40),
5
+ cwd: z.string(),
6
+ gitCommonDir: z.string(),
7
+ branch: z.string().nullable(),
8
+ head: z.string().regex(/^[0-9a-f]{40}$/),
9
+ at: z.iso.datetime({ offset: true }),
10
+ sessionId: z.string().max(200).nullable()
11
+ });
12
+ var ReportInput = z.object({
13
+ agent: z.string().min(1).max(40),
14
+ gitCommonDir: z.string(),
15
+ summary: z.string().min(1).max(2e3),
16
+ entries: z.array(z.string().regex(/^[RDTQSGW]-[1-9]\d*$/)).max(50).default([]),
17
+ commits: z.array(z.string().regex(/^[0-9a-f]{7,40}$/)).min(1).max(50),
18
+ files: z.array(z.string().min(1).max(500)).max(500).default([]),
19
+ task: z.number().int().min(1).max(15).optional()
20
+ });
21
+ var IMPLEMENTATION_STATUSES = ["reported", "verified", "mismatch"];
22
+ var Implementation = z.object({
23
+ status: z.enum(IMPLEMENTATION_STATUSES),
24
+ evidence: z.object({
25
+ reportMessageId: z.string().nullable(),
26
+ commits: z.array(z.string()),
27
+ /** True when the work was inferred from code on main with no report. */
28
+ inferred: z.boolean(),
29
+ note: z.string().nullable(),
30
+ confirmedBy: z.literal("user").nullable()
31
+ })
32
+ });
33
+
34
+ // ../../../packages/shared/dist/entry.js
35
+ import { z as z2 } from "zod";
36
+ var ENTRY_KINDS = ["requirement", "decision", "tradeoff", "question", "source", "diagram", "workpackage"];
37
+ var EntryKindSchema = z2.enum(ENTRY_KINDS);
38
+ var BASIS_VALUES = ["stated", "decided", "inferred"];
39
+ var BasisSchema = z2.enum(BASIS_VALUES);
40
+ var Quote = z2.object({ messageId: z2.string().min(1), text: z2.string().min(1).max(500) });
41
+ var DIAGRAM_TYPES = [
42
+ "architecture",
43
+ "workflow",
44
+ "sequence",
45
+ "dataflow",
46
+ "lifecycle",
47
+ "erd",
48
+ "class",
49
+ "tree",
50
+ "timeline",
51
+ "waterfall"
52
+ ];
53
+ var DiagramMeta = z2.object({
54
+ repoId: z2.string().min(1),
55
+ type: z2.enum(DIAGRAM_TYPES),
56
+ /** repo id -> main sha the diagram was drawn at. */
57
+ sourceCommits: z2.record(z2.string(), z2.string()),
58
+ /** archify node id -> repo-relative paths that node stands for. */
59
+ nodePaths: z2.record(z2.string(), z2.array(z2.string()))
60
+ });
61
+ var MAX_WP_TASKS = 15;
62
+ var WpTask = z2.object({
63
+ n: z2.number().int().min(1).max(MAX_WP_TASKS),
64
+ title: z2.string(),
65
+ satisfies: z2.array(z2.string()),
66
+ files: z2.array(z2.object({ op: z2.enum(["modify", "create"]), repo: z2.string(), path: z2.string() })),
67
+ status: z2.enum(["pending", "reported", "verified", "mismatch"]),
68
+ inferred: z2.boolean(),
69
+ reportMessageId: z2.string().nullable(),
70
+ confirmedBy: z2.literal("user").nullable()
71
+ });
72
+ var WorkPackageMeta = z2.object({
73
+ requirements: z2.array(z2.string()),
74
+ repos: z2.array(z2.string()),
75
+ approvedAt: z2.string().nullable(),
76
+ approvedCommit: z2.string().nullable(),
77
+ blockedOn: z2.string().nullable(),
78
+ tasks: z2.array(WpTask)
79
+ });
80
+ var IsoDateTime = z2.iso.datetime({ offset: true }).nullable();
81
+ var PREFIX_KIND = {
82
+ R: "requirement",
83
+ D: "decision",
84
+ T: "tradeoff",
85
+ Q: "question",
86
+ S: "source",
87
+ G: "diagram",
88
+ W: "workpackage"
89
+ };
90
+ var ID_RE = /^(R|D|T|Q|S|G|W)-[1-9]\d*$/;
91
+ function kindFromId(id) {
92
+ if (!ID_RE.test(id))
93
+ return null;
94
+ return PREFIX_KIND[id[0]] ?? null;
95
+ }
96
+ var KIND_STATUSES = {
97
+ requirement: ["active", "superseded", "dropped"],
98
+ decision: ["active", "superseded", "dropped"],
99
+ tradeoff: ["active", "dropped"],
100
+ question: ["open", "resolved", "dropped"],
101
+ source: ["active", "dropped"],
102
+ diagram: ["active", "superseded", "dropped"],
103
+ workpackage: ["draft", "approved", "in_progress", "done", "dropped"]
104
+ };
105
+ var ALL_STATUSES = ["active", "superseded", "dropped", "open", "resolved", "draft", "approved", "in_progress", "done"];
106
+ var StatusSchema = z2.enum(ALL_STATUSES);
107
+ var BusinessDate = z2.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable();
108
+ var HttpUrl = z2.string().refine((s) => {
109
+ try {
110
+ const p = new URL(s).protocol;
111
+ return p === "http:" || p === "https:";
112
+ } catch {
113
+ return false;
114
+ }
115
+ }, "url must be http or https");
116
+ var Priority = z2.union([z2.literal(1), z2.literal(2), z2.literal(3)]);
117
+ function refineKind(v, ctx) {
118
+ if (v.status !== void 0 && !KIND_STATUSES[v.kind].includes(v.status)) {
119
+ ctx.addIssue({ code: "custom", path: ["status"], message: `invalid status "${v.status}" for ${v.kind}` });
120
+ }
121
+ if (v.kind === "source") {
122
+ if (v.url === void 0)
123
+ ctx.addIssue({ code: "custom", path: ["url"], message: "url is required for source" });
124
+ } else if (v.url !== void 0) {
125
+ ctx.addIssue({ code: "custom", path: ["url"], message: "url is only allowed for source" });
126
+ }
127
+ if (v.kind === "diagram") {
128
+ if (v.diagram === void 0)
129
+ ctx.addIssue({ code: "custom", path: ["diagram"], message: "diagram is required for diagram" });
130
+ } else if (v.diagram !== void 0) {
131
+ ctx.addIssue({ code: "custom", path: ["diagram"], message: "diagram is only allowed for diagram" });
132
+ }
133
+ if (v.kind === "workpackage") {
134
+ if (v.workpackage === void 0)
135
+ ctx.addIssue({ code: "custom", path: ["workpackage"], message: "workpackage is required for workpackage" });
136
+ } else if (v.workpackage !== void 0) {
137
+ ctx.addIssue({ code: "custom", path: ["workpackage"], message: "workpackage is only allowed for workpackage" });
138
+ }
139
+ if (v.kind !== "requirement" && v.implementation !== void 0) {
140
+ ctx.addIssue({ code: "custom", path: ["implementation"], message: "implementation is only allowed for requirement" });
141
+ }
142
+ if (v.kind === "question") {
143
+ if (v.priority === void 0)
144
+ ctx.addIssue({ code: "custom", path: ["priority"], message: "priority is required for question" });
145
+ } else if (v.priority !== void 0) {
146
+ ctx.addIssue({ code: "custom", path: ["priority"], message: "priority is only allowed for question" });
147
+ }
148
+ }
149
+ var EntryFrontmatter = z2.object({
150
+ id: z2.string().regex(ID_RE),
151
+ kind: EntryKindSchema,
152
+ title: z2.string().min(1).max(200),
153
+ status: StatusSchema,
154
+ businessDate: BusinessDate,
155
+ related: z2.array(z2.string()),
156
+ sourceMessages: z2.array(z2.string()),
157
+ url: HttpUrl.optional(),
158
+ priority: Priority.optional(),
159
+ diagram: DiagramMeta.optional(),
160
+ implementation: Implementation.optional(),
161
+ workpackage: WorkPackageMeta.optional(),
162
+ basis: BasisSchema.nullable(),
163
+ ingestedAt: IsoDateTime,
164
+ confirmedAt: IsoDateTime,
165
+ quotes: z2.array(Quote)
166
+ }).superRefine((v, ctx) => {
167
+ refineKind(v, ctx);
168
+ if (kindFromId(v.id) !== v.kind) {
169
+ ctx.addIssue({ code: "custom", path: ["id"], message: "id prefix does not match kind" });
170
+ }
171
+ });
172
+ var UpsertEntryInput = z2.object({
173
+ id: z2.string().regex(ID_RE).optional(),
174
+ kind: EntryKindSchema,
175
+ title: z2.string().min(1).max(200),
176
+ body: z2.string(),
177
+ status: StatusSchema.optional(),
178
+ businessDate: BusinessDate.optional(),
179
+ related: z2.array(z2.string()).optional(),
180
+ sourceMessages: z2.array(z2.string()).default([]),
181
+ url: HttpUrl.optional(),
182
+ priority: Priority.optional(),
183
+ /** Requirements only. The Room API checks it against reports; omitted keeps the stored one. */
184
+ implementation: Implementation.optional(),
185
+ basis: BasisSchema.optional(),
186
+ quotes: z2.array(Quote).max(10).optional(),
187
+ confirmed: z2.boolean().optional(),
188
+ reason: z2.string().min(1).max(500)
189
+ }).superRefine((v, ctx) => {
190
+ refineKind(v, ctx);
191
+ if (v.id !== void 0 && kindFromId(v.id) !== v.kind) {
192
+ ctx.addIssue({ code: "custom", path: ["id"], message: "id prefix does not match kind" });
193
+ }
194
+ });
195
+
196
+ // ../../../packages/shared/dist/workspace.js
197
+ import { z as z3 } from "zod";
198
+ var MessageQuote = z3.object({
199
+ messageId: z3.string(),
200
+ role: z3.enum(["user", "agent", "system", "report"]),
201
+ excerpt: z3.string()
202
+ });
203
+ var UserMessageMeta = z3.object({
204
+ quote: MessageQuote.optional()
205
+ });
206
+ var AgentMessageMeta = z3.object({
207
+ changes: z3.array(z3.object({
208
+ entryId: z3.string(),
209
+ kind: EntryKindSchema,
210
+ title: z3.string(),
211
+ op: z3.enum(["add", "update"])
212
+ })),
213
+ askedQuestion: z3.object({ id: z3.string(), title: z3.string(), body: z3.string() }).nullable(),
214
+ quote: MessageQuote.optional()
215
+ });
216
+ function isBranchName(name) {
217
+ if (name === "" || name === "HEAD" || name === "@")
218
+ return false;
219
+ if (/^[-+]/.test(name))
220
+ return false;
221
+ if (/[\u0000-\u0020\u007f~^:?*[\\]/.test(name))
222
+ return false;
223
+ if (name.includes("..") || name.includes("@{"))
224
+ return false;
225
+ if (name.endsWith("/") || name.endsWith(".") || name.endsWith(".lock"))
226
+ return false;
227
+ return name.split("/").every((segment) => segment !== "" && !segment.startsWith(".") && !segment.endsWith(".lock"));
228
+ }
229
+
230
+ // ../../../packages/shared/dist/plugins.js
231
+ var PAGE = { type: "number", minimum: 1, description: "Page number for pagination." };
232
+ var PER_PAGE = { type: "number", minimum: 1, maximum: 100, description: "Results per page, at most 100." };
233
+ var OWNER = { type: "string", description: "Repository owner." };
234
+ var REPO_NAME = { type: "string", description: "Repository name." };
235
+ function ghArgsSchema(description) {
236
+ return {
237
+ type: "object",
238
+ properties: { args: { type: "array", items: { type: "string" }, minItems: 2, maxItems: 80, description } },
239
+ required: ["args"],
240
+ additionalProperties: false
241
+ };
242
+ }
243
+ var GITHUB_FUNCTIONS = [
244
+ {
245
+ name: "github__pull_request_read",
246
+ description: "Read one pull request of a bound repository on GitHub: details, diff, files, commits, reviews or comments.",
247
+ readOnly: true,
248
+ parameters: {
249
+ type: "object",
250
+ properties: {
251
+ owner: OWNER,
252
+ repo: REPO_NAME,
253
+ pullNumber: { type: "number", minimum: 1, description: "Pull request number." },
254
+ method: {
255
+ type: "string",
256
+ enum: ["get", "get_diff", "get_status", "get_files", "get_commits", "get_review_comments", "get_reviews", "get_comments", "get_check_runs"]
257
+ },
258
+ page: PAGE,
259
+ perPage: PER_PAGE,
260
+ after: { type: "string", description: "Cursor for get_review_comments pagination." }
261
+ },
262
+ required: ["owner", "repo", "pullNumber", "method"],
263
+ additionalProperties: false
264
+ }
265
+ },
266
+ {
267
+ name: "github__list_pull_requests",
268
+ description: "List pull requests of a bound repository on GitHub.",
269
+ readOnly: true,
270
+ parameters: {
271
+ type: "object",
272
+ properties: {
273
+ owner: OWNER,
274
+ repo: REPO_NAME,
275
+ state: { type: "string", enum: ["open", "closed", "all"] },
276
+ base: { type: "string", description: "Filter by base branch." },
277
+ head: { type: "string", description: "Filter by head user or org and branch." },
278
+ sort: { type: "string" },
279
+ direction: { type: "string" },
280
+ page: PAGE,
281
+ perPage: PER_PAGE
282
+ },
283
+ required: ["owner", "repo"],
284
+ additionalProperties: false
285
+ }
286
+ },
287
+ {
288
+ name: "github__search_pull_requests",
289
+ description: "Search pull requests on GitHub with a query that names exactly one bound repository as repo:owner/name.",
290
+ readOnly: true,
291
+ parameters: {
292
+ type: "object",
293
+ properties: {
294
+ query: { type: "string", description: "GitHub search syntax, with exactly one repo:owner/name qualifier." },
295
+ sort: { type: "string" },
296
+ order: { type: "string" },
297
+ page: PAGE,
298
+ perPage: PER_PAGE
299
+ },
300
+ required: ["query"],
301
+ additionalProperties: false
302
+ }
303
+ },
304
+ {
305
+ name: "github__issue_read",
306
+ description: "Read one issue of a bound repository on GitHub: details, comments, sub-issues, parent or labels.",
307
+ readOnly: true,
308
+ parameters: {
309
+ type: "object",
310
+ properties: {
311
+ owner: OWNER,
312
+ repo: REPO_NAME,
313
+ issue_number: { type: "number", minimum: 1, description: "Issue number." },
314
+ method: { type: "string", enum: ["get", "get_comments", "get_sub_issues", "get_parent", "get_labels"] },
315
+ page: PAGE,
316
+ perPage: PER_PAGE
317
+ },
318
+ required: ["owner", "repo", "issue_number", "method"],
319
+ additionalProperties: false
320
+ }
321
+ },
322
+ {
323
+ name: "github__list_issues",
324
+ description: "List issues of a bound repository on GitHub.",
325
+ readOnly: true,
326
+ parameters: {
327
+ type: "object",
328
+ properties: {
329
+ owner: OWNER,
330
+ repo: REPO_NAME,
331
+ state: { type: "string" },
332
+ labels: { type: "array", items: { type: "string" } },
333
+ orderBy: { type: "string" },
334
+ direction: { type: "string" },
335
+ since: { type: "string", description: "ISO 8601 timestamp." },
336
+ after: { type: "string", description: "Cursor from the previous page." },
337
+ perPage: PER_PAGE
338
+ },
339
+ required: ["owner", "repo"],
340
+ additionalProperties: false
341
+ }
342
+ },
343
+ {
344
+ name: "github__search_issues",
345
+ description: "Search issues on GitHub with a query that names exactly one bound repository as repo:owner/name.",
346
+ readOnly: true,
347
+ parameters: {
348
+ type: "object",
349
+ properties: {
350
+ query: { type: "string", description: "GitHub search syntax, with exactly one repo:owner/name qualifier." },
351
+ sort: { type: "string" },
352
+ order: { type: "string" },
353
+ page: PAGE,
354
+ perPage: PER_PAGE
355
+ },
356
+ required: ["query"],
357
+ additionalProperties: false
358
+ }
359
+ },
360
+ {
361
+ name: "github__gh_read",
362
+ description: "Run a read-only gh command on a bound repository or on a Project of a bound owner, such as issue list, pr view, label list, run list or project item-list.",
363
+ readOnly: true,
364
+ parameters: ghArgsSchema("Arguments after gh, one array item each. Read commands: issue list|view|status, pr list|view|diff|checks|status, label list, run list|view, project list|view|field-list|item-list. Repository commands need --repo owner/name; project commands need --owner. Use long flags (--state, --limit, --json fields, --jq expr).")
365
+ },
366
+ {
367
+ name: "github__gh_write",
368
+ description: "Run a gh command that changes GitHub on a bound repository or on a Project of a bound owner, such as issue create, issue comment, issue edit, pr comment or project item-add.",
369
+ readOnly: false,
370
+ parameters: ghArgsSchema("Arguments after gh, one array item each. Write commands: issue create|comment|edit|close|reopen, pr comment|edit, label create|edit, project item-add|item-create|item-edit|item-archive. Repository commands need --repo owner/name; project commands need --owner. Pass text with --title and --body; files, editors and merging are not available.")
371
+ }
372
+ ];
373
+ var PLUGINS = [
374
+ {
375
+ id: "code",
376
+ displayName: "graphify",
377
+ dataFlow: "local",
378
+ runsOn: "daemon",
379
+ scope: "repo",
380
+ functions: [
381
+ {
382
+ name: "code__search",
383
+ description: "Search the repository for code matching a query.",
384
+ readOnly: true,
385
+ parameters: {
386
+ type: "object",
387
+ properties: {
388
+ repo: { type: "string" },
389
+ query: { type: "string" }
390
+ },
391
+ required: ["repo", "query"],
392
+ additionalProperties: false
393
+ }
394
+ },
395
+ {
396
+ name: "code__explain",
397
+ description: "Explain what a named symbol does in the repository.",
398
+ readOnly: true,
399
+ parameters: {
400
+ type: "object",
401
+ properties: {
402
+ repo: { type: "string" },
403
+ symbol: { type: "string" }
404
+ },
405
+ required: ["repo", "symbol"],
406
+ additionalProperties: false
407
+ }
408
+ },
409
+ {
410
+ name: "code__path",
411
+ description: "Show the path from one symbol to another in the repository.",
412
+ readOnly: true,
413
+ parameters: {
414
+ type: "object",
415
+ properties: {
416
+ repo: { type: "string" },
417
+ from: { type: "string" },
418
+ to: { type: "string" }
419
+ },
420
+ required: ["repo", "from", "to"],
421
+ additionalProperties: false
422
+ }
423
+ },
424
+ {
425
+ name: "code__read",
426
+ description: "Read a file from the repository, optionally limited to a line range.",
427
+ readOnly: true,
428
+ parameters: {
429
+ type: "object",
430
+ properties: {
431
+ repo: { type: "string" },
432
+ path: { type: "string" },
433
+ startLine: { type: "integer", minimum: 1 },
434
+ endLine: { type: "integer", minimum: 1 }
435
+ },
436
+ required: ["repo", "path"],
437
+ additionalProperties: false
438
+ }
439
+ },
440
+ {
441
+ name: "code__changes",
442
+ description: "List changes in the repository between two refs.",
443
+ readOnly: true,
444
+ parameters: {
445
+ type: "object",
446
+ properties: {
447
+ repo: { type: "string" },
448
+ from: { type: "string" },
449
+ to: { type: "string", description: "Defaults to the current main ref when omitted." }
450
+ },
451
+ required: ["repo", "from"],
452
+ additionalProperties: false
453
+ }
454
+ }
455
+ ]
456
+ },
457
+ {
458
+ id: "diagram",
459
+ displayName: "archify",
460
+ dataFlow: "local",
461
+ runsOn: "hub",
462
+ scope: "repo",
463
+ functions: [
464
+ {
465
+ name: "diagram__save",
466
+ description: "Save an archify diagram of a bound repository as a knowledge entry; pass id to update that diagram in place, and fix the spec and retry when the result is ok:false with diagnostics.",
467
+ readOnly: true,
468
+ parameters: {
469
+ type: "object",
470
+ properties: {
471
+ repo: { type: "string" },
472
+ type: { type: "string", enum: [...DIAGRAM_TYPES] },
473
+ title: { type: "string", minLength: 1, maxLength: 200 },
474
+ summary: { type: "string", description: "Markdown shown above the diagram." },
475
+ spec: { type: "object", description: "The archify JSON spec for this diagram type." },
476
+ nodePaths: {
477
+ type: "object",
478
+ description: "archify node id -> repo-relative paths that node stands for.",
479
+ additionalProperties: { type: "array", items: { type: "string" } }
480
+ },
481
+ id: { type: "string", pattern: "^G-[1-9][0-9]*$", description: "An existing diagram to update; omit to create one." }
482
+ },
483
+ required: ["repo", "type", "title", "summary", "spec", "nodePaths"],
484
+ additionalProperties: false
485
+ }
486
+ },
487
+ {
488
+ name: "diagram__read",
489
+ description: "Read a saved diagram entry and its archify JSON spec.",
490
+ readOnly: true,
491
+ parameters: {
492
+ type: "object",
493
+ properties: {
494
+ id: { type: "string", pattern: "^G-[1-9][0-9]*$" }
495
+ },
496
+ required: ["id"],
497
+ additionalProperties: false
498
+ }
499
+ }
500
+ ]
501
+ },
502
+ {
503
+ id: "superpowers",
504
+ displayName: "superpowers",
505
+ dataFlow: "local",
506
+ runsOn: "hub",
507
+ scope: "none",
508
+ functions: [
509
+ {
510
+ name: "workpackage__read",
511
+ description: "Read a work package: its entry, spec, plan and the writing rules for spec and plan.",
512
+ readOnly: true,
513
+ parameters: {
514
+ type: "object",
515
+ properties: { id: { type: "string", pattern: "^W-[1-9][0-9]*$" } },
516
+ required: ["id"],
517
+ additionalProperties: false
518
+ }
519
+ },
520
+ {
521
+ name: "workpackage__save_spec",
522
+ description: "Save the spec of a work package, and fix it and retry when the result is ok:false with an error.",
523
+ readOnly: true,
524
+ parameters: {
525
+ type: "object",
526
+ properties: { id: { type: "string", pattern: "^W-[1-9][0-9]*$" }, markdown: { type: "string" } },
527
+ required: ["id", "markdown"],
528
+ additionalProperties: false
529
+ }
530
+ },
531
+ {
532
+ name: "workpackage__save_plan",
533
+ description: "Save the plan of a work package, and fix it and retry when the result is ok:false with an error.",
534
+ readOnly: true,
535
+ parameters: {
536
+ type: "object",
537
+ properties: { id: { type: "string", pattern: "^W-[1-9][0-9]*$" }, markdown: { type: "string" } },
538
+ required: ["id", "markdown"],
539
+ additionalProperties: false
540
+ }
541
+ },
542
+ {
543
+ name: "workpackage__block",
544
+ description: "Mark a work package as blocked on an open question entry of this workspace.",
545
+ readOnly: true,
546
+ parameters: {
547
+ type: "object",
548
+ properties: { id: { type: "string", pattern: "^W-[1-9][0-9]*$" }, questionId: { type: "string", pattern: "^Q-[1-9][0-9]*$" } },
549
+ required: ["id", "questionId"],
550
+ additionalProperties: false
551
+ }
552
+ },
553
+ {
554
+ name: "workpackage__request",
555
+ description: "Ask for a work package to be written from the given requirement entries.",
556
+ readOnly: true,
557
+ parameters: {
558
+ type: "object",
559
+ properties: {
560
+ requirements: { type: "array", items: { type: "string", pattern: "^R-[1-9][0-9]*$" }, minItems: 1 },
561
+ title: { type: "string", minLength: 1, maxLength: 200 }
562
+ },
563
+ required: ["requirements"],
564
+ additionalProperties: false
565
+ }
566
+ },
567
+ {
568
+ name: "workpackage__mark_task_inferred",
569
+ description: "Mark a pending task of a work package as reported from the given main commits, inferred from the code.",
570
+ readOnly: true,
571
+ parameters: {
572
+ type: "object",
573
+ properties: {
574
+ id: { type: "string", pattern: "^W-[1-9][0-9]*$" },
575
+ task: { type: "integer", minimum: 1 },
576
+ commits: { type: "array", items: { type: "string" }, minItems: 1 }
577
+ },
578
+ required: ["id", "task", "commits"],
579
+ additionalProperties: false
580
+ }
581
+ }
582
+ ]
583
+ },
584
+ {
585
+ id: "grill",
586
+ displayName: "grill-me",
587
+ dataFlow: "local",
588
+ runsOn: "hub",
589
+ scope: "none",
590
+ functions: []
591
+ },
592
+ {
593
+ id: "github",
594
+ displayName: "GitHub",
595
+ dataFlow: "external",
596
+ runsOn: "daemon",
597
+ scope: "github",
598
+ functions: GITHUB_FUNCTIONS
599
+ }
600
+ ];
601
+
602
+ // ../../../packages/shared/dist/extensions.js
603
+ function bundled(id, name, availability, error) {
604
+ return {
605
+ id,
606
+ kind: "plugin",
607
+ name,
608
+ summary: "",
609
+ source: "bundled",
610
+ revision: "bundled",
611
+ provision: "bundled",
612
+ installState: "installed",
613
+ useState: "enabled",
614
+ availability,
615
+ externalPath: null,
616
+ error
617
+ };
618
+ }
619
+ function bundledExtensions() {
620
+ return [
621
+ bundled("code", "graphify", "missing-dependency", "bundled-runtime-missing"),
622
+ bundled("diagram", "archify", "ready", null),
623
+ bundled("superpowers", "superpowers", "ready", null),
624
+ bundled("grill", "grill-me", "ready", null),
625
+ bundled("github", "GitHub", "ready", null)
626
+ ];
627
+ }
628
+
629
+ // ../../../packages/shared/dist/protocol.js
630
+ import { z as z4 } from "zod";
631
+ var DaemonToHubSchema = z4.union([
632
+ z4.object({
633
+ type: z4.literal("hello"),
634
+ token: z4.string(),
635
+ version: z4.string(),
636
+ adapters: z4.array(z4.string()),
637
+ /** sha256 hex of ~/.nema/report-token, sent when that file exists. */
638
+ reportTokenHash: z4.string().regex(/^[0-9a-f]{64}$/).optional()
639
+ }),
640
+ z4.object({
641
+ type: z4.literal("task.event"),
642
+ taskId: z4.string(),
643
+ event: z4.object({ type: z4.enum(["progress", "agent_message", "tool_call"]), text: z4.string() })
644
+ }),
645
+ z4.object({ type: z4.literal("task.finished"), taskId: z4.string(), ok: z4.literal(true), reply: z4.string() }),
646
+ z4.object({ type: z4.literal("task.finished"), taskId: z4.string(), ok: z4.literal(false), error: z4.string() }),
647
+ z4.object({ type: z4.literal("rpc.response"), id: z4.string(), ok: z4.literal(true), result: z4.unknown() }),
648
+ z4.object({ type: z4.literal("rpc.response"), id: z4.string(), ok: z4.literal(false), error: z4.string() }),
649
+ z4.object({ type: z4.literal("repo.moved"), repoId: z4.string(), mainRef: z4.string(), from: z4.string().nullable(), to: z4.string() }),
650
+ z4.object({ type: z4.literal("repo.fetched"), repoId: z4.string(), ok: z4.boolean(), error: z4.string().optional(), at: z4.string() })
651
+ ]);
652
+ var HubToDaemonSchema = z4.discriminatedUnion("type", [
653
+ // workspaceIds: every workspace that still exists, so the daemon can remove the isolation dirs
654
+ // (`~/.nema/ws/<id>`) of workspaces deleted while it was offline. Optional for older hubs.
655
+ z4.object({ type: z4.literal("welcome"), workspaceIds: z4.array(z4.string()).optional() }),
656
+ // Sent to a connected daemon when a workspace is deleted, so it removes that workspace's isolation dir.
657
+ z4.object({ type: z4.literal("workspace.deleted"), workspaceId: z4.string() }),
658
+ z4.object({
659
+ type: z4.literal("task.assign"),
660
+ taskId: z4.string(),
661
+ workspaceId: z4.string(),
662
+ adapter: z4.string().min(1),
663
+ confidential: z4.boolean(),
664
+ prompt: z4.string(),
665
+ runToken: z4.string(),
666
+ hubUrl: z4.string(),
667
+ pluginTools: z4.array(z4.object({ name: z4.string(), description: z4.string(), parameters: z4.record(z4.string(), z4.unknown()) })),
668
+ limits: z4.object({ maxModelCalls: z4.number().int().min(1), maxToolCalls: z4.number().int().min(1), timeoutMs: z4.number().int().min(1) }).optional()
669
+ }),
670
+ z4.object({ type: z4.literal("rpc.request"), id: z4.string(), method: z4.string(), params: z4.unknown() }),
671
+ z4.object({ type: z4.literal("error"), message: z4.string() })
672
+ ]);
673
+ function parseHubToDaemon(raw) {
674
+ return HubToDaemonSchema.parse(raw);
675
+ }
676
+
677
+ // ../../../packages/shared/dist/ghCommand.js
678
+ var OUT = { json: "json", jq: "str" };
679
+ var rep = (kind) => ({ kind, repeat: true });
680
+ var STATE = { enum: ["open", "closed", "all"] };
681
+ var SPECS = {
682
+ "issue list": { mode: "read", scope: "repo", positional: "none", flags: { ...OUT, state: STATE, limit: "int", label: rep("str"), assignee: "str", author: "str", milestone: "str", mention: "str" } },
683
+ "issue view": { mode: "read", scope: "repo", positional: "number", flags: { ...OUT, comments: "bool" } },
684
+ "issue status": { mode: "read", scope: "repo", positional: "none", flags: { ...OUT } },
685
+ "issue create": { mode: "write", scope: "repo", positional: "none", flags: { title: "str", body: "str", label: rep("str"), assignee: rep("str"), milestone: "str", project: rep("str") }, required: ["title", "body"] },
686
+ "issue comment": { mode: "write", scope: "repo", positional: "number", flags: { body: "str" }, required: ["body"] },
687
+ "issue edit": { mode: "write", scope: "repo", positional: "number", flags: { title: "str", body: "str", "add-label": rep("str"), "remove-label": rep("str"), "add-assignee": rep("str"), "remove-assignee": rep("str"), milestone: "str", "remove-milestone": "bool", "add-project": rep("str"), "remove-project": rep("str") } },
688
+ "issue close": { mode: "write", scope: "repo", positional: "number", flags: { comment: "str", reason: { enum: ["completed", "not planned", "duplicate"] } } },
689
+ "issue reopen": { mode: "write", scope: "repo", positional: "number", flags: { comment: "str" } },
690
+ "pr list": { mode: "read", scope: "repo", positional: "none", flags: { ...OUT, state: { enum: ["open", "closed", "merged", "all"] }, limit: "int", label: rep("str"), assignee: "str", author: "str", base: "str", head: "str" } },
691
+ "pr view": { mode: "read", scope: "repo", positional: "number", flags: { ...OUT, comments: "bool" } },
692
+ "pr diff": { mode: "read", scope: "repo", positional: "number", flags: { "name-only": "bool", patch: "bool" } },
693
+ "pr checks": { mode: "read", scope: "repo", positional: "number", flags: { ...OUT, required: "bool" } },
694
+ "pr status": { mode: "read", scope: "repo", positional: "none", flags: { ...OUT } },
695
+ "pr comment": { mode: "write", scope: "repo", positional: "number", flags: { body: "str" }, required: ["body"] },
696
+ "pr edit": { mode: "write", scope: "repo", positional: "number", flags: { title: "str", body: "str", base: "str", milestone: "str", "add-label": rep("str"), "remove-label": rep("str"), "add-assignee": rep("str"), "remove-assignee": rep("str"), "add-reviewer": rep("str"), "remove-reviewer": rep("str") } },
697
+ "label list": { mode: "read", scope: "repo", positional: "none", flags: { ...OUT, limit: "int" } },
698
+ "label create": { mode: "write", scope: "repo", positional: "name", flags: { color: "str", description: "str", force: "bool" } },
699
+ "label edit": { mode: "write", scope: "repo", positional: "name", flags: { color: "str", description: "str", name: "str" } },
700
+ "run list": { mode: "read", scope: "repo", positional: "none", flags: { ...OUT, limit: "int", workflow: "str", branch: "str", status: "str" } },
701
+ "run view": { mode: "read", scope: "repo", positional: "number", flags: { ...OUT, log: "bool", "log-failed": "bool" } },
702
+ "project list": { mode: "read", scope: "owner", positional: "none", flags: { owner: "str", limit: "int", format: { enum: ["json"] }, jq: "str", closed: "bool" } },
703
+ "project view": { mode: "read", scope: "owner", positional: "number", flags: { owner: "str", format: { enum: ["json"] }, jq: "str" } },
704
+ "project field-list": { mode: "read", scope: "owner", positional: "number", flags: { owner: "str", limit: "int", format: { enum: ["json"] }, jq: "str" } },
705
+ "project item-list": { mode: "read", scope: "owner", positional: "number", flags: { owner: "str", limit: "int", format: { enum: ["json"] }, jq: "str" } },
706
+ "project item-add": { mode: "write", scope: "owner", positional: "number", flags: { owner: "str", url: "str" }, required: ["url"] },
707
+ "project item-create": { mode: "write", scope: "owner", positional: "number", flags: { owner: "str", title: "str", body: "str" }, required: ["title"] },
708
+ "project item-archive": { mode: "write", scope: "owner", positional: "number", flags: { owner: "str", id: "str", undo: "bool" }, required: ["id"] },
709
+ // Node ids cannot be tied to an owner; the Agent only gets them by reading a bound owner's Project.
710
+ "project item-edit": { mode: "write", scope: "none", positional: "none", flags: { id: "str", "project-id": "str", "field-id": "str", text: "str", number: "str", date: "str", "single-select-option-id": "str", "iteration-id": "str", clear: "bool" }, required: ["id"] }
711
+ };
712
+ var MAX_ITEMS = 80;
713
+ var MAX_VALUE = 65536;
714
+ var MAX_TOTAL = 2e5;
715
+ var NAME = /^[A-Za-z0-9._-]+$/;
716
+ var ISSUE_URL = /^https:\/\/github\.com\/([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+)\/(?:issues|pull)\/\d{1,9}$/;
717
+ var fail = (error) => ({ ok: false, error });
718
+ function boundRepo(value, bound) {
719
+ const [owner, repo, extra] = value.split("/");
720
+ if (extra !== void 0 || !owner || !repo || !NAME.test(owner) || !NAME.test(repo))
721
+ return false;
722
+ return bound.some((target) => target.owner.toLowerCase() === owner.toLowerCase() && target.repo.toLowerCase() === repo.toLowerCase());
723
+ }
724
+ function parseGhCommand(input, bound) {
725
+ if (!Array.isArray(input) || input.length === 0 || input.length > MAX_ITEMS || input.some((item) => typeof item !== "string"))
726
+ return fail("args must be a non-empty array of strings");
727
+ const args = input;
728
+ if (args.reduce((sum, item) => sum + item.length, 0) > MAX_TOTAL || args.some((item) => item.length > MAX_VALUE || item.includes("\0")))
729
+ return fail("argument too long or contains a NUL");
730
+ const spec = SPECS[`${args[0]} ${args[1]}`];
731
+ if (!spec)
732
+ return fail(`unsupported gh command: ${args.slice(0, 2).join(" ")}`);
733
+ const positionals = [];
734
+ const flags = [];
735
+ const seen = /* @__PURE__ */ new Set();
736
+ for (let i = 2; i < args.length; i++) {
737
+ const token = args[i];
738
+ let name;
739
+ let inline;
740
+ if (token === "-R")
741
+ name = "repo";
742
+ else if (token.startsWith("--")) {
743
+ const eq = token.indexOf("=");
744
+ name = eq < 0 ? token.slice(2) : token.slice(2, eq);
745
+ inline = eq < 0 ? void 0 : token.slice(eq + 1);
746
+ } else if (token.startsWith("-"))
747
+ return fail(`unsupported flag: ${token.slice(0, 40)}`);
748
+ else {
749
+ positionals.push(token);
750
+ continue;
751
+ }
752
+ const raw = name === "repo" ? spec.scope === "repo" ? "str" : void 0 : spec.flags[name];
753
+ if (raw === void 0)
754
+ return fail(`unsupported flag for gh ${args[0]} ${args[1]}: --${name.slice(0, 40)}`);
755
+ const flag = typeof raw === "object" && "kind" in raw ? raw.kind : raw;
756
+ const repeat = typeof raw === "object" && "kind" in raw;
757
+ if (!repeat && seen.has(name))
758
+ return fail(`repeated flag: --${name}`);
759
+ seen.add(name);
760
+ if (flag === "bool") {
761
+ if (inline !== void 0)
762
+ return fail(`--${name} takes no value`);
763
+ flags.push([name, true]);
764
+ continue;
765
+ }
766
+ const value2 = inline ?? args[++i];
767
+ if (value2 === void 0)
768
+ return fail(`--${name} needs a value`);
769
+ if (flag === "int" && !(/^\d{1,4}$/.test(value2) && +value2 >= 1 && +value2 <= 1e3))
770
+ return fail(`--${name} must be 1-1000`);
771
+ if (flag === "json" && !/^[A-Za-z0-9,]+$/.test(value2))
772
+ return fail("--json takes a comma-separated field list");
773
+ if (typeof flag === "object" && "enum" in flag && !flag.enum.includes(value2))
774
+ return fail(`--${name} must be one of: ${flag.enum.join(", ")}`);
775
+ flags.push([name, value2]);
776
+ }
777
+ for (const name of spec.required ?? [])
778
+ if (!seen.has(name))
779
+ return fail(`--${name} is required`);
780
+ if (spec.positional === "none" && positionals.length > 0)
781
+ return fail("unexpected argument");
782
+ if (spec.positional !== "none" && positionals.length !== 1)
783
+ return fail("exactly one target argument is required");
784
+ const target = positionals[0];
785
+ if (spec.positional === "number" && !/^\d{1,9}$/.test(target))
786
+ return fail("the target must be an issue, pull request, project or run number");
787
+ if (spec.positional === "name" && (target.startsWith("-") || target.length > 50 || /[\r\n]/.test(target)))
788
+ return fail("invalid name");
789
+ const value = (name) => flags.find(([key]) => key === name)?.[1];
790
+ if (spec.scope === "repo") {
791
+ const repo = value("repo");
792
+ if (repo === void 0)
793
+ return fail("--repo owner/name is required");
794
+ if (!boundRepo(repo, bound))
795
+ return fail(`only repositories bound to this workspace may be used: ${repo.slice(0, 100)}`);
796
+ }
797
+ if (spec.scope === "owner") {
798
+ const owner = value("owner");
799
+ if (owner === void 0)
800
+ return fail("--owner is required");
801
+ if (!NAME.test(owner) || !bound.some((item) => item.owner.toLowerCase() === owner.toLowerCase()))
802
+ return fail(`only owners of repositories bound to this workspace may be used: ${owner.slice(0, 100)}`);
803
+ }
804
+ const url = value("url");
805
+ if (args[0] === "project" && url !== void 0) {
806
+ const match = ISSUE_URL.exec(url);
807
+ if (!match || !boundRepo(`${match[1]}/${match[2]}`, bound))
808
+ return fail("--url must be an issue or pull request of a bound repository");
809
+ }
810
+ const argv = [args[0], args[1], ...positionals, ...flags.map(([name, v]) => v === true ? `--${name}` : `--${name}=${v}`)];
811
+ return { ok: true, mode: spec.mode, argv };
812
+ }
813
+ var GH_COMMAND_TOOLS = ["gh_read", "gh_write"];
814
+
815
+ export {
816
+ HookSignal,
817
+ ReportInput,
818
+ UpsertEntryInput,
819
+ isBranchName,
820
+ PLUGINS,
821
+ bundledExtensions,
822
+ parseHubToDaemon,
823
+ parseGhCommand,
824
+ GH_COMMAND_TOOLS
825
+ };