@thxgg/steward 0.1.7 → 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 (34) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{Bo1Fdv48.js → BPaqwWyl.js} +2 -2
  3. package/.output/public/_nuxt/{DhQtydpF.js → C8LtDyY4.js} +1 -1
  4. package/.output/public/_nuxt/{D0zW6lUK.js → CQgu_W_k.js} +1 -1
  5. package/.output/public/_nuxt/{BRDbaJqY.js → CZKCADv6.js} +2 -2
  6. package/.output/public/_nuxt/{CEJOILWG.js → CeO4HNxC.js} +1 -1
  7. package/.output/public/_nuxt/{BNzFoVmP.js → Cs5ptsBk.js} +1 -1
  8. package/.output/public/_nuxt/{CFsNy2aC.js → CshyynD6.js} +1 -1
  9. package/.output/public/_nuxt/{DYDTtHLR.js → CzKPXRws.js} +1 -1
  10. package/.output/public/_nuxt/{BqmZq_gb.js → DOvbLsAq.js} +1 -1
  11. package/.output/public/_nuxt/{Bri1ZtcQ.js → DbloiS5Y.js} +1 -1
  12. package/.output/public/_nuxt/{B3hkJjmY.js → DcRwFvvS.js} +1 -1
  13. package/.output/public/_nuxt/builds/latest.json +1 -1
  14. package/.output/public/_nuxt/builds/meta/7fda7510-94bc-443a-a338-a8d2af142ed9.json +1 -0
  15. package/.output/public/_nuxt/{X6fIXIFO.js → vr7VLA9A.js} +1 -1
  16. package/.output/server/chunks/build/{_prd_-CnwhMRyf.mjs → _prd_-CkKfJB6U.mjs} +2 -2
  17. package/.output/server/chunks/build/_prd_-CkKfJB6U.mjs.map +1 -0
  18. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  19. package/.output/server/chunks/build/server.mjs +1 -1
  20. package/.output/server/chunks/nitro/nitro.mjs +617 -617
  21. package/.output/server/package.json +1 -1
  22. package/README.md +22 -4
  23. package/dist/host/src/api/git.js +1 -8
  24. package/dist/host/src/api/prds.js +2 -8
  25. package/dist/host/src/api/repo-context.js +60 -0
  26. package/dist/host/src/api/repos.js +6 -0
  27. package/dist/host/src/api/state.js +20 -21
  28. package/dist/host/src/executor.js +215 -29
  29. package/dist/host/src/help.js +124 -0
  30. package/dist/host/src/mcp.js +49 -25
  31. package/docs/MCP.md +50 -3
  32. package/package.json +1 -1
  33. package/.output/public/_nuxt/builds/meta/6683a0d9-9c02-4098-b750-bbbc0305261e.json +0 -1
  34. package/.output/server/chunks/build/_prd_-CnwhMRyf.mjs.map +0 -1
