@podo/skill-validator 0.0.0-stage → 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.
- package/LICENSE +21 -0
- package/README.md +286 -2
- package/THIRD_PARTY_NOTICES.md +58 -0
- package/dist/cli.js +8612 -0
- package/package.json +34 -4
- package/schema/report.schema.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Giedrius Jaloveckas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,287 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Skill Validator CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Offline Node 22+ validator for directories containing `SKILL.md`. Uses the
|
|
4
|
+
website's deterministic rules, security heuristics, static package checks, and
|
|
5
|
+
token estimates. No network requests, AI calls, or execution of skill scripts.
|
|
6
|
+
|
|
7
|
+
**Public npm package:** `@podo/skill-validator`. Stable installations should pin
|
|
8
|
+
`0.1.0`; verify its registry publication before installing it.
|
|
9
|
+
The package does not require Cloudsmith or Nexus. Direct npm downloads from the
|
|
10
|
+
target Jenkins agent still need a network/policy check. The source repository
|
|
11
|
+
does not need to move to distribute this package.
|
|
12
|
+
|
|
13
|
+
## Try locally
|
|
14
|
+
|
|
15
|
+
From the repository root:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm --prefix cli ci
|
|
19
|
+
npm --prefix cli run build
|
|
20
|
+
node cli/dist/cli.js validate cli/test/fixtures/skills/csv-summary
|
|
21
|
+
node cli/dist/cli.js --help
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Build an installable tarball with `npm pack` from `cli/`, then install that
|
|
25
|
+
tarball in another project with `npm install -D /absolute/path/to/the.tgz`.
|
|
26
|
+
Both `skill-validator` and `skillval` invoke the same command.
|
|
27
|
+
|
|
28
|
+
## Install from public npm
|
|
29
|
+
|
|
30
|
+
**After the stable release is published and verified**, pin its exact version:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm install --save-dev --save-exact --ignore-scripts \
|
|
34
|
+
@podo/skill-validator@0.1.0 \
|
|
35
|
+
--registry=https://registry.npmjs.org/
|
|
36
|
+
./node_modules/.bin/skill-validator validate skills
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Commit the manifest and lockfile for reproducible installs. Public consumers need
|
|
40
|
+
no npm credentials. An existing `@podo:registry` mapping takes precedence over the
|
|
41
|
+
default registry; remove an obsolete mapping or explicitly set
|
|
42
|
+
`--@podo:registry=https://registry.npmjs.org/` for this command.
|
|
43
|
+
|
|
44
|
+
The public package and its bundled first-party validator engine are MIT-licensed;
|
|
45
|
+
see [`LICENSE`](LICENSE). Bundled dependency licenses are preserved in
|
|
46
|
+
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md). This does not change the license
|
|
47
|
+
of the rest of the website repository.
|
|
48
|
+
|
|
49
|
+
## Commands
|
|
50
|
+
|
|
51
|
+
After installing the package locally:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
skill-validator validate skills
|
|
55
|
+
skill-validator skills/foo/SKILL.md # validate is the default command
|
|
56
|
+
skill-validator doctor # install/config/discovery diagnostics
|
|
57
|
+
skill-validator rules list # web-only rules are marked [web/live only]
|
|
58
|
+
skill-validator rules explain B4
|
|
59
|
+
skill-validator prompt skills/foo # offline repair prompt, to stdout
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
With no paths, discovery starts at `skills/` in the current directory if it
|
|
63
|
+
exists, otherwise at the current directory. Paths must stay within the nearest
|
|
64
|
+
Git repository root (or the current directory when outside Git).
|
|
65
|
+
|
|
66
|
+
### Reports and flags
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
skill-validator validate skills --format json --out report.json
|
|
70
|
+
skill-validator validate skills --format junit,json,markdown --report-dir reports
|
|
71
|
+
skill-validator validate skills --fail-on critical --quiet
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- `--format`: comma-separated `text,json,junit,markdown`; default `text`.
|
|
75
|
+
- `--report-dir`: required for multiple formats. Fixed filenames are
|
|
76
|
+
`report.txt`, `report.json`, `junit.xml`, and `report.md`.
|
|
77
|
+
- `--out`: a single-format destination; `-` means stdout. Mutually exclusive
|
|
78
|
+
with `--report-dir`. Outputs must stay inside the repository and outside skill
|
|
79
|
+
directories, so reports cannot overwrite skill source.
|
|
80
|
+
- `--fail-on`: `critical`, `high`, `suggestion`, `info`, or `none`; default `high`.
|
|
81
|
+
- `--quiet`: counts and gate line only in text output; machine formats stay intact.
|
|
82
|
+
- `--config`: explicit config path, otherwise `.skill-validator.json` at repo root.
|
|
83
|
+
|
|
84
|
+
File output creates parent directories and writes atomically. Its short summary
|
|
85
|
+
goes to stderr; stdout JSON/XML is not mixed with logs. Text is uncolored. Text
|
|
86
|
+
and Markdown cap output at 20 findings per skill; JSON and JUnit are complete.
|
|
87
|
+
Destinations inside any skill are refused, including unselected or ignored skills
|
|
88
|
+
and filesystem case aliases. Failed writes remove their owned temporary file and
|
|
89
|
+
leave any existing destination intact.
|
|
90
|
+
|
|
91
|
+
Exit codes:
|
|
92
|
+
|
|
93
|
+
- `0`: no findings meet the configured threshold.
|
|
94
|
+
- `1`: findings fail the gate.
|
|
95
|
+
- `2`: invalid invocation, config, missing skills, incomplete discovery,
|
|
96
|
+
unreadable or refused input, or output I/O failure. A closed stdout/stderr pipe
|
|
97
|
+
exits 2 without an unhandled stack trace and without forcing pending output to
|
|
98
|
+
be truncated.
|
|
99
|
+
- `3`: internal CLI error; prints the version, Node version, and the npm package
|
|
100
|
+
page (the source repository is private, so there is no issue tracker link). Set
|
|
101
|
+
`SKILL_VALIDATOR_DEBUG=1` for a stack trace, which may contain sensitive data.
|
|
102
|
+
|
|
103
|
+
Zero skills is never a successful validation. `doctor` can report zero skills
|
|
104
|
+
without failing because it is diagnostic, not a gate.
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
|
|
108
|
+
The default gate is `high`. A team can initially choose `critical` with reviewed
|
|
109
|
+
severity overrides, then tighten the gate after checking real skills:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"failOn": "critical",
|
|
114
|
+
"ruleSeverities": {
|
|
115
|
+
"TT-003": "high",
|
|
116
|
+
"DE-002": "suggestion"
|
|
117
|
+
},
|
|
118
|
+
"ignore": ["drafts/**"]
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Flags override config. Unknown keys, rule IDs, and severity values are errors,
|
|
123
|
+
as are overrides for web/live-only rules (AI-assisted review, URL/registry
|
|
124
|
+
liveness, HP-001): the CLI never reports them, so an override cannot take effect.
|
|
125
|
+
Overrides change visible findings and preserve `originalSeverity` in JSON;
|
|
126
|
+
they do not hide rules. First-party API integrations can legitimately read tokens
|
|
127
|
+
and make requests, which is why the example recalibrates those security rules.
|
|
128
|
+
|
|
129
|
+
`ignore` accepts repo-relative glob patterns and affects **skill discovery only**.
|
|
130
|
+
Each pattern is limited to 1,024 characters and 128 glob operators; invalid or
|
|
131
|
+
unevaluable patterns are configuration errors, not internal crashes.
|
|
132
|
+
It cannot hide files inside a discovered skill. `.git` and `node_modules` are
|
|
133
|
+
excluded at the root of a skill only; nested copies (for example
|
|
134
|
+
`scripts/node_modules`) are scanned and count toward the per-skill limits below.
|
|
135
|
+
Discovery itself never descends into `.git` or `node_modules`. Protect CI configuration with CODEOWNERS/review requirements:
|
|
136
|
+
a PR-controlled threshold can otherwise weaken its own gate.
|
|
137
|
+
|
|
138
|
+
## Scope and safety
|
|
139
|
+
|
|
140
|
+
- Discovery descends at most four directories below each input root. If any
|
|
141
|
+
eligible directory (not ignored, not `.git`/`node_modules`) lies below that
|
|
142
|
+
limit, the run exits 2 and names it, even when other skills were found, so a
|
|
143
|
+
gate never passes on a partly searched tree. Pass a narrower root, or add
|
|
144
|
+
directories without skills to `ignore`. `doctor` reports them without failing.
|
|
145
|
+
Overlapping inputs are deduplicated, including explicit nested inputs. Nested
|
|
146
|
+
skills stay in their parent bundle so rule A0 can report them. A skill's contents
|
|
147
|
+
are loaded as a complete bundle rather than subject to the discovery depth limit.
|
|
148
|
+
- Symlinks and nonregular skill files are refused. Per-skill limits are 2,000 files,
|
|
149
|
+
100 MiB total file size, and 5 MiB per text file. Discovery and bundle traversal
|
|
150
|
+
each cap directories at 10,000; discovery counts unique directories, not repeated
|
|
151
|
+
overlapping visits. Bundle nesting is capped at 64.
|
|
152
|
+
- Archives are not CLI inputs. Binary files contribute metadata and size, not
|
|
153
|
+
decoded content. Skills and inputs are never executed.
|
|
154
|
+
- JavaScript `.js`, `.mjs`, and `.cjs` files are decoded and security-scanned with
|
|
155
|
+
the same executable-risk weighting. Malformed frontmatter mappings and eval
|
|
156
|
+
document/case shapes produce findings instead of passing silently or crashing.
|
|
157
|
+
- These checks bound ordinary validation; they are not a sandbox against a
|
|
158
|
+
separate process maliciously changing directories during a scan.
|
|
159
|
+
- Security patterns currently report the first matching occurrence per rule/file.
|
|
160
|
+
A passing result is not proof a skill is safe or effective.
|
|
161
|
+
|
|
162
|
+
The website additionally performs liveness and optional AI review, so its complete
|
|
163
|
+
report can differ. CLI reports explicitly list `ai-review` and `liveness` as not
|
|
164
|
+
run. Static known-hallucinated-package rule HP-002 still runs offline.
|
|
165
|
+
|
|
166
|
+
### Report contract and privacy
|
|
167
|
+
|
|
168
|
+
JSON has `schemaVersion: 1`, relative paths, stable finding fingerprints, and an
|
|
169
|
+
explicit `gate`. The published package includes
|
|
170
|
+
[`schema/report.schema.json`](schema/report.schema.json). Fingerprints normalize
|
|
171
|
+
line endings and include diagnostic text so separate eval cases stay distinct.
|
|
172
|
+
They exclude line numbers and severity; wording changes can change an identifier.
|
|
173
|
+
They are identifiers, not a baseline feature.
|
|
174
|
+
Legal POSIX names such as colons and newlines retain their identity. A relative
|
|
175
|
+
path that could be read as a Windows drive-absolute or rooted path (a drive letter
|
|
176
|
+
and colon followed by a separator or nothing, or a leading backslash) is prefixed
|
|
177
|
+
with `./`; the prefixed path resolves to the same file. Absolute and `..` paths
|
|
178
|
+
never appear in reports.
|
|
179
|
+
|
|
180
|
+
JUnit includes one failing testcase per blocking finding and an `@summary` case
|
|
181
|
+
per skill. A testcase is named by rule ID; when a rule blocks more than once in
|
|
182
|
+
a skill, the name becomes `<ruleId>:<fingerprint>` so cases stay distinct.
|
|
183
|
+
Advisory findings are neither failures nor fake skipped tests. Counts match the
|
|
184
|
+
gate; timestamps and durations are omitted for stable output.
|
|
185
|
+
XML attribute encoding preserves tabs, newlines, and carriage returns in paths,
|
|
186
|
+
so distinct files do not merge into the same Jenkins testcase identity.
|
|
187
|
+
|
|
188
|
+
Security snippets are omitted from reports and from repair prompts, and common
|
|
189
|
+
credential patterns are redacted from both. This is best-effort, not complete
|
|
190
|
+
secret detection. Prompts still quote other source content (for example
|
|
191
|
+
descriptions and suggested replacements), and reports include skill paths and
|
|
192
|
+
finding text. Treat both as potentially sensitive; use appropriate artifact
|
|
193
|
+
access/retention. Text and Markdown output show control characters in paths as
|
|
194
|
+
visible `\uXXXX` escapes; JSON keeps the exact path.
|
|
195
|
+
|
|
196
|
+
## Jenkins advisory example
|
|
197
|
+
|
|
198
|
+
**After publishing and verifying direct registry access:** add a separate stage
|
|
199
|
+
to the existing pipeline and preserve all existing checks. The example assumes
|
|
200
|
+
Node 22+ is already available and skills live under `plugins/`; adapt this path
|
|
201
|
+
to the consuming repository. It uses an exact package version without adding
|
|
202
|
+
application dependencies to that repository. A consumer with a package manifest
|
|
203
|
+
can instead commit a pinned devDependency/lockfile and use `npm ci --ignore-scripts`.
|
|
204
|
+
|
|
205
|
+
```groovy
|
|
206
|
+
stage('Skill Validator (advisory)') {
|
|
207
|
+
steps {
|
|
208
|
+
// Remove stale artifacts before invocation, including crash paths.
|
|
209
|
+
dir('skill-validator-report') { deleteDir() }
|
|
210
|
+
script {
|
|
211
|
+
def status = sh(returnStatus: true, script: '''
|
|
212
|
+
npm exec --yes --ignore-scripts \
|
|
213
|
+
--registry=https://registry.npmjs.org/ \
|
|
214
|
+
--@podo:registry=https://registry.npmjs.org/ \
|
|
215
|
+
--package=@podo/skill-validator@0.1.0 -- \
|
|
216
|
+
skill-validator validate plugins --fail-on none \
|
|
217
|
+
--format junit,json,markdown \
|
|
218
|
+
--report-dir skill-validator-report --quiet
|
|
219
|
+
''')
|
|
220
|
+
if (status != 0) {
|
|
221
|
+
error("skill-validator input/tool failure (${status}); see log")
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
post {
|
|
226
|
+
always {
|
|
227
|
+
archiveArtifacts artifacts: 'skill-validator-report/*', allowEmptyArchive: true
|
|
228
|
+
junit testResults: 'skill-validator-report/junit.xml', allowEmptyResults: false
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
`--fail-on none` keeps findings advisory; invalid input, failed downloads, and tool
|
|
235
|
+
errors remain blocking. Missing JUnit is an error, not an empty successful run.
|
|
236
|
+
Protect policy files and preserve the marketplace's existing validation stages.
|
|
237
|
+
This example has not yet been executed on a Jenkins agent; it does not establish
|
|
238
|
+
permission to bypass any employer-required registry proxy.
|
|
239
|
+
|
|
240
|
+
## Development
|
|
241
|
+
|
|
242
|
+
From `cli/`, run `npm ci`, `npm run typecheck`, and `npm test`. The tests build
|
|
243
|
+
the bundle, validate report schemas/JUnit, exercise the exit-code and filesystem
|
|
244
|
+
contracts, and install a packed tarball without runtime dependencies.
|
|
245
|
+
Release-orchestration tests simulate identity/registry/upload responses while
|
|
246
|
+
using real npm packing; they never upload a package or request credentials.
|
|
247
|
+
Also run root typecheck, tests, and build when changing shared engine code.
|
|
248
|
+
The test suite uses Python 3's standard library for XML round-trips and isolated
|
|
249
|
+
OS-level write/pipe fault injection; Python is not a package runtime dependency.
|
|
250
|
+
The repository CI workflow (`.github/workflows/ci.yml`) runs these checks for
|
|
251
|
+
the application, CLI, and server across its OS/Node matrix. It never publishes
|
|
252
|
+
packages or deploys the app.
|
|
253
|
+
|
|
254
|
+
## Publishing
|
|
255
|
+
|
|
256
|
+
The release script targets **public npm**, not an internal registry, and verifies
|
|
257
|
+
the signed-in account is `podo`. Sign in from your own terminal:
|
|
258
|
+
|
|
259
|
+
```sh
|
|
260
|
+
npm login --registry=https://registry.npmjs.org/
|
|
261
|
+
npm whoami --registry=https://registry.npmjs.org/
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Use npm's browser/2FA flow; never paste credentials into chat or tracked files.
|
|
265
|
+
The script uses existing npm authentication without copying or printing secrets.
|
|
266
|
+
Public publishing requires the account's applicable 2FA or npm-approved automation
|
|
267
|
+
authentication. A successful dry-run is not proof of publishing permission.
|
|
268
|
+
|
|
269
|
+
- `scripts/publish-cli.sh dry-run`: installs build dependencies without lifecycle
|
|
270
|
+
scripts, typechecks, tests, and packs an audited tarball. No authentication,
|
|
271
|
+
registry availability request, or upload; allowed before committing.
|
|
272
|
+
- `scripts/publish-cli.sh test`: requires a clean committed tree and a unique
|
|
273
|
+
prerelease version, then publishes the exact checked tarball with `canary`.
|
|
274
|
+
- `scripts/publish-cli.sh release`: additionally requires a stable version and an
|
|
275
|
+
exact matching `cli-vX.Y.Z` tag on HEAD, then publishes with `latest`.
|
|
276
|
+
|
|
277
|
+
Both publishing modes pin default **and scoped** registries, check identity and
|
|
278
|
+
version availability, and stop on registry errors. An existing exact version is
|
|
279
|
+
not overwritten; use a new version for changed bytes. The packed allowlist is
|
|
280
|
+
only the executable, schema, package metadata, README, license, and dependency
|
|
281
|
+
notices. Inspect the artifact for sensitive material before the first upload.
|
|
282
|
+
|
|
283
|
+
CLI tags are independent of web `vX.Y.Z` tags and do not require a Playground
|
|
284
|
+
deploy. After each release, verify its public access and integrity,
|
|
285
|
+
install it in a clean directory without credentials, and run it on a real Jenkins
|
|
286
|
+
agent before enabling consumer integration. Publication does not establish
|
|
287
|
+
Jenkins compatibility: that remains a separate acceptance check.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Bundled dependency notices
|
|
2
|
+
|
|
3
|
+
The CLI bundles the following third-party software. These notices apply to that
|
|
4
|
+
software; the CLI and its bundled first-party validator engine use the MIT
|
|
5
|
+
license in `LICENSE`. No dependency code has been intentionally modified; the
|
|
6
|
+
build bundles and transforms it for Node.js.
|
|
7
|
+
|
|
8
|
+
## js-yaml
|
|
9
|
+
|
|
10
|
+
Source: https://github.com/nodeca/js-yaml
|
|
11
|
+
|
|
12
|
+
(The MIT License)
|
|
13
|
+
|
|
14
|
+
Copyright (C) 2011-2015 by Vitaly Puzrin
|
|
15
|
+
|
|
16
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
18
|
+
in the Software without restriction, including without limitation the rights
|
|
19
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
20
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
21
|
+
furnished to do so, subject to the following conditions:
|
|
22
|
+
|
|
23
|
+
The above copyright notice and this permission notice shall be included in
|
|
24
|
+
all copies or substantial portions of the Software.
|
|
25
|
+
|
|
26
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
27
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
28
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
29
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
30
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
31
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
32
|
+
THE SOFTWARE.
|
|
33
|
+
|
|
34
|
+
## picomatch
|
|
35
|
+
|
|
36
|
+
Source: https://github.com/micromatch/picomatch
|
|
37
|
+
|
|
38
|
+
The MIT License (MIT)
|
|
39
|
+
|
|
40
|
+
Copyright (c) 2017-present, Jon Schlinkert.
|
|
41
|
+
|
|
42
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
43
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
44
|
+
in the Software without restriction, including without limitation the rights
|
|
45
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
46
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
47
|
+
furnished to do so, subject to the following conditions:
|
|
48
|
+
|
|
49
|
+
The above copyright notice and this permission notice shall be included in
|
|
50
|
+
all copies or substantial portions of the Software.
|
|
51
|
+
|
|
52
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
53
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
54
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
55
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
56
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
57
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
58
|
+
THE SOFTWARE.
|