@csark0812/skeleton 1.6.2 → 2.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.
Files changed (51) hide show
  1. package/README.md +19 -12
  2. package/dist/audit/config/load.d.ts +18 -0
  3. package/dist/audit/config/types.d.ts +75 -0
  4. package/dist/audit/core/code-fit.d.ts +35 -0
  5. package/dist/audit/core/collect.d.ts +21 -0
  6. package/dist/audit/core/context.d.ts +46 -0
  7. package/dist/audit/core/draft.d.ts +11 -0
  8. package/dist/audit/core/fix.d.ts +29 -0
  9. package/dist/audit/core/git-meta.d.ts +1 -0
  10. package/dist/audit/core/markdown.d.ts +16 -0
  11. package/dist/audit/core/report.d.ts +31 -0
  12. package/dist/audit/core/review-proof.d.ts +23 -0
  13. package/dist/audit/core/shared.d.ts +25 -0
  14. package/dist/audit/core/skill-provenance.d.ts +37 -0
  15. package/dist/audit/core/skill-roots.d.ts +54 -0
  16. package/dist/audit/core/ssot-collect.d.ts +16 -0
  17. package/dist/audit/core/ssot-fit.d.ts +38 -0
  18. package/dist/audit/core/ssot.d.ts +28 -0
  19. package/dist/audit/fix/anchors.d.ts +6 -0
  20. package/dist/audit/fix/doc-meta.d.ts +4 -0
  21. package/dist/audit/fix/match-anchor.d.ts +8 -0
  22. package/dist/audit/fix/ssot.d.ts +3 -0
  23. package/dist/audit/policies/load.d.ts +13 -0
  24. package/dist/audit/policies/types.d.ts +46 -0
  25. package/dist/audit/rules/banned.d.ts +7 -0
  26. package/dist/audit/rules/code-fit.d.ts +13 -0
  27. package/dist/audit/rules/doc-meta.d.ts +8 -0
  28. package/dist/audit/rules/index.d.ts +26 -0
  29. package/dist/audit/rules/links.d.ts +7 -0
  30. package/dist/audit/rules/near-duplicate.d.ts +8 -0
  31. package/dist/audit/rules/prose-policy.d.ts +7 -0
  32. package/dist/audit/rules/review-proof.d.ts +1 -0
  33. package/dist/audit/rules/scan-gaps.d.ts +7 -0
  34. package/dist/audit/rules/scan-roots.d.ts +7 -0
  35. package/dist/audit/rules/skill-index.d.ts +10 -0
  36. package/dist/audit/rules/ssot-summary.d.ts +8 -0
  37. package/dist/audit/rules/ssot.d.ts +7 -0
  38. package/dist/cli.js +4439 -3631
  39. package/dist/hooks/customize-on-skill-read.js +27 -1
  40. package/dist/plugin-types.d.ts +12 -131
  41. package/dist/plugin-types.js +6 -3
  42. package/dist/references/check.d.ts +10 -0
  43. package/dist/references/constants.d.ts +9 -0
  44. package/dist/references/discover.d.ts +19 -0
  45. package/dist/result-types.d.ts +72 -0
  46. package/dist/result-types.js +0 -0
  47. package/package.json +26 -17
  48. package/schemas/config.schema.json +29 -1
  49. package/schemas/policy-file.schema.json +5 -2
  50. package/schemas/result.schema.json +207 -0
  51. package/templates/skeleton-init/skeleton.toml +6 -0