@@ -1,57 +1,81 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import { z } from 'zod';
4
- import { execute, ExecutionError } from './executor.js';
5
- function formatError(error) {
6
- if (error instanceof ExecutionError) {
7
- return error.stackTrace
8
- ? `${error.message}\n\n${error.stackTrace}`
9
- : error.message;
10
- }
11
- if (error instanceof Error) {
12
- return error.stack
13
- ? `${error.message}\n\n${error.stack}`
14
- : error.message;
15
- }
16
- return String(error);
17
- }
18
- function serializeResult(result) {
19
- if (result === undefined) {
20
- return 'undefined';
21
- }
4
+ import { execute } from './executor.js';
5
+ import { getExecuteToolDescription } from './help.js';
6
+ function serializeEnvelope(envelope) {
22
7
  try {
23
- return JSON.stringify(result, null, 2);
8
+ return JSON.stringify(envelope, null, 2);
24
9
  }
25
10
  catch {
26
- return String(result);
11
+ const fallback = {
12
+ ok: false,
13
+ result: null,
14
+ logs: [],
15
+ error: {
16
+ code: 'SERIALIZATION_ERROR',
17
+ message: 'Failed to serialize execution envelope'
18
+ },
19
+ meta: {
20
+ timeoutMs: 30_000,
21
+ durationMs: 0,
22
+ truncatedResult: false,
23
+ truncatedLogs: false,
24
+ resultWasUndefined: false
25
+ }
26
+ };
27
+ return JSON.stringify(fallback, null, 2);
27
28
  }
28
29
  }
30
+ function buildUnexpectedErrorEnvelope(error) {
31
+ const message = error instanceof Error ? error.message : String(error);
32
+ const stack = error instanceof Error ? error.stack : undefined;
33
+ return {
34
+ ok: false,
35
+ result: null,
36
+ logs: [],
37
+ error: {
38
+ code: 'MCP_EXECUTION_FAILURE',
39
+ message,
40
+ ...(stack && { stack })
41
+ },
42
+ meta: {
43
+ timeoutMs: 30_000,
44
+ durationMs: 0,
45
+ truncatedResult: false,
46
+ truncatedLogs: false,
47
+ resultWasUndefined: false
48
+ }
49
+ };
50
+ }
29
51
  export async function runMcpServer() {
30
52
  const server = new McpServer({
31
53
  name: 'steward',
32
54
  version: '0.1.0'
33
55
  });
34
- server.tool('execute', 'Run codemode JavaScript with repos, prds, git, and state APIs.', {
35
- code: z.string().min(1)
56
+ server.tool('execute', getExecuteToolDescription(), {
57
+ code: z.string().optional()
36
58
  }, async ({ code }) => {
37
59
  try {
38
- const result = await execute(code);
60
+ const envelope = await execute(code || '');
39
61
  return {
62
+ isError: !envelope.ok,
40
63
  content: [
41
64
  {
42
65
  type: 'text',
43
- text: serializeResult(result)
66
+ text: serializeEnvelope(envelope)
44
67
  }
45
68
  ]
46
69
  };
47
70
  }
48
71
  catch (error) {
72
+ const envelope = buildUnexpectedErrorEnvelope(error);
49
73
  return {
50
74
  isError: true,
51
75
  content: [
52
76
  {
53
77
  type: 'text',
54
- text: formatError(error)
78
+ text: serializeEnvelope(envelope)
55
79
  }
56
80
  ]
57
81
  };
package/docs/MCP.md CHANGED
@@ -58,7 +58,31 @@ Example MCP client config:
58
58
 
59
59
  Your code is wrapped in an async function, so you can use `await` directly.
60
60
 
61
- Return values are JSON-stringified in the MCP response.
61
+ Each call returns a JSON envelope:
62
+
63
+ ```json
64
+ {
65
+ "ok": true,
66
+ "result": {},
67
+ "logs": [],
68
+ "error": null,
69
+ "meta": {
70
+ "timeoutMs": 30000,
71
+ "durationMs": 12,
72
+ "truncatedResult": false,
73
+ "truncatedLogs": false,
74
+ "resultWasUndefined": false
75
+ }
76
+ }
77
+ ```
78
+
79
+ - `result` is `null` when your code does not explicitly return a value.
80
+ - `logs` contains captured `console.log/info/warn/error` output from sandbox code.
81
+ - `error` is populated with `{ code, message, stack?, details? }` on failure.
82
+
83
+ In-sandbox discovery helper:
84
+
85
+ - `steward.help()`
62
86
 
63
87
  ## Available APIs
64
88
 
@@ -66,6 +90,7 @@ Return values are JSON-stringified in the MCP response.
66
90
 
67
91
  - `repos.list()`
68
92
  - `repos.get(repoId)`
93
+ - `repos.current()`
69
94
  - `repos.add(path, name?)`
70
95
  - `repos.remove(repoId)`
71
96
  - `repos.refreshGitRepos(repoId)`
@@ -89,10 +114,13 @@ Return values are JSON-stringified in the MCP response.
89
114
 
90
115
  - `state.get(repoId, slug)`
91
116
  - `state.getByPath(repoPath, slug)`
117
+ - `state.getCurrent(slug)`
92
118
  - `state.summaries(repoId)`
93
119
  - `state.summariesByPath(repoPath)`
120
+ - `state.summariesCurrent()`
94
121
  - `state.upsert(repoId, slug, payload)`
95
122
  - `state.upsertByPath(repoPath, slug, payload)`
123
+ - `state.upsertCurrent(slug, payload)`
96
124
 
97
125
  `payload` supports any combination of:
98
126
 
@@ -116,7 +144,7 @@ return await Promise.all(reposList.map(async (repo) => ({
116
144
  Load one PRD with state:
117
145
 
118
146
  ```js
119
- const repo = (await repos.list())[0]
147
+ const repo = await repos.current()
120
148
  const slug = 'prd-viewer'
121
149
 
122
150
  return {
@@ -139,6 +167,24 @@ return await Promise.all(commits.map(async (entry) => ({
139
167
  })))
140
168
  ```
141
169
 
170
+ Inspect signatures at runtime:
171
+
172
+ ```js
173
+ return steward.help()
174
+ ```
175
+
176
+ Update state in the current repo (no repoId required):
177
+
178
+ ```js
179
+ const slug = 'prd-viewer'
180
+
181
+ await state.upsertCurrent(slug, {
182
+ notes: '# Updated from codemode'
183
+ })
184
+
185
+ return { saved: true }
186
+ ```
187
+
142
188
  Update state directly by path (replacement for shell helpers):
143
189
 
144
190
  ```js
@@ -170,7 +216,8 @@ return { saved: true }
170
216
  ## Limits
171
217
 
172
218
  - Execution timeout: 30 seconds
173
- - Output preview limit: 50,000 characters
219
+ - Result preview limit: 50,000 characters
220
+ - Captured log limit: 20,000 characters (max 200 log entries)
174
221
  - Timer limit: 100 active timers in sandbox
175
222
 
176
223
  ## Safety Notes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thxgg/steward",
3
- "version": "0.1.7",
3
+ "version": "0.1.10",
4
4
  "description": "Local-first PRD workflow steward with codemode MCP and web UI.",
5
5
  "type": "module",
6
6
  "author": "thxgg",
@@ -1 +0,0 @@
1
- {"id":"6683a0d9-9c02-4098-b750-bbbc0305261e","timestamp":1771766521897,"prerendered":[]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_prd_-CnwhMRyf.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/_prd_-CnwhMRyf.js"],"names":[],"mappings":"","x_google_ignoreList":[0]}