coding-agent-skills 0.2.16 → 0.2.17
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/CHANGELOG.md +9 -0
- package/README.md +8 -1
- package/bin/coding-agent-skills +2 -2
- package/docs/adapters/README.md +6 -0
- package/docs/adapters/project-installation.md +6 -0
- package/docs/release/npm-package.md +1 -1
- package/docs/usage/README.md +9 -7
- package/package.json +1 -1
- package/scripts/lib/adapter-repo-map.mjs +194 -12
- package/scripts/test-pack.mjs +43 -2
- package/scripts/validate-pack.mjs +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes follow [Semantic Versioning](docs/versioning/README.md).
|
|
4
4
|
|
|
5
|
+
## [0.2.17] - 2026-07-04
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- `repo-map` now supports generic safe discovery when no `.coding-agent` project declaration exists.
|
|
10
|
+
- JSON output now reports `adapterPresent: false`, `mode: generic-safe-discovery`, reduced confidence, `changedState: false`, no target-project commands, and no secret-file reads for no-adapter repo-map runs.
|
|
11
|
+
- Invalid or unsafe project adapters still fail closed instead of falling back silently.
|
|
12
|
+
- Usage, adapter, and release documentation now clarify that adapters are optional hints, not mandatory requirements.
|
|
13
|
+
|
|
5
14
|
## [0.2.16] - 2026-07-03
|
|
6
15
|
|
|
7
16
|
### Added
|
package/README.md
CHANGED
|
@@ -60,7 +60,8 @@ Every skill emits the evidence-pack contract. A command being attempted is never
|
|
|
60
60
|
- Run `node scripts/validate-adapters.mjs <adapter-root>` for a disposable external root.
|
|
61
61
|
- Review [project-owned installation and pinning](docs/adapters/project-installation.md).
|
|
62
62
|
- Run `node scripts/validate-project-adapters.mjs <project-root>` for a declared project root.
|
|
63
|
-
- Render
|
|
63
|
+
- Render repo-map orientation with optional adapter hints and generic safe
|
|
64
|
+
discovery when no adapter is present:
|
|
64
65
|
`node scripts/render-adapter-repo-map.mjs <project-root>`.
|
|
65
66
|
- Render a static route-trace report with
|
|
66
67
|
`node scripts/render-route-trace.mjs <project-root>`.
|
|
@@ -118,6 +119,12 @@ OpenClaw should remain the owner of memory, routing, permissions, scheduling, us
|
|
|
118
119
|
interaction, and workflow state. `coding-agent-skills` is a safe callable evidence
|
|
119
120
|
producer, not an orchestrator.
|
|
120
121
|
|
|
122
|
+
Adapters are optional hints, not a prerequisite for safe orientation. `repo-map`
|
|
123
|
+
falls back to `generic-safe-discovery` when no `.coding-agent` declaration exists,
|
|
124
|
+
marks `adapterPresent: false`, reduces confidence, and still refuses target project
|
|
125
|
+
builds, tests, runtime checks, deploys, migrations, package installs, and secret-file
|
|
126
|
+
reads.
|
|
127
|
+
|
|
121
128
|
## Autonomous Maintainer Loop
|
|
122
129
|
|
|
123
130
|
The local maintainer loop reads Git tags, `ROADMAP.md`, `CHANGELOG.md`, and
|
package/bin/coding-agent-skills
CHANGED
|
@@ -42,8 +42,8 @@ const commandMetadata = {
|
|
|
42
42
|
skillId: "repo-map",
|
|
43
43
|
mode: "audit-only",
|
|
44
44
|
next: {
|
|
45
|
-
label: "Review
|
|
46
|
-
reason: "Use the reported docs, safe paths, ignored paths, and evidence requirements before choosing another action.",
|
|
45
|
+
label: "Review reported repo boundaries",
|
|
46
|
+
reason: "Use the reported docs, safe paths, ignored paths, adapter status, confidence, and evidence requirements before choosing another action.",
|
|
47
47
|
requiresApproval: false,
|
|
48
48
|
},
|
|
49
49
|
},
|
package/docs/adapters/README.md
CHANGED
|
@@ -35,6 +35,12 @@ ignored paths, required evidence, package-manager hints, repository bounds, and
|
|
|
35
35
|
Git branch state. It does not read target project file contents, run project tests or
|
|
36
36
|
builds, install packages, perform runtime checks, deploy, migrate, or read `.env` files.
|
|
37
37
|
|
|
38
|
+
Adapters are optional hints, not mandatory gates. If no `.coding-agent` declaration is
|
|
39
|
+
present, `repo-map` falls back to `generic-safe-discovery`, reports `adapterPresent: false`,
|
|
40
|
+
uses reduced confidence, applies built-in ignored paths, and still refuses target project
|
|
41
|
+
builds, tests, runtime checks, deployments, migrations, package installs, and secret-file
|
|
42
|
+
reads. Invalid or weakening adapters still fail closed.
|
|
43
|
+
|
|
38
44
|
This is agent context for safer repository understanding. It is not target-application
|
|
39
45
|
product behavior.
|
|
40
46
|
|
|
@@ -109,6 +109,12 @@ The renderer is metadata-only. It does not read target project file contents, ru
|
|
|
109
109
|
project tests, run builds, install packages, perform runtime checks, deploy, migrate, read
|
|
110
110
|
`.env` files, or modify project state.
|
|
111
111
|
|
|
112
|
+
Project adapters are optional hints. If no project declaration exists, `repo-map` still
|
|
113
|
+
runs a bounded `generic-safe-discovery` report with `adapterPresent: false`, reduced
|
|
114
|
+
confidence, built-in ignored paths, and explicit no-secret/no-build/no-runtime safety
|
|
115
|
+
warnings. A declared adapter that is invalid, unsafe, or incompatible remains a hard
|
|
116
|
+
failure.
|
|
117
|
+
|
|
112
118
|
A project-owned adapter can also enable read-only `route-trace` context:
|
|
113
119
|
|
|
114
120
|
```bash
|
|
@@ -7,7 +7,7 @@ safety model.
|
|
|
7
7
|
## Current Package Shape
|
|
8
8
|
|
|
9
9
|
- Package name: `coding-agent-skills`.
|
|
10
|
-
- Package version: `0.2.
|
|
10
|
+
- Package version: `0.2.17`.
|
|
11
11
|
- CLI bin: `coding-agent-skills` mapped to `bin/coding-agent-skills`.
|
|
12
12
|
- Module type: `module`.
|
|
13
13
|
- Dependencies: none.
|
package/docs/usage/README.md
CHANGED
|
@@ -41,16 +41,18 @@ Select the least-privileged skill that matches the request:
|
|
|
41
41
|
|
|
42
42
|
Every skill emits an evidence pack. Read `status`, skipped checks, failures, confidence, and changed state before relying on a completion claim.
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
with:
|
|
44
|
+
Render read-only `repo-map` context with:
|
|
46
45
|
|
|
47
46
|
```bash
|
|
48
47
|
node scripts/render-adapter-repo-map.mjs <project-root>
|
|
49
48
|
```
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
precedence, safe read paths, ignored paths, and required
|
|
53
|
-
|
|
50
|
+
When a project owns a compatible adapter, this validates the adapter first and reports
|
|
51
|
+
adapter-declared documentation precedence, safe read paths, ignored paths, and required
|
|
52
|
+
evidence. When no `.coding-agent` declaration exists, adapters remain optional: `repo-map`
|
|
53
|
+
uses `generic-safe-discovery`, reports `adapterPresent: false`, reduces confidence, and
|
|
54
|
+
still refuses builds, tests, runtime checks, deployments, migrations, package installs, and
|
|
55
|
+
secret-file reads.
|
|
54
56
|
|
|
55
57
|
See [examples](../../examples/README.md) for safe concrete inputs and outputs.
|
|
56
58
|
|
|
@@ -85,8 +87,8 @@ npx coding-agent-skills validate-pack
|
|
|
85
87
|
```
|
|
86
88
|
|
|
87
89
|
These commands wrap the same validated scripts shipped in the repository. `repo-map`
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
uses adapter metadata when present and valid; otherwise it falls back to generic safe
|
|
91
|
+
discovery with reduced confidence and clear adapter-absence warnings.
|
|
90
92
|
`route-trace` validates a project adapter when present, uses adapter-declared safe paths
|
|
91
93
|
when enabled, and statically reports verified route files, inferred route declarations,
|
|
92
94
|
skipped items, and not-verified runtime-dependent route classes.
|
package/package.json
CHANGED
|
@@ -30,6 +30,87 @@ const REFUSED_BEHAVIOR = [
|
|
|
30
30
|
"no project writes",
|
|
31
31
|
];
|
|
32
32
|
|
|
33
|
+
const GENERIC_IGNORED_PATHS = [
|
|
34
|
+
".git",
|
|
35
|
+
".env",
|
|
36
|
+
".env.*",
|
|
37
|
+
".next",
|
|
38
|
+
".nuxt",
|
|
39
|
+
".output",
|
|
40
|
+
".turbo",
|
|
41
|
+
".cache",
|
|
42
|
+
"node_modules",
|
|
43
|
+
"dist",
|
|
44
|
+
"build",
|
|
45
|
+
"coverage",
|
|
46
|
+
"validation-output",
|
|
47
|
+
"supabase/.temp",
|
|
48
|
+
"secrets",
|
|
49
|
+
"tokens",
|
|
50
|
+
"credentials",
|
|
51
|
+
"private",
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const GENERIC_DOCUMENTATION_PRECEDENCE = [
|
|
55
|
+
"README.md",
|
|
56
|
+
"docs/README.md",
|
|
57
|
+
"docs/kb/README.md",
|
|
58
|
+
"AGENTS.md",
|
|
59
|
+
"CLAUDE.md",
|
|
60
|
+
"RUNBOOK.md",
|
|
61
|
+
"CONTRIBUTING.md",
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const GENERIC_SAFE_READ_PATHS = [
|
|
65
|
+
"README.md",
|
|
66
|
+
"docs",
|
|
67
|
+
"app",
|
|
68
|
+
"apps",
|
|
69
|
+
"src",
|
|
70
|
+
"lib",
|
|
71
|
+
"pages",
|
|
72
|
+
"components",
|
|
73
|
+
"server",
|
|
74
|
+
"api",
|
|
75
|
+
"routes",
|
|
76
|
+
"services",
|
|
77
|
+
"packages",
|
|
78
|
+
"schemas",
|
|
79
|
+
"scripts",
|
|
80
|
+
"tests",
|
|
81
|
+
"package.json",
|
|
82
|
+
"tsconfig.json",
|
|
83
|
+
"vite.config.ts",
|
|
84
|
+
"vite.config.js",
|
|
85
|
+
"next.config.ts",
|
|
86
|
+
"next.config.js",
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
const GENERIC_ROOT_MARKERS = [
|
|
90
|
+
"README.md",
|
|
91
|
+
"package.json",
|
|
92
|
+
"pnpm-lock.yaml",
|
|
93
|
+
"package-lock.json",
|
|
94
|
+
"yarn.lock",
|
|
95
|
+
"bun.lockb",
|
|
96
|
+
"tsconfig.json",
|
|
97
|
+
"vite.config.ts",
|
|
98
|
+
"vite.config.js",
|
|
99
|
+
"next.config.ts",
|
|
100
|
+
"next.config.js",
|
|
101
|
+
"pyproject.toml",
|
|
102
|
+
"Cargo.toml",
|
|
103
|
+
"go.mod",
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
const PACKAGE_MANAGER_MARKERS = [
|
|
107
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
108
|
+
["package-lock.json", "npm"],
|
|
109
|
+
["yarn.lock", "yarn"],
|
|
110
|
+
["bun.lockb", "bun"],
|
|
111
|
+
["package.json", "npm-compatible"],
|
|
112
|
+
];
|
|
113
|
+
|
|
33
114
|
function inside(root, candidate) {
|
|
34
115
|
const relative = path.relative(root, candidate);
|
|
35
116
|
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
@@ -90,6 +171,28 @@ function describeApprovedPath(projectRoot, relativePath) {
|
|
|
90
171
|
};
|
|
91
172
|
}
|
|
92
173
|
|
|
174
|
+
function existingPathRecords(projectRoot, candidates) {
|
|
175
|
+
return candidates
|
|
176
|
+
.map((relativePath) => describeApprovedPath(projectRoot, relativePath))
|
|
177
|
+
.filter((record) => record.status === "present");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function genericRootMarkers(projectRoot) {
|
|
181
|
+
return GENERIC_ROOT_MARKERS
|
|
182
|
+
.map((relativePath) => describeApprovedPath(projectRoot, relativePath))
|
|
183
|
+
.filter((record) => record.status === "present")
|
|
184
|
+
.map((record) => ({
|
|
185
|
+
kind: record.type,
|
|
186
|
+
path: record.path,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function genericPackageManagers(projectRoot) {
|
|
191
|
+
return PACKAGE_MANAGER_MARKERS
|
|
192
|
+
.filter(([relativePath]) => describeApprovedPath(projectRoot, relativePath).status === "present")
|
|
193
|
+
.map(([, manager]) => manager);
|
|
194
|
+
}
|
|
195
|
+
|
|
93
196
|
function gitSummary(projectRoot) {
|
|
94
197
|
const summary = {
|
|
95
198
|
root: null,
|
|
@@ -174,30 +277,92 @@ function loadRepoMapAdapters(loaded) {
|
|
|
174
277
|
|
|
175
278
|
export function buildAdapterRepoMapReport(projectRootInput, options = {}) {
|
|
176
279
|
const coreRoot = path.resolve(options.coreRoot ?? DEFAULT_CORE_ROOT);
|
|
177
|
-
const
|
|
178
|
-
if (!
|
|
280
|
+
const loaded = readProjectAdapterDeclaration(projectRootInput);
|
|
281
|
+
if (!loaded.ok) {
|
|
282
|
+
if (loaded.codes.length === 1 && loaded.codes[0] === "missing-project-declaration") {
|
|
283
|
+
const projectRoot = fs.realpathSync(path.resolve(projectRootInput));
|
|
284
|
+
const git = gitSummary(projectRoot);
|
|
285
|
+
return {
|
|
286
|
+
ok: true,
|
|
287
|
+
status: "complete",
|
|
288
|
+
coreVersion: PILOT_VERSION,
|
|
289
|
+
projectRoot,
|
|
290
|
+
declarationPath: "not present",
|
|
291
|
+
adapterRoot: "not present",
|
|
292
|
+
projectId: "not declared",
|
|
293
|
+
adapterIds: [],
|
|
294
|
+
manifestPaths: [],
|
|
295
|
+
enabledSkills: ["repo-map"],
|
|
296
|
+
adapter: {
|
|
297
|
+
present: false,
|
|
298
|
+
enabled: false,
|
|
299
|
+
mode: "generic-safe-discovery",
|
|
300
|
+
codes: ["missing-project-declaration"],
|
|
301
|
+
},
|
|
302
|
+
adapterPresent: false,
|
|
303
|
+
mode: "generic-safe-discovery",
|
|
304
|
+
confidence: "reduced",
|
|
305
|
+
rootMarkers: genericRootMarkers(projectRoot),
|
|
306
|
+
maximumDepth: 2,
|
|
307
|
+
scope: "generic-project-root",
|
|
308
|
+
requireApprovalOutsideScope: true,
|
|
309
|
+
documentationPrecedence: existingPathRecords(projectRoot, GENERIC_DOCUMENTATION_PRECEDENCE),
|
|
310
|
+
safeReadPaths: existingPathRecords(projectRoot, GENERIC_SAFE_READ_PATHS),
|
|
311
|
+
ignoredPaths: GENERIC_IGNORED_PATHS,
|
|
312
|
+
requiredEvidence: [
|
|
313
|
+
"repository root markers",
|
|
314
|
+
"bounded generic file/directory inventory",
|
|
315
|
+
"adapter absence evidence",
|
|
316
|
+
],
|
|
317
|
+
packageManagers: unique(genericPackageManagers(projectRoot)),
|
|
318
|
+
git,
|
|
319
|
+
warnings: unique([
|
|
320
|
+
...git.warnings,
|
|
321
|
+
"adapterPresent: false",
|
|
322
|
+
"mode: generic-safe-discovery",
|
|
323
|
+
"reduced confidence; adapter-provided project intent is unavailable",
|
|
324
|
+
"no project adapter declaration found; repo-map used generic bounded discovery",
|
|
325
|
+
"no target project build, test, runtime, deployment, migration, package, or secret-reading command was performed",
|
|
326
|
+
"no secrets read",
|
|
327
|
+
]),
|
|
328
|
+
refusedBehavior: REFUSED_BEHAVIOR,
|
|
329
|
+
validation: {
|
|
330
|
+
ok: false,
|
|
331
|
+
status: "failed",
|
|
332
|
+
acceptedAdapters: 0,
|
|
333
|
+
acceptedSkills: [],
|
|
334
|
+
codes: ["missing-project-declaration"],
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
}
|
|
179
338
|
return {
|
|
180
339
|
ok: false,
|
|
181
340
|
status: "failed",
|
|
182
|
-
codes:
|
|
183
|
-
validation
|
|
341
|
+
codes: loaded.codes,
|
|
342
|
+
validation: {
|
|
343
|
+
ok: false,
|
|
344
|
+
status: "failed",
|
|
345
|
+
acceptedAdapters: 0,
|
|
346
|
+
acceptedSkills: [],
|
|
347
|
+
codes: loaded.codes,
|
|
348
|
+
},
|
|
184
349
|
};
|
|
185
350
|
}
|
|
186
|
-
|
|
351
|
+
|
|
352
|
+
const validation = validateProjectAdapters(loaded.projectRoot, { coreRoot });
|
|
353
|
+
if (!validation.ok) {
|
|
187
354
|
return {
|
|
188
355
|
ok: false,
|
|
189
356
|
status: "failed",
|
|
190
|
-
codes:
|
|
357
|
+
codes: validation.codes,
|
|
191
358
|
validation,
|
|
192
359
|
};
|
|
193
360
|
}
|
|
194
|
-
|
|
195
|
-
const loaded = readProjectAdapterDeclaration(projectRootInput);
|
|
196
|
-
if (!loaded.ok) {
|
|
361
|
+
if (!validation.acceptedSkills.includes("repo-map")) {
|
|
197
362
|
return {
|
|
198
363
|
ok: false,
|
|
199
364
|
status: "failed",
|
|
200
|
-
codes:
|
|
365
|
+
codes: ["repo-map-not-enabled"],
|
|
201
366
|
validation,
|
|
202
367
|
};
|
|
203
368
|
}
|
|
@@ -246,6 +411,15 @@ export function buildAdapterRepoMapReport(projectRootInput, options = {}) {
|
|
|
246
411
|
adapterIds: adapters.map((adapter) => adapter.manifest.adapterId).sort(),
|
|
247
412
|
manifestPaths: adapters.map((adapter) => adapter.manifestPath).sort(),
|
|
248
413
|
enabledSkills: ["repo-map"],
|
|
414
|
+
adapter: {
|
|
415
|
+
present: true,
|
|
416
|
+
enabled: true,
|
|
417
|
+
mode: "adapter-limited",
|
|
418
|
+
codes: [],
|
|
419
|
+
},
|
|
420
|
+
adapterPresent: true,
|
|
421
|
+
mode: "adapter-limited",
|
|
422
|
+
confidence: "adapter-declared",
|
|
249
423
|
rootMarkers,
|
|
250
424
|
maximumDepth,
|
|
251
425
|
scope: "declared-project-root",
|
|
@@ -294,10 +468,16 @@ export function renderAdapterRepoMapReport(report) {
|
|
|
294
468
|
`Project root: ${redactSensitiveText(report.projectRoot)}`,
|
|
295
469
|
`Declaration: ${report.declarationPath}`,
|
|
296
470
|
`Adapter root: ${report.adapterRoot}`,
|
|
297
|
-
`Adapter IDs: ${report.adapterIds.join(", ")}`,
|
|
298
|
-
`Adapter manifests: ${report.manifestPaths.join(", ")}`,
|
|
471
|
+
`Adapter IDs: ${report.adapterIds.length ? report.adapterIds.join(", ") : "none"}`,
|
|
472
|
+
`Adapter manifests: ${report.manifestPaths.length ? report.manifestPaths.join(", ") : "none"}`,
|
|
299
473
|
`Enabled skills: ${report.enabledSkills.join(", ")}`,
|
|
300
474
|
"",
|
|
475
|
+
"## Adapter Scope",
|
|
476
|
+
`- Adapter present: ${report.adapterPresent ? "yes" : "no"}`,
|
|
477
|
+
`- Repo-map enabled: ${report.adapter?.enabled ? "yes" : "generic fallback"}`,
|
|
478
|
+
`- Mode: ${report.mode}`,
|
|
479
|
+
`- Confidence: ${report.confidence}`,
|
|
480
|
+
"",
|
|
301
481
|
"## Git State",
|
|
302
482
|
`- Git root: ${redactSensitiveText(report.git.root ?? "not detected")}`,
|
|
303
483
|
`- Branch state: ${redactSensitiveText(report.git.branchState ?? "not detected")}`,
|
|
@@ -334,6 +514,8 @@ export function renderAdapterRepoMapReport(report) {
|
|
|
334
514
|
...formatList("Refused Behavior", report.refusedBehavior),
|
|
335
515
|
"",
|
|
336
516
|
"No target project build, test, runtime, deployment, migration, package installation, or secret-file read was performed.",
|
|
517
|
+
"No project commands beyond safe repository metadata inspection were performed.",
|
|
518
|
+
"No secrets were read.",
|
|
337
519
|
];
|
|
338
520
|
|
|
339
521
|
return lines.join("\n");
|
package/scripts/test-pack.mjs
CHANGED
|
@@ -221,7 +221,7 @@ function snapshotAbsoluteDirectory(directory) {
|
|
|
221
221
|
return digest.digest("hex");
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
function assertOpenClawJsonContract(value, command, packageVersion = "0.2.
|
|
224
|
+
function assertOpenClawJsonContract(value, command, packageVersion = "0.2.17") {
|
|
225
225
|
assert.equal(value.tool, "coding-agent-skills");
|
|
226
226
|
assert.equal(value.command, command);
|
|
227
227
|
assert.equal(value.packageVersion, packageVersion);
|
|
@@ -378,6 +378,10 @@ test("local CLI maps approved commands to existing safe scripts", () => {
|
|
|
378
378
|
["repo-map", path.join(fixtureRoot, "project-adapter-installation", "valid-exact-pin")],
|
|
379
379
|
/# Adapter-Aware Repo Map/,
|
|
380
380
|
],
|
|
381
|
+
[
|
|
382
|
+
["repo-map", path.join(fixtureRoot, "sample-repo")],
|
|
383
|
+
/generic-safe-discovery/,
|
|
384
|
+
],
|
|
381
385
|
[
|
|
382
386
|
["route-trace", path.join(fixtureRoot, "route-trace", "static-project")],
|
|
383
387
|
/# Route Trace Report/,
|
|
@@ -443,6 +447,7 @@ test("local CLI emits OpenClaw-compatible JSON for public commands", () => {
|
|
|
443
447
|
path.join(fixtureRoot, "project-adapter-installation", "valid-exact-pin"),
|
|
444
448
|
],
|
|
445
449
|
["repo-map", path.join(fixtureRoot, "project-adapter-installation", "valid-exact-pin")],
|
|
450
|
+
["repo-map", path.join(fixtureRoot, "sample-repo")],
|
|
446
451
|
["route-trace", path.join(fixtureRoot, "route-trace", "static-project")],
|
|
447
452
|
["env-audit", path.join(fixtureRoot, "env-audit", "static-project")],
|
|
448
453
|
["secret-audit", path.join(fixtureRoot, "secret-audit", "static-project")],
|
|
@@ -488,7 +493,7 @@ test("local CLI emits OpenClaw-compatible JSON for public commands", () => {
|
|
|
488
493
|
test("npm package metadata is public-ready and dependency-free", () => {
|
|
489
494
|
const packageJson = readJson("package.json");
|
|
490
495
|
assert.equal(packageJson.name, "coding-agent-skills");
|
|
491
|
-
assert.equal(packageJson.version, "0.2.
|
|
496
|
+
assert.equal(packageJson.version, "0.2.17");
|
|
492
497
|
assert.equal(
|
|
493
498
|
packageJson.description,
|
|
494
499
|
"Evidence-first, read-only coding-agent skills and project adapter tooling.",
|
|
@@ -1769,6 +1774,42 @@ test("adapter-aware repo-map consumes validated project adapter metadata", () =>
|
|
|
1769
1774
|
assert.match(rendered, /No target project build, test, runtime, deployment/);
|
|
1770
1775
|
});
|
|
1771
1776
|
|
|
1777
|
+
test("repo-map supports generic safe discovery without a project adapter", () => {
|
|
1778
|
+
const report = buildAdapterRepoMapReport(
|
|
1779
|
+
path.join(root, "tests", "fixtures", "sample-repo"),
|
|
1780
|
+
{ coreRoot: root },
|
|
1781
|
+
);
|
|
1782
|
+
|
|
1783
|
+
assert.equal(report.ok, true, report.codes?.join(","));
|
|
1784
|
+
assert.equal(report.adapter.present, false);
|
|
1785
|
+
assert.equal(report.adapter.enabled, false);
|
|
1786
|
+
assert.equal(report.mode, "generic-safe-discovery");
|
|
1787
|
+
assert.equal(report.confidence, "reduced");
|
|
1788
|
+
assert.equal(report.adapterPresent, false);
|
|
1789
|
+
assert.ok(report.validation.codes.includes("missing-project-declaration"));
|
|
1790
|
+
assert.ok(report.warnings.includes("adapterPresent: false"));
|
|
1791
|
+
assert.ok(report.warnings.includes("mode: generic-safe-discovery"));
|
|
1792
|
+
assert.ok(report.warnings.includes("no secrets read"));
|
|
1793
|
+
assert.ok(report.ignoredPaths.includes(".env"));
|
|
1794
|
+
assert.ok(report.ignoredPaths.includes(".env.*"));
|
|
1795
|
+
assert.ok(
|
|
1796
|
+
report.documentationPrecedence.some((record) => record.path === "README.md"),
|
|
1797
|
+
);
|
|
1798
|
+
|
|
1799
|
+
const rendered = renderAdapterRepoMapReport(report);
|
|
1800
|
+
assert.match(rendered, /Adapter present: no/);
|
|
1801
|
+
assert.match(rendered, /Mode: generic-safe-discovery/);
|
|
1802
|
+
assert.match(rendered, /Confidence: reduced/);
|
|
1803
|
+
assert.match(rendered, /No secrets were read/);
|
|
1804
|
+
|
|
1805
|
+
const cli = adapterRepoMapCliResult(path.join(root, "tests", "fixtures", "sample-repo"), {
|
|
1806
|
+
coreRoot: root,
|
|
1807
|
+
});
|
|
1808
|
+
assert.equal(cli.exitCode, 0);
|
|
1809
|
+
assert.equal(cli.stream, "stdout");
|
|
1810
|
+
assert.match(cli.lines.join("\n"), /generic-safe-discovery/);
|
|
1811
|
+
});
|
|
1812
|
+
|
|
1772
1813
|
test("adapter-aware repo-map fails closed without repo-map compatibility", () => {
|
|
1773
1814
|
const fixtureRoot = path.join(
|
|
1774
1815
|
root,
|
|
@@ -687,8 +687,8 @@ if (packageJson) {
|
|
|
687
687
|
if (packageJson.name !== "coding-agent-skills") {
|
|
688
688
|
failures.push("package.json has unexpected package name");
|
|
689
689
|
}
|
|
690
|
-
if (packageJson.version !== "0.2.
|
|
691
|
-
failures.push("package.json version must be 0.2.
|
|
690
|
+
if (packageJson.version !== "0.2.17") {
|
|
691
|
+
failures.push("package.json version must be 0.2.17 for public package validation");
|
|
692
692
|
}
|
|
693
693
|
if (packageJson.type !== "module") failures.push("package.json must preserve ESM mode");
|
|
694
694
|
if (packageJson.private !== false) {
|