@@ -3520,7 +3520,12 @@ var require_fast_uri = __commonJS((exports, module) => {
3520
3520
  }
3521
3521
  function resolve(baseURI, relativeURI, options) {
3522
3522
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3523
- const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
3523
+ const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
3524
+ const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
3525
+ if (baseMalformed || relativeMalformed) {
3526
+ throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
3527
+ }
3528
+ const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
3524
3529
  schemelessOptions.skipEscape = true;
3525
3530
  return serialize(resolved, schemelessOptions);
3526
3531
  }
@@ -3646,6 +3651,8 @@ var require_fast_uri = __commonJS((exports, module) => {
3646
3651
  return uriTokens.join("");
3647
3652
  }
3648
3653
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
3654
+ var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
3655
+ var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
3649
3656
  function getParseError(parsed, matches) {
3650
3657
  if (matches[2] !== undefined && parsed.path && parsed.path[0] !== "/") {
3651
3658
  return 'URI path must start with "/" when authority is present.';
@@ -3675,6 +3682,25 @@ var require_fast_uri = __commonJS((exports, module) => {
3675
3682
  uri = "//" + uri;
3676
3683
  }
3677
3684
  }
3685
+ const authorityMatch = uri.match(AUTHORITY_PREFIX);
3686
+ if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
3687
+ parsed.error = "URI authority must not contain a literal backslash.";
3688
+ malformedAuthorityOrPort = true;
3689
+ }
3690
+ const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
3691
+ if (introducerMatch !== null) {
3692
+ const region = introducerMatch[1];
3693
+ const normalizedRegion = region.replace(/[\t\n\r]/g, "");
3694
+ if (normalizedRegion.length >= 2) {
3695
+ if (normalizedRegion.slice(0, 2) !== "//") {
3696
+ parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
3697
+ malformedAuthorityOrPort = true;
3698
+ } else if (region.length !== normalizedRegion.length) {
3699
+ parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
3700
+ malformedAuthorityOrPort = true;
3701
+ }
3702
+ }
3703
+ }
3678
3704
  const matches = uri.match(URI_PARSE);
3679
3705
  if (matches) {
3680
3706
  parsed.scheme = matches[1];
@@ -1,133 +1,14 @@
1
1
  /**
2
- * Public types for `@csark0812/skeleton/plugin-types`.
3
- * Kept hand-written so publishes stay independent of `.ts` extension emit quirks.
2
+ * Public types and helpers for skeleton plugin authors.
3
+ *
4
+ * ```ts
5
+ * import type { AuditRule, AuditContext } from "@csark0812/skeleton/plugin-types";
6
+ * import { issue, matchesGlobScope } from "@csark0812/skeleton/plugin-types";
7
+ * ```
4
8
  */
5
-
6
- export type Severity = "error" | "warning";
7
-
8
- export interface Issue {
9
- rule: string;
10
- file: string;
11
- link?: string;
12
- message: string;
13
- severity: Severity;
14
- }
15
-
16
- export declare function issue(
17
- rule: string,
18
- file: string,
19
- message: string,
20
- opts?: { link?: string; severity?: Severity },
21
- ): Issue;
22
-
23
- export type AuditSuite = "docs" | "skills";
24
-
25
- export interface AuditRule {
26
- id: string;
27
- global?: boolean;
28
- suites?: AuditSuite[];
29
- run: (ctx: AuditContext) => Issue[];
30
- }
31
-
32
- export type PolicyEntry =
33
- | {
34
- id: string;
35
- message: string;
36
- mode?: "pattern";
37
- pattern: string;
38
- scope?: string;
39
- severity?: Severity;
40
- canonical?: string;
41
- }
42
- | {
43
- id: string;
44
- message: string;
45
- mode: "fingerprint";
46
- pattern?: string;
47
- scope?: string;
48
- severity?: Severity;
49
- canonical?: string;
50
- };
51
-
52
- export interface CompiledPolicyEntry {
53
- id: string;
54
- message: string;
55
- mode: "pattern" | "fingerprint";
56
- pattern?: string;
57
- scope?: string;
58
- severity?: Severity;
59
- canonical?: string;
60
- regex: RegExp | null;
61
- }
62
-
63
- export interface PolicyFile {
64
- name: string;
65
- entries: CompiledPolicyEntry[];
66
- }
67
-
68
- export interface PolicyFileYaml {
69
- name: string;
70
- entries: PolicyEntry[];
71
- }
72
-
73
- export type MatchedPolicyEntry = CompiledPolicyEntry & { policyName: string };
74
-
75
- export interface ScanConfig {
76
- include: string[];
77
- exclude: string[];
78
- nonPublicSkills?: string[];
79
- }
80
-
81
- export interface DenyConfig {
82
- paths?: string[];
83
- }
84
-
85
- export interface CustomizeConfig {
86
- alwaysInclude?: string[];
87
- }
88
-
89
- export interface DocsLintConfig {
90
- nearDuplicateThreshold?: number;
91
- ssotOverlapMin?: number;
92
- ssotBetterMatchMargin?: number;
93
- ssotPhraseCheck?: boolean;
94
- ignorePairs?: [string, string][];
95
- ignoreGlobs?: string[];
96
- }
97
-
98
- export interface SkeletonConfig {
99
- scan: ScanConfig;
100
- daysUntilStale: number;
101
- deny?: DenyConfig;
102
- customize?: CustomizeConfig;
103
- docsLint?: DocsLintConfig;
104
- plugins?: string[];
105
- draftPathPrefixes?: string[];
106
- }
107
-
108
- export interface SkillRoot {
109
- kind: "nested" | "flat";
110
- relPath: string;
111
- }
112
-
113
- export interface SkillIndex {
114
- roots: SkillRoot[];
115
- slugs: string[];
116
- }
117
-
118
- export interface AuditContext {
119
- root: string;
120
- config: SkeletonConfig;
121
- files: string[];
122
- docMetaPaths: string[];
123
- ssotEntries: Array<{ path: string; summary: string; form: string }>;
124
- ssotErrors: Array<{ path: string; kind: string; detail: string }>;
125
- /** @deprecated Prefer ssotEntries */
126
- registryPaths: string[];
127
- /** @deprecated Always false */
128
- registryHasTableHeader: boolean;
129
- skillIndex: SkillIndex;
130
- policies: PolicyFile[];
131
- }
132
-
133
- export declare function matchesGlobScope(relPath: string, scope: string | undefined): boolean;
9
+ export type { AuditContext } from "./audit/core/context.ts";
10
+ export type { Issue, Severity } from "./audit/core/report.ts";
11
+ export { issue } from "./audit/core/report.ts";
12
+ export { matchesGlobScope } from "./audit/core/shared.ts";
13
+ export type { CompiledPolicyEntry, MatchedPolicyEntry, PolicyEntry, PolicyFile, PolicyFileYaml, } from "./audit/policies/types.ts";
14
+ export type { AuditRule, AuditSuite } from "./audit/rules/index.ts";
@@ -1,12 +1,15 @@
1
1
  // src/audit/core/report.ts
2
- function issue(rule, file, details) {
2
+ function issue(rule, file, details, options) {
3
3
  const message = typeof details === "string" ? details : details.message;
4
+ const selected = typeof details === "string" ? options : details;
4
5
  return {
5
6
  rule,
7
+ ...selected?.code ? { code: selected.code } : {},
6
8
  file,
7
- link: typeof details === "string" ? undefined : details.link,
9
+ link: selected?.link,
8
10
  message,
9
- severity: typeof details === "string" ? "error" : details.severity ?? "error"
11
+ ...selected?.remediation ? { remediation: selected.remediation } : {},
12
+ severity: selected?.severity ?? "error"
10
13
  };
11
14
  }
12
15
  // src/audit/core/shared.ts
@@ -0,0 +1,10 @@
1
+ import type { SkillOwnershipConfig } from "../audit/config/types.ts";
2
+ import type { AuditContext } from "../audit/core/context.ts";
3
+ import { type Issue } from "../audit/core/report.ts";
4
+ export declare function runGeneratedReferencesCheck(root: string, ownership?: SkillOwnershipConfig): Issue[];
5
+ export declare function runGeneratedReferencesRule(ctx: AuditContext): Issue[];
6
+ export declare const generatedReferencesRule: {
7
+ id: string;
8
+ global: boolean;
9
+ run: typeof runGeneratedReferencesRule;
10
+ };
@@ -0,0 +1,9 @@
1
+ export declare const CANONICAL_REFS_DIR = ".skeleton/references";
2
+ export declare const GENERATED_MARKER_START = "<!-- skeleton: generated-reference";
3
+ export declare const GENERATED_MARKER_RE: RegExp;
4
+ /** Markdown links targeting the old shared root references/ tree. */
5
+ export declare const SHARED_REF_LINK_RE: RegExp;
6
+ export declare function formatGeneratedHeader(sourceRelPath: string): string;
7
+ export declare function stripGeneratedHeader(content: string): string;
8
+ export declare function parseGeneratedSource(content: string): string | null;
9
+ export declare function isGeneratedReference(content: string): boolean;
@@ -0,0 +1,19 @@
1
+ import type { SkillOwnershipConfig } from "../audit/config/types.ts";
2
+ export interface SharedRefLink {
3
+ refPath: string;
4
+ sourceFile: string;
5
+ }
6
+ export interface SkillReferencePlan {
7
+ skill: string;
8
+ /** Repo-relative directory containing this concrete skill instance. */
9
+ skillDir: string;
10
+ refPaths: Set<string>;
11
+ links: SharedRefLink[];
12
+ }
13
+ /** Links still pointing at the old shared root references/ tree. */
14
+ export declare function findSharedRefLinks(content: string, sourceFile: string): SharedRefLink[];
15
+ export declare function discoverSkillReferencePlans(root: string, ownership?: SkillOwnershipConfig): SkillReferencePlan[];
16
+ export declare function canonicalRefPath(_root: string, refPath: string): string;
17
+ export declare function generatedRefPath(skillDir: string, refPath: string): string;
18
+ export declare function rewriteSharedRefTarget(sourceFile: string, skillDir: string, refPath: string): string;
19
+ export declare function rewriteSharedRefLinks(content: string, sourceFile: string, skillDir: string): string;
@@ -0,0 +1,72 @@
1
+ import type { Issue } from "./audit/core/report.ts";
2
+ export type CatalogStatus = "current" | "missing" | "stale" | "skipped-ci" | "not-applicable";
3
+ export interface ReviewProofResult {
4
+ mode: "date" | "hash";
5
+ status: "not-enabled" | "not-checked" | "valid" | "invalid";
6
+ lockfile?: string;
7
+ }
8
+ export interface AuditResult {
9
+ schemaVersion: 1;
10
+ command: "audit";
11
+ ok: boolean;
12
+ exitCode: 0 | 1;
13
+ suite: string;
14
+ strict: boolean;
15
+ label: string;
16
+ scope: {
17
+ paths: string[];
18
+ fileCount?: number;
19
+ };
20
+ rules: {
21
+ requested: string[] | null;
22
+ executed: string[];
23
+ };
24
+ counts: {
25
+ errors: number;
26
+ warnings: number;
27
+ };
28
+ diagnostics: Issue[];
29
+ catalog: {
30
+ status: CatalogStatus;
31
+ };
32
+ reviewProof: ReviewProofResult;
33
+ successSuffix?: string;
34
+ }
35
+ export interface ValidateClassificationResult {
36
+ docs: string[];
37
+ code: string[];
38
+ skills: string[];
39
+ shell: string[];
40
+ json: string[];
41
+ policy: string[];
42
+ skipped: string[];
43
+ foreignSkills: string[];
44
+ missing: string[];
45
+ orphanPolicies: string[];
46
+ }
47
+ export type DocumentImpactReason = {
48
+ kind: "changed-document";
49
+ } | {
50
+ kind: "changed-code-target";
51
+ target: string;
52
+ };
53
+ export interface ImpactedDocument {
54
+ path: string;
55
+ codeTargets: string[];
56
+ reasons: DocumentImpactReason[];
57
+ }
58
+ export interface ValidateChangedResult {
59
+ schemaVersion: 1;
60
+ command: "validate-changed";
61
+ ok: boolean;
62
+ exitCode: 0 | 1;
63
+ input: {
64
+ paths: string[];
65
+ staged: boolean;
66
+ base?: string;
67
+ };
68
+ classification: ValidateClassificationResult;
69
+ impactedDocuments: ImpactedDocument[];
70
+ audits: AuditResult[];
71
+ diagnostics: Issue[];
72
+ }
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@csark0812/skeleton",
3
- "version": "1.6.2",
3
+ "version": "2.0.0",
4
4
  "description": "SSOT audit CLI for agent harness repos",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,8 +11,13 @@
11
11
  "types": "./dist/plugin-types.d.ts",
12
12
  "default": "./dist/plugin-types.js"
13
13
  },
14
+ "./result-types": {
15
+ "types": "./dist/result-types.d.ts",
16
+ "default": "./dist/result-types.js"
17
+ },
14
18
  "./schemas/config.schema.json": "./schemas/config.schema.json",
15
- "./schemas/policy-file.schema.json": "./schemas/policy-file.schema.json"
19
+ "./schemas/policy-file.schema.json": "./schemas/policy-file.schema.json",
20
+ "./schemas/result.schema.json": "./schemas/result.schema.json"
16
21
  },
17
22
  "files": [
18
23
  "dist",
@@ -29,7 +34,7 @@
29
34
  },
30
35
  "packageManager": "bun@1.2.21",
31
36
  "scripts": {
32
- "build": "bun build src/cli.ts --target=node --outfile=dist/cli.js && bun build src/hooks/customize-on-skill-read.ts --target=node --outfile=dist/hooks/customize-on-skill-read.js && bun build src/plugin-types.ts --target=node --format=esm --outfile=dist/plugin-types.js --packages=external && cp types/plugin-types.d.ts dist/plugin-types.d.ts",
37
+ "build": "bun build src/cli.ts --target=node --outfile=dist/cli.js && bun build src/hooks/customize-on-skill-read.ts --target=node --outfile=dist/hooks/customize-on-skill-read.js && bun build src/plugin-types.ts --target=node --format=esm --outfile=dist/plugin-types.js --packages=external && bun build src/result-types.ts --target=node --format=esm --outfile=dist/result-types.js --packages=external && tsc -p tsconfig.types.json",
33
38
  "test": "bun test",
34
39
  "test:audit": "bun test src/audit/__tests__",
35
40
  "test:cli": "bun test src/__tests__/cli",
@@ -45,6 +50,7 @@
45
50
  "audit:skills": "bun src/cli.ts audit skills",
46
51
  "audit:self": "bun src/cli.ts audit self",
47
52
  "check": "bun run lint && bun test && bun run typecheck && bun run build && bun run audit:self",
53
+ "verify:package": "bun run build && bun scripts/verify-package.ts",
48
54
  "start": "bun src/cli.ts --help",
49
55
  "dev": "bun src/cli.ts --help",
50
56
  "agent:test:live": "agent-test --suites-dir agent-suites --live --fail-on=behavior",
@@ -56,24 +62,27 @@
56
62
  "agent:evidence:charts": "bun scripts/agent-evidence/render-charts.ts",
57
63
  "agent:evidence:excerpt": "bun scripts/agent-evidence/excerpt-transcript.ts",
58
64
  "agent:evidence:archive": "bash scripts/agent-evidence/archive-run.sh",
59
- "prepack": "bun test && bun run typecheck && bun run build"
65
+ "prepack": "bun run check && bun scripts/verify-package.ts"
60
66
  },
61
67
  "dependencies": {
62
- "ajv": "^8.17.1",
63
- "github-slugger": "^2.0.0",
64
- "remark": "^15.0.1",
65
- "remark-gfm": "^4.0.1",
66
- "smol-toml": "^1.8.0",
67
- "tinyglobby": "^0.2.14",
68
- "unist-util-visit": "^5.0.0",
69
- "yaml": "^2.8.0"
68
+ "ajv": "8.20.0",
69
+ "github-slugger": "2.0.0",
70
+ "remark": "15.0.1",
71
+ "remark-gfm": "4.0.1",
72
+ "smol-toml": "1.8.0",
73
+ "tinyglobby": "0.2.14",
74
+ "unist-util-visit": "5.0.0",
75
+ "yaml": "2.9.0"
70
76
  },
71
77
  "devDependencies": {
72
- "@biomejs/biome": "^2.5.3",
73
- "@cursor/sdk": "^1.0.23",
74
- "@post-print/agent-test": "^0.2.7",
75
- "@types/bun": "^1.3.8",
76
- "@types/github-slugger": "^2.0.0",
78
+ "@biomejs/biome": "2.5.3",
79
+ "@post-print/agent-test": "0.2.7",
80
+ "@types/bun": "1.3.8",
81
+ "@types/github-slugger": "2.0.0",
77
82
  "typescript": "~7.0.2"
83
+ },
84
+ "overrides": {
85
+ "fast-uri": "3.1.5",
86
+ "undici": "6.28.0"
78
87
  }
79
88
  }
@@ -47,7 +47,7 @@
47
47
  "docsLint": {
48
48
  "type": "object",
49
49
  "additionalProperties": false,
50
- "description": "Near-duplicate and SSOT-summary lint tunables",
50
+ "description": "Near-duplicate, SSOT-summary, and code-fit lint tunables",
51
51
  "properties": {
52
52
  "nearDuplicateThreshold": {
53
53
  "type": "number",
@@ -85,6 +85,17 @@
85
85
  "type": "array",
86
86
  "items": { "type": "string", "minLength": 1 },
87
87
  "description": "Globs excluded from near-dupe / duplicate-SSOT"
88
+ },
89
+ "codeFitOverlapMin": {
90
+ "type": "number",
91
+ "minimum": 0,
92
+ "maximum": 1,
93
+ "description": "Min fraction of doc tokens that must also appear as code identifiers (default 0.03)"
94
+ },
95
+ "codeFitSurfaceCap": {
96
+ "type": "integer",
97
+ "minimum": 1,
98
+ "description": "Max auto-extracted surface names before surface= is required (default 25)"
88
99
  }
89
100
  }
90
101
  },
@@ -126,6 +137,23 @@
126
137
  }
127
138
  }
