yichus 0.3.2 → 0.3.4
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.
- package/README.md +5 -2
- package/dist/cli.js +27 -0
- package/dist/cli.js.map +1 -1
- package/dist/main.js +400 -118
- package/dist/main.js.map +1 -1
- package/dist/studio-page/system-map-record.js +93 -7
- package/dist/studio-page/system-map.js +60 -23
- package/dist/studio-page/what-happens-record.js +90 -6
- package/dist/studio-page/what-happens.js +72 -13
- package/dist/studio-reference/calculator.md +1 -0
- package/dist/studio-reference/deploy-platforms.md +3 -0
- package/dist/studio-reference/mutants/double-signup.bosatsu +149 -0
- package/dist/studio-reference/mutants/overfill.bosatsu +153 -0
- package/dist/studio-reference/near-miss-case.json +104 -0
- package/dist/studio-reference/near-miss-signups.bosatsu +139 -0
- package/dist/studio-reference/protocol-cases.md +7 -1
- package/dist/studio-reference/signups-case.json +122 -0
- package/dist/studio-reference/signups-laws.bosatsu +32 -0
- package/dist/studio-reference/signups.bosatsu +155 -0
- package/dist/studio-reference/spots.bosatsu +27 -0
- package/dist/studio-reference/the-page.md +7 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ shipped in `@yichus/api-mcp`; installing the release requires Node 20+,
|
|
|
6
6
|
without Java, sbt, Nix, or a browser.
|
|
7
7
|
|
|
8
8
|
```sh
|
|
9
|
-
npm install --save-dev yichus@0.3.
|
|
9
|
+
npm install --save-dev yichus@0.3.4
|
|
10
10
|
npx yichus tools
|
|
11
11
|
npx yichus call api_guide
|
|
12
12
|
```
|
|
@@ -29,7 +29,7 @@ and the studio tells the agent what to do next after every change:
|
|
|
29
29
|
```json
|
|
30
30
|
{
|
|
31
31
|
"mcpServers": {
|
|
32
|
-
"yichus": { "command": "npx", "args": ["-y", "yichus@0.3.
|
|
32
|
+
"yichus": { "command": "npx", "args": ["-y", "yichus@0.3.4", "studio"] }
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
```
|
|
@@ -219,6 +219,9 @@ different folders are named by the folders that tell them apart
|
|
|
219
219
|
Use `--args options.json` (or `--args -` for stdin) for the remaining
|
|
220
220
|
arguments. Values retain their JSON types. You can supply a complete
|
|
221
221
|
`sources` array there instead of `--source`; mixing the two is rejected.
|
|
222
|
+
`--arg-file NAME=FILE` sets one argument to the JSON in a file, such as
|
|
223
|
+
a saved snapshot for `api_snapshot` (`--arg-file snapshot=ledger.snap.json`);
|
|
224
|
+
naming the same argument in `--args` too is rejected.
|
|
222
225
|
|
|
223
226
|
```json
|
|
224
227
|
{"instances":"1"}
|
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,7 @@ var engines = {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/node-version.ts
|
|
9
|
+
import { createInterface } from "readline";
|
|
9
10
|
function nodeVersionProblem(running, required) {
|
|
10
11
|
const floor = /^>=(\d+)$/.exec(required);
|
|
11
12
|
if (!floor) throw new Error(`engines.node must read >=N, not ${required}`);
|
|
@@ -13,13 +14,39 @@ function nodeVersionProblem(running, required) {
|
|
|
13
14
|
if (Number(running.split(".")[0]) >= needed) return void 0;
|
|
14
15
|
return `yichus needs Node ${needed} or newer; this is Node ${running}. Install Node ${needed} or newer and run the command again.`;
|
|
15
16
|
}
|
|
17
|
+
async function refuseFirstRequest(problem2, input, output) {
|
|
18
|
+
for await (const line of createInterface({ input, crlfDelay: Infinity })) {
|
|
19
|
+
const id = requestId(line);
|
|
20
|
+
if (id === void 0) continue;
|
|
21
|
+
output.write(`${JSON.stringify({ jsonrpc: "2.0", id, error: { code: -32e3, message: problem2 } })}
|
|
22
|
+
`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function requestId(line) {
|
|
27
|
+
let message;
|
|
28
|
+
try {
|
|
29
|
+
message = JSON.parse(line);
|
|
30
|
+
} catch {
|
|
31
|
+
return void 0;
|
|
32
|
+
}
|
|
33
|
+
if (typeof message !== "object" || message === null || !("method" in message) || !("id" in message)) return void 0;
|
|
34
|
+
const { id } = message;
|
|
35
|
+
return typeof id === "string" || typeof id === "number" ? id : void 0;
|
|
36
|
+
}
|
|
16
37
|
|
|
17
38
|
// src/cli.ts
|
|
39
|
+
var argv = process.argv.slice(2);
|
|
40
|
+
var servesMcp = argv[0] === "studio" && !argv.includes("--page");
|
|
18
41
|
var problem = nodeVersionProblem(process.versions.node, engines.node);
|
|
19
42
|
if (problem) {
|
|
20
43
|
process.stderr.write(`${problem}
|
|
21
44
|
`);
|
|
22
45
|
process.exitCode = 1;
|
|
46
|
+
if (servesMcp && !process.stdin.isTTY) {
|
|
47
|
+
await refuseFirstRequest(problem, process.stdin, process.stdout);
|
|
48
|
+
process.stdin.destroy();
|
|
49
|
+
}
|
|
23
50
|
} else {
|
|
24
51
|
await import("./main.js");
|
|
25
52
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/node-version.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"yichus\",\n \"version\": \"0.3.
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/node-version.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"yichus\",\n \"version\": \"0.3.4\",\n \"description\": \"Local Bosatsu compilation, Yichus analysis, and generated apps using the WebMCP engine\",\n \"license\": \"MIT\",\n \"homepage\": \"https://yich.us\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/snoble/yichus.git\",\n \"directory\": \"packages/yichus-cli\"\n },\n \"type\": \"module\",\n \"bin\": {\n \"yichus\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"scripts\": {\n \"build\": \"tsup && node ./scripts/copy-studio-assets.mjs\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run --coverage\",\n \"prepack\": \"npm run build\"\n },\n \"dependencies\": {\n \"@yichus/api-mcp\": \"workspace:*\",\n \"zod\": \"^4.3.6\",\n \"@modelcontextprotocol/sdk\": \"^1.26.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.0.0\",\n \"tsup\": \"^8.3.0\",\n \"typescript\": \"^5.6.0\",\n \"vitest\": \"^2.1.0\",\n \"@vitest/coverage-v8\": \"2.1.9\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import { createInterface } from 'node:readline';\nimport type { Readable, Writable } from 'node:stream';\n\n/**\n * The sentence that stops the command on a Node older than the package's\n * `engines.node` floor, or undefined when the running Node meets it.\n */\nexport function nodeVersionProblem(running: string, required: string): string | undefined {\n const floor = /^>=(\\d+)$/.exec(required);\n if (!floor) throw new Error(`engines.node must read >=N, not ${required}`);\n const needed = Number(floor[1]);\n if (Number(running.split('.')[0]) >= needed) return undefined;\n return `yichus needs Node ${needed} or newer; this is Node ${running}. Install Node ${needed} or newer and run the command again.`;\n}\n\n/**\n * Answers the first JSON-RPC request on `input` with `problem` as its error,\n * so an agent host that started `yichus studio` shows the person why the\n * server stopped instead of a server that died without a word. Lines that\n * are not requests (notifications, anything unreadable) get no answer.\n */\nexport async function refuseFirstRequest(problem: string, input: Readable, output: Writable): Promise<void> {\n for await (const line of createInterface({ input, crlfDelay: Infinity })) {\n const id = requestId(line);\n if (id === undefined) continue;\n output.write(`${JSON.stringify({ jsonrpc: '2.0', id, error: { code: -32000, message: problem } })}\\n`);\n return;\n }\n}\n\nfunction requestId(line: string): string | number | undefined {\n let message: unknown;\n try { message = JSON.parse(line); } catch { return undefined; }\n if (typeof message !== 'object' || message === null || !('method' in message) || !('id' in message)) return undefined;\n const { id } = message;\n return typeof id === 'string' || typeof id === 'number' ? id : undefined;\n}\n","#!/usr/bin/env node\n// The Node check runs before the rest of the command loads, so an older\n// Node gets a sentence naming what to install rather than an error from\n// inside the engine. `yichus studio` also says it to the agent host that\n// started it, as the answer to its first request.\nimport { engines } from '../package.json';\nimport { nodeVersionProblem, refuseFirstRequest } from './node-version.js';\n\nconst argv = process.argv.slice(2);\nconst servesMcp = argv[0] === 'studio' && !argv.includes('--page');\n\nconst problem = nodeVersionProblem(process.versions.node, engines.node);\nif (problem) {\n process.stderr.write(`${problem}\\n`);\n process.exitCode = 1;\n if (servesMcp && !process.stdin.isTTY) {\n await refuseFirstRequest(problem, process.stdin, process.stdout);\n process.stdin.destroy();\n }\n} else {\n await import('./main.js');\n}\n"],"mappings":";;;AAqCE,cAAW;AAAA,EACT,MAAQ;AACV;;;ACvCF,SAAS,uBAAuB;AAOzB,SAAS,mBAAmB,SAAiB,UAAsC;AACxF,QAAM,QAAQ,YAAY,KAAK,QAAQ;AACvC,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,mCAAmC,QAAQ,EAAE;AACzE,QAAM,SAAS,OAAO,MAAM,CAAC,CAAC;AAC9B,MAAI,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,OAAQ,QAAO;AACpD,SAAO,qBAAqB,MAAM,2BAA2B,OAAO,kBAAkB,MAAM;AAC9F;AAQA,eAAsB,mBAAmBA,UAAiB,OAAiB,QAAiC;AAC1G,mBAAiB,QAAQ,gBAAgB,EAAE,OAAO,WAAW,SAAS,CAAC,GAAG;AACxE,UAAM,KAAK,UAAU,IAAI;AACzB,QAAI,OAAO,OAAW;AACtB,WAAO,MAAM,GAAG,KAAK,UAAU,EAAE,SAAS,OAAO,IAAI,OAAO,EAAE,MAAM,OAAQ,SAASA,SAAQ,EAAE,CAAC,CAAC;AAAA,CAAI;AACrG;AAAA,EACF;AACF;AAEA,SAAS,UAAU,MAA2C;AAC5D,MAAI;AACJ,MAAI;AAAE,cAAU,KAAK,MAAM,IAAI;AAAA,EAAG,QAAQ;AAAE,WAAO;AAAA,EAAW;AAC9D,MAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,EAAE,YAAY,YAAY,EAAE,QAAQ,SAAU,QAAO;AAC5G,QAAM,EAAE,GAAG,IAAI;AACf,SAAO,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,KAAK;AACjE;;;AC5BA,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,YAAY,KAAK,CAAC,MAAM,YAAY,CAAC,KAAK,SAAS,QAAQ;AAEjE,IAAM,UAAU,mBAAmB,QAAQ,SAAS,MAAM,QAAQ,IAAI;AACtE,IAAI,SAAS;AACX,UAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AACnC,UAAQ,WAAW;AACnB,MAAI,aAAa,CAAC,QAAQ,MAAM,OAAO;AACrC,UAAM,mBAAmB,SAAS,QAAQ,OAAO,QAAQ,MAAM;AAC/D,YAAQ,MAAM,QAAQ;AAAA,EACxB;AACF,OAAO;AACL,QAAM,OAAO,WAAW;AAC1B;","names":["problem"]}
|