@josfox/jos 4.1.0 → 5.0.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.
- package/LICENSE +208 -21
- package/PROMISES.md +52 -0
- package/README.md +334 -138
- package/SECURITY-MCP.md +117 -0
- package/SECURITY-SECRETS.md +108 -0
- package/STYLE.md +23 -0
- package/bin/jos +170 -160
- package/examples/01-hello.jos +44 -0
- package/examples/02-criteria.jos +54 -0
- package/examples/03-flow-gate.jos +83 -0
- package/examples/04-use-template/README.md +22 -0
- package/examples/04-use-template/lib/greeting.jos +56 -0
- package/examples/04-use-template/use.jos +64 -0
- package/examples/05-sealed/.jos/manifest.jos +53 -0
- package/examples/05-sealed/README.md +25 -0
- package/examples/06-requires.jos +42 -0
- package/examples/07-sandbox.jos +39 -0
- package/examples/08-ids-ledger-meter.md +26 -0
- package/examples/10-ollama.jos +47 -0
- package/examples/11-openai.jos +47 -0
- package/examples/12-gemini.jos +47 -0
- package/examples/13-anthropic.jos +47 -0
- package/examples/14-serve.jos +88 -0
- package/examples/README.md +105 -0
- package/examples/hello.jos +47 -0
- package/package.json +57 -40
- package/promises.json +894 -0
- package/src/args.js +47 -0
- package/src/commands/_frozen/add.README.md +1 -0
- package/src/commands/_frozen/get.README.md +1 -0
- package/src/commands/_frozen/llm.README.md +1 -0
- package/src/commands/_frozen/prompts.README.md +1 -0
- package/src/commands/_frozen/repo.README.md +1 -0
- package/src/commands/_frozen/serve-explorer.README.md +1 -0
- package/src/commands/ids.js +101 -0
- package/src/commands/init.js +128 -162
- package/src/commands/ledger.js +94 -0
- package/src/commands/meter.js +96 -0
- package/src/commands/migrate.js +214 -0
- package/src/commands/overview.js +118 -0
- package/src/commands/run.js +194 -244
- package/src/commands/runs.js +102 -0
- package/src/commands/secrets.js +717 -137
- package/src/commands/start.js +210 -0
- package/src/commands/validate.js +178 -194
- package/src/commands/verify.js +56 -98
- package/src/commands/version.js +23 -0
- package/src/intention.js +114 -0
- package/src/kernel.js +69 -0
- package/src/ledgers.js +57 -0
- package/src/mcp-guide.js +138 -0
- package/src/mcp.js +734 -0
- package/src/serve.js +48 -781
- package/src/ui.js +98 -0
- package/src/adapters/index.js +0 -16
- package/src/adapters/native.js +0 -41
- package/src/adapters/ollama.js +0 -140
- package/src/commands/add.js +0 -145
- package/src/commands/get.js +0 -245
- package/src/commands/llm.js +0 -159
- package/src/commands/prompts.js +0 -229
- package/src/commands/repo.js +0 -139
- package/src/utils/crypto.js +0 -41
- package/src/utils/request.js +0 -41
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jos": {
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"kind": "flow"
|
|
5
|
+
},
|
|
6
|
+
"id": "tour.serve",
|
|
7
|
+
"meta": {
|
|
8
|
+
"name": "tour.serve",
|
|
9
|
+
"version": "1.0.0"
|
|
10
|
+
},
|
|
11
|
+
"intention": {
|
|
12
|
+
"objective": "Serve a read-only HTML index of ~/.jos/runs on http://127.0.0.1:8765/ for 60 s, from a temporary folder (never ~/.jos itself)",
|
|
13
|
+
"success_criteria": [
|
|
14
|
+
{
|
|
15
|
+
"exit": 0
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"stdout_contains": "stopped and removed"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"guardrails": {
|
|
23
|
+
"avoid": [
|
|
24
|
+
"rm -rf",
|
|
25
|
+
"curl",
|
|
26
|
+
"wget"
|
|
27
|
+
],
|
|
28
|
+
"limit": {
|
|
29
|
+
"seconds": 900,
|
|
30
|
+
"output_bytes": 65536,
|
|
31
|
+
"retries": 0
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"orchestration": {
|
|
35
|
+
"definitions": {
|
|
36
|
+
"index": {
|
|
37
|
+
"engine": "shell",
|
|
38
|
+
"run": [
|
|
39
|
+
"/bin/sh",
|
|
40
|
+
"-c",
|
|
41
|
+
"dir=$(mktemp -d \"${TMPDIR:-/tmp}/jos-runs-index.XXXXXX\") || exit 1\nnode -e 'const fs = require(\"fs\"), path = require(\"path\");\nconst [runs, out] = process.argv.slice(1);\nconst esc = (s) => String(s).replace(/[&<>\"]/g, (c) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", \"\\\"\": \""\" })[c]);\nlet ids = [];\ntry { ids = fs.readdirSync(runs).filter((n) => /^run_[0-9A-Za-z]+$/.test(n)).sort().reverse(); } catch (e) { ids = []; }\nconst rows = ids.map((id) => {\n let es = [];\n try { es = fs.readFileSync(path.join(runs, id, \"ledger.jsonl\"), \"utf8\").split(\"\\n\").filter(Boolean).map((l) => JSON.parse(l)); } catch (e) { es = []; }\n const b = (e) => (e && e.body) || {};\n const end = b(es.find((e) => e.kind === \"end\"));\n const top = b(es.filter((e) => e.kind === \"receipt\").pop());\n const cells = [id, top.step || \"\", end.code === undefined ? \"\" : end.code, es.length ? es[0].ts : \"\"];\n return \"<tr>\" + cells.map((c) => \"<td>\" + esc(c) + \"</td>\").join(\"\") + \"</tr>\";\n});\nfs.writeFileSync(out, \"<!doctype html>\\n<meta charset=\\\"utf-8\\\">\\n<title>jos runs</title>\\n<h1>Runs in ~/.jos/runs</h1>\\n<p>A read-only snapshot. Check a run with <code>jos ledger verify <run_id></code>.</p>\\n<table>\\n<tr><th>run</th><th>document</th><th>code</th><th>started</th></tr>\\n\" + rows.join(\"\\n\") + \"\\n</table>\\n\");\nconsole.error(ids.length + \" runs indexed\");' \"$HOME/.jos/runs\" \"$dir/index.html\" || { rmdir \"$dir\"; exit 1; }\nprintf %s \"$dir\"",
|
|
42
|
+
"index"
|
|
43
|
+
],
|
|
44
|
+
"execution": {
|
|
45
|
+
"env": [
|
|
46
|
+
"PATH",
|
|
47
|
+
"HOME",
|
|
48
|
+
"TMPDIR"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"as": "site",
|
|
52
|
+
"description": "Write index.html for ~/.jos/runs into a new temporary folder"
|
|
53
|
+
},
|
|
54
|
+
"serve": {
|
|
55
|
+
"engine": "shell",
|
|
56
|
+
"run": [
|
|
57
|
+
"/bin/sh",
|
|
58
|
+
"-c",
|
|
59
|
+
"dir=$(node -e 'let s = \"\"; process.stdin.on(\"data\", (d) => { s += d; }).on(\"end\", () => { process.stdout.write(String(JSON.parse(s).input.dir)); });') || exit 2\ncase \"$dir\" in \"\"|\"$HOME/.jos\"|\"$HOME/.jos/\"*) echo \"refusing to serve $dir\" >&2; exit 2;; esac\n[ -f \"$dir/index.html\" ] || { echo \"no index in $dir\" >&2; exit 2; }\ncommand -v python3 >/dev/null 2>&1 || { echo \"python3 is not installed\" >&2; rm -f \"$dir/index.html\"; rmdir \"$dir\"; exit 3; }\nport=\"${JOS_SERVE_PORT:-8765}\"\nsecs=\"${JOS_SERVE_SECONDS:-60}\"\nlog=\"$dir.log\"\npython3 -u -m http.server \"$port\" --bind 127.0.0.1 --directory \"$dir\" >\"$log\" 2>/dev/null &\npid=$!\nn=0\nuntil grep -q '^Serving HTTP on' \"$log\" 2>/dev/null; do\n if ! kill -0 \"$pid\" 2>/dev/null; then echo \"python3 could not serve on 127.0.0.1:$port (is the port in use?)\" >&2; rm -f \"$dir/index.html\" \"$log\"; rmdir \"$dir\"; exit 1; fi\n if [ \"$n\" -ge 600 ]; then echo \"python3 did not start serving on 127.0.0.1:$port within 60 s\" >&2; kill \"$pid\" 2>/dev/null; wait \"$pid\" 2>/dev/null; rm -f \"$dir/index.html\" \"$log\"; rmdir \"$dir\"; exit 1; fi\n n=$((n + 1))\n sleep 0.1\ndone\nsleep \"$secs\"\nkill \"$pid\" 2>/dev/null\nwait \"$pid\" 2>/dev/null\nrm -f \"$dir/index.html\" \"$log\"\nrmdir \"$dir\"\necho \"served a read-only index of ~/.jos/runs from $dir on http://127.0.0.1:$port/ for $secs s; stopped and removed it\"",
|
|
60
|
+
"serve"
|
|
61
|
+
],
|
|
62
|
+
"execution": {
|
|
63
|
+
"env": [
|
|
64
|
+
"PATH",
|
|
65
|
+
"HOME",
|
|
66
|
+
"JOS_SERVE_PORT",
|
|
67
|
+
"JOS_SERVE_SECONDS"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"needs": [
|
|
71
|
+
"index"
|
|
72
|
+
],
|
|
73
|
+
"with": {
|
|
74
|
+
"dir": "{{ site }}"
|
|
75
|
+
},
|
|
76
|
+
"description": "python3 -m http.server --bind 127.0.0.1 on that folder, counted from the moment it says it is serving, then remove it"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"flows": {
|
|
80
|
+
"main": {
|
|
81
|
+
"steps": [
|
|
82
|
+
"index",
|
|
83
|
+
"serve"
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# The tour
|
|
2
|
+
|
|
3
|
+
Each example is one capability of `jos`, and each one runs. Copy the folder first, so the runs do not write into
|
|
4
|
+
the installed package (a run of `05-sealed` keeps its ledger in `05-sealed/.jos/replays/`; the others in
|
|
5
|
+
`~/.jos/runs/`):
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
cp -R "$(npm root -g)/@josfox/jos/examples" jos-tour && cd jos-tour
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Every `jos run` prints the document's intention before it runs (`Intention`, `Done when`, `Avoid`, `Limit`), then
|
|
12
|
+
the verdict of each criterion as jos-core evaluated it, then `Intention met` or `Intention NOT met (code N: …)`.
|
|
13
|
+
`--json` prints jos-core's result object instead, unchanged.
|
|
14
|
+
|
|
15
|
+
| Example | Command | Result |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `01-hello.jos` | `jos run 01-hello.jos` | prints `hello, .jos`; `✓ Intention met`; exit 0 |
|
|
18
|
+
| `02-criteria.jos` | `jos run 02-criteria.jos` | one verdict line per criterion: `exit`, `stdout_contains`, `stdout_matches`, `stderr_empty`, `not`, and a descriptive one (recorded, never evaluated); exit 0. Change the `echo` text and it is exit 1 |
|
|
19
|
+
| `03-flow-gate.jos` | `jos run 03-flow-gate.jos` | `build` runs, the human gate stops the flow: `Intention NOT met (code 1: not done)` and the command to approve; exit 1 |
|
|
20
|
+
| | `jos run 03-flow-gate.jos --approve build` | `build`, then `publish`; prints `published`; exit 0 |
|
|
21
|
+
| | `jos run 03-flow-gate.jos --flow build-only` | runs the other flow of the document (`build` only); exit 0 |
|
|
22
|
+
| `04-use-template/` | `jos run 04-use-template/use.jos --library 04-use-template/lib` | one template, used twice with `with`, pinned by its digest; prints `hello, Leo`; exit 0. See [its README](04-use-template/README.md) |
|
|
23
|
+
| | `jos run 04-use-template/lib/greeting.jos --with '{"name":"Ana"}'` | the template run directly; prints `hello, Ana`; exit 0 |
|
|
24
|
+
| `05-sealed/` | `jos run 05-sealed` | the folder runs while its hash matches `integrity.hash`; exit 0. Edit it and it is exit 3. See [its README](05-sealed/README.md) |
|
|
25
|
+
| `06-requires.jos` | `jos run 06-requires.jos` | needs a `payments` service this runtime does not provide: refused before anything starts, `/requires/0: not satisfied`; exit 5 |
|
|
26
|
+
| `07-sandbox.jos` | `jos run 07-sandbox.jos` | `security.tier: sandbox`, and this kernel cannot confine a process: refused, `sandbox not available`; exit 5 |
|
|
27
|
+
| `08-ids-ledger-meter.md` | the commands in it | `jos ids`, `jos runs`, `jos ledger verify`, `jos meter` over the runs above |
|
|
28
|
+
| `10-ollama.jos` | `jos run 10-ollama.jos` | checks `http://localhost:11434`; without Ollama it says so and sends nothing (exit 1); with Ollama the objective goes to `ollama run ${OLLAMA_MODEL:-llama3.2}` and the answer is printed (exit 0) |
|
|
29
|
+
| `11-openai.jos` | `jos secrets exec --only OPENAI_API_KEY -- jos run 11-openai.jos` | the objective to the OpenAI Responses API (`${OPENAI_MODEL:-gpt-5-mini}`); prints the answer; exit 0. Without the key: `OPENAI_API_KEY is not set: no request was sent.`, exit 1 |
|
|
30
|
+
| `12-gemini.jos` | `jos secrets exec --only GEMINI_API_KEY -- jos run 12-gemini.jos` | the same with the Gemini API (`${GEMINI_MODEL:-gemini-2.5-flash}`) |
|
|
31
|
+
| `13-anthropic.jos` | `jos secrets exec --only ANTHROPIC_API_KEY -- jos run 13-anthropic.jos` | the same with the Anthropic Messages API (`${ANTHROPIC_MODEL:-claude-opus-5-5}`) |
|
|
32
|
+
| `14-serve.jos` | `jos run 14-serve.jos` | writes a read-only HTML index of `~/.jos/runs` into a new temporary folder and serves only that folder with `python3 -m http.server --bind 127.0.0.1` on port `${JOS_SERVE_PORT:-8765}` for `${JOS_SERVE_SECONDS:-60}` seconds, counted from the moment python3 says it is serving (it may take a few seconds to listen; at most 60 s), then removes it; exit 0 |
|
|
33
|
+
|
|
34
|
+
`hello.jos` is the document `jos verify` runs.
|
|
35
|
+
|
|
36
|
+
## The provider examples and your keys
|
|
37
|
+
|
|
38
|
+
`11`, `12` and `13` are shell steps that call the provider's REST API with `curl`. They are paid calls on your
|
|
39
|
+
account. Store a key once, then give it only to the run that needs it:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
jos secrets set OPENAI_API_KEY --stdin # type or paste the key; it is not echoed
|
|
43
|
+
jos secrets exec --only OPENAI_API_KEY -- jos run 11-openai.jos
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
What happens to the key: `jos secrets exec` puts it only in the environment of that `jos run`; the document's
|
|
47
|
+
`execution.env` lets it reach the step; the step hands it to `curl` on stdin (`-H @-`), so it is never on a command
|
|
48
|
+
line; the examples never print it, and an error message from the API is printed with the key replaced by `[key]`.
|
|
49
|
+
The key is not in the receipts or the ledger: a receipt records the step's code, its criteria verdicts and hashes
|
|
50
|
+
of its input and output, never the environment (the test suite checks the ledger, the result and the output for
|
|
51
|
+
the key). The answer itself is printed
|
|
52
|
+
to your terminal and not stored. The model's tokens and cost are not recorded either: the `shell` engine does not
|
|
53
|
+
report them, so `jos meter` shows them as "not reported".
|
|
54
|
+
|
|
55
|
+
## What `jos run` prints (NO_COLOR)
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
$ jos run 03-flow-gate.jos
|
|
59
|
+
|
|
60
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
61
|
+
JOS RUN // jos-core 2.0.0
|
|
62
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
63
|
+
|
|
64
|
+
File: 03-flow-gate.jos
|
|
65
|
+
|
|
66
|
+
Intention: Build, wait for a person to approve the build, then publish
|
|
67
|
+
Done when:
|
|
68
|
+
• exit 0
|
|
69
|
+
Avoid: "rm -rf"
|
|
70
|
+
Limit: 10 s, 65536 output bytes per stream, 0 retries
|
|
71
|
+
|
|
72
|
+
ID: art_572a58662e9e76761b6844bfd091ed08636023e39ce10cd13dc1cdf463741d96
|
|
73
|
+
Input version: 2.0.0
|
|
74
|
+
Capability: cap_01M5DX8R8WT15PS3SQV70CV2PM (local-trusted)
|
|
75
|
+
Ledger: ~/.jos/runs/run_01M5DX8R8TCEQ2D7DESRZQH8JG/ledger.jsonl
|
|
76
|
+
|
|
77
|
+
built
|
|
78
|
+
|
|
79
|
+
Verdict:
|
|
80
|
+
[1] build ✓ code 0
|
|
81
|
+
✓ stdout_contains: found
|
|
82
|
+
[1] tour.flow-gate (flow main) ✖ code 1
|
|
83
|
+
✓ exit: exit 0 (want 0)
|
|
84
|
+
|
|
85
|
+
✖ Intention NOT met (code 1: not done) (run_01M5DX8R8TCEQ2D7DESRZQH8JG)
|
|
86
|
+
gate human: waiting for an approval of "build"
|
|
87
|
+
To approve it: jos run 03-flow-gate.jos --approve build
|
|
88
|
+
|
|
89
|
+
$ jos run 03-flow-gate.jos --approve build
|
|
90
|
+
…
|
|
91
|
+
published
|
|
92
|
+
|
|
93
|
+
Verdict:
|
|
94
|
+
[1] build ✓ code 0
|
|
95
|
+
✓ stdout_contains: found
|
|
96
|
+
[1] publish ✓ code 0
|
|
97
|
+
✓ stdout_contains: found
|
|
98
|
+
[1] tour.flow-gate (flow main) ✓ code 0
|
|
99
|
+
✓ exit: exit 0 (want 0)
|
|
100
|
+
|
|
101
|
+
✓ Intention met (code 0, run_01M5DX8R9YSZT1S7GKJJJNS9MM)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The `run_` and `cap_` ids and the ledger path are yours; the `art_` is the same on every machine and in both
|
|
105
|
+
reference kernels, because it is the hash of the document's content.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jos": {
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"kind": "atom"
|
|
5
|
+
},
|
|
6
|
+
"id": "hello",
|
|
7
|
+
"meta": {
|
|
8
|
+
"name": "hello",
|
|
9
|
+
"version": "1.0.0"
|
|
10
|
+
},
|
|
11
|
+
"intention": {
|
|
12
|
+
"objective": "Print a greeting and exit cleanly",
|
|
13
|
+
"success_criteria": [
|
|
14
|
+
{
|
|
15
|
+
"exit": 0
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"stdout_contains": "hello"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"guardrails": {
|
|
23
|
+
"avoid": [
|
|
24
|
+
"rm -rf",
|
|
25
|
+
"curl",
|
|
26
|
+
"wget"
|
|
27
|
+
],
|
|
28
|
+
"limit": {
|
|
29
|
+
"seconds": 5,
|
|
30
|
+
"output_bytes": 65536,
|
|
31
|
+
"retries": 0
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"execution": {
|
|
35
|
+
"engine": "shell",
|
|
36
|
+
"run": [
|
|
37
|
+
"echo",
|
|
38
|
+
"hello, .jos"
|
|
39
|
+
],
|
|
40
|
+
"on_error": "fail",
|
|
41
|
+
"env": [
|
|
42
|
+
"PATH",
|
|
43
|
+
"HOME"
|
|
44
|
+
],
|
|
45
|
+
"cwd": "."
|
|
46
|
+
}
|
|
47
|
+
}
|
package/package.json
CHANGED
|
@@ -1,40 +1,57 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@josfox/jos",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"license": "
|
|
6
|
-
"author": "
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/josfox-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
},
|
|
27
|
-
"files": [
|
|
28
|
-
"bin/",
|
|
29
|
-
"src/"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@josfox/jos",
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Host CLI for the jos-core kernel: run and validate .jos documents (2.0.0, 1.1.0, 1.0.0, 0.0.7). Offline first.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Josué Emmanuel Gómez Carrillo (JOSFOX LLC)",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/josfox-jos/jos.git",
|
|
10
|
+
"directory": "packages/jos"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/josfox-jos/jos/tree/main/packages/jos",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"cli",
|
|
15
|
+
"ai",
|
|
16
|
+
"agent",
|
|
17
|
+
"orchestration",
|
|
18
|
+
"jos",
|
|
19
|
+
"josfox",
|
|
20
|
+
"artifacts",
|
|
21
|
+
"offline-first",
|
|
22
|
+
"zero-dependencies"
|
|
23
|
+
],
|
|
24
|
+
"bin": {
|
|
25
|
+
"jos": "bin/jos"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"bin/",
|
|
29
|
+
"src/",
|
|
30
|
+
"examples/",
|
|
31
|
+
"SECURITY-SECRETS.md",
|
|
32
|
+
"SECURITY-MCP.md",
|
|
33
|
+
"STYLE.md",
|
|
34
|
+
"PROMISES.md",
|
|
35
|
+
"promises.json",
|
|
36
|
+
"!src/commands/_frozen/",
|
|
37
|
+
"src/commands/_frozen/*.README.md"
|
|
38
|
+
],
|
|
39
|
+
"type": "commonjs",
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=18"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@josfox/jos-core": "^2.0.0"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"test": "node test/gate.js",
|
|
48
|
+
"test:cli": "node bin/jos verify",
|
|
49
|
+
"test:coverage": "node test/coverage.js",
|
|
50
|
+
"test:host": "node --test test/host.test.js",
|
|
51
|
+
"test:promises": "node --test test/promises.test.js",
|
|
52
|
+
"promises:md": "node test/promises-md.js",
|
|
53
|
+
"promises:check": "node test/promises-md.js --check",
|
|
54
|
+
"test:secrets": "node --test --experimental-test-coverage --test-coverage-include=src/commands/secrets.js --test-coverage-lines=100 --test-coverage-branches=100 --test-coverage-functions=100 test/secrets.test.js",
|
|
55
|
+
"test:mcp": "node --test --experimental-test-coverage --test-coverage-include=src/mcp.js --test-coverage-lines=100 --test-coverage-branches=100 --test-coverage-functions=100 test/mcp.test.js"
|
|
56
|
+
}
|
|
57
|
+
}
|