128
139
  },
140
+ "reviewProof": {
141
+ "type": "object",
142
+ "additionalProperties": false,
143
+ "required": ["mode"],
144
+ "description": "Bind an explicit documentation review to exact document and code-target bytes",
145
+ "properties": {
146
+ "mode": {
147
+ "const": "hash",
148
+ "description": "Store SHA-256 review evidence"
149
+ },
150
+ "lockfile": {
151
+ "type": "string",
152
+ "minLength": 1,
153
+ "description": "Repo-relative review proof lockfile (default: .skeleton/review-lock.json)"
154
+ }
155
+ }
156
+ },
129
157
  "plugins": {
130
158
  "type": "array",
131
159
  "items": { "type": "string", "minLength": 1 },
@@ -28,13 +28,16 @@
28
28
  "message": { "type": "string" },
29
29
  "scope": { "type": "string" },
30
30
  "severity": { "enum": ["error", "warning"] },
31
- "canonical": { "type": "string" }
31
+ "canonical": { "type": "string" },
32
+ "caseSensitive": { "type": "boolean" },
33
+ "placement": { "enum": ["any", "draft-only"] },
34
+ "handledBy": { "type": "string", "minLength": 1 }
32
35
  },
33
36
  "if": {
34
37
  "properties": { "mode": { "const": "fingerprint" } },
35
38
  "required": ["mode"]
36
39
  },
37
- "then": true,
40
+ "then": { "required": ["handledBy"] },
38
41
  "else": { "required": ["pattern"] }
39
42
  }
40
43
  }