@phamvuhoang/otto-core 0.21.0 → 0.23.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/dist/external-skills.d.ts +170 -0
- package/dist/external-skills.d.ts.map +1 -0
- package/dist/external-skills.js +417 -0
- package/dist/external-skills.js.map +1 -0
- package/dist/index.d.ts +11 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/loop.d.ts.map +1 -1
- package/dist/loop.js +200 -16
- package/dist/loop.js.map +1 -1
- package/dist/plan-artifacts.d.ts +10 -0
- package/dist/plan-artifacts.d.ts.map +1 -0
- package/dist/plan-artifacts.js +63 -0
- package/dist/plan-artifacts.js.map +1 -0
- package/dist/plan-gate.d.ts +10 -1
- package/dist/plan-gate.d.ts.map +1 -1
- package/dist/plan-gate.js +22 -4
- package/dist/plan-gate.js.map +1 -1
- package/dist/plan-report-cli.d.ts +2 -1
- package/dist/plan-report-cli.d.ts.map +1 -1
- package/dist/plan-report-cli.js +9 -32
- package/dist/plan-report-cli.js.map +1 -1
- package/dist/plan-rubric.d.ts +24 -0
- package/dist/plan-rubric.d.ts.map +1 -1
- package/dist/plan-rubric.js +122 -0
- package/dist/plan-rubric.js.map +1 -1
- package/dist/report-finalize.d.ts +26 -0
- package/dist/report-finalize.d.ts.map +1 -0
- package/dist/report-finalize.js +222 -0
- package/dist/report-finalize.js.map +1 -0
- package/dist/report-rubric.d.ts +1 -1
- package/dist/report-rubric.d.ts.map +1 -1
- package/dist/report-rubric.js +3 -3
- package/dist/report-rubric.js.map +1 -1
- package/dist/run-report.d.ts +29 -0
- package/dist/run-report.d.ts.map +1 -1
- package/dist/run-report.js.map +1 -1
- package/dist/runner.d.ts +2 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +1 -1
- package/dist/runner.js.map +1 -1
- package/dist/skills-cli.d.ts +16 -5
- package/dist/skills-cli.d.ts.map +1 -1
- package/dist/skills-cli.js +134 -7
- package/dist/skills-cli.js.map +1 -1
- package/dist/skills.d.ts +21 -0
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +26 -1
- package/dist/skills.js.map +1 -1
- package/dist/stage-exec.d.ts.map +1 -1
- package/dist/stage-exec.js +3 -2
- package/dist/stage-exec.js.map +1 -1
- package/dist/tools-cli.d.ts +55 -0
- package/dist/tools-cli.d.ts.map +1 -0
- package/dist/tools-cli.js +196 -0
- package/dist/tools-cli.js.map +1 -0
- package/dist/tools.d.ts +164 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +228 -0
- package/dist/tools.js.map +1 -0
- package/package.json +2 -2
- package/templates/plan.md +36 -4
- package/templates/quality-report.md +18 -9
- package/templates/report-rewrite.md +25 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { type Skill } from "./skills.js";
|
|
2
|
+
/**
|
|
3
|
+
* External skill source registry (issue #110 P16). Otto can import outside skill
|
|
4
|
+
* packs (Superpowers, PM-Skills, …) into the existing `.otto/skills/<name>/`
|
|
5
|
+
* package shape, but **import is separated from trust and runtime use**: every
|
|
6
|
+
* imported skill lands as `trust: "unverified"` with empty validation, so it
|
|
7
|
+
* stays inert on the loop until a later validation/activation slice (P17/P18).
|
|
8
|
+
*
|
|
9
|
+
* Two files back the registry, both pure fs + JSON with safe defaults (never
|
|
10
|
+
* throw on the read path, mirroring `skills.ts`/`memory.ts`):
|
|
11
|
+
*
|
|
12
|
+
* - `.otto/skills/sources.json` — the configured sources (`{ sources: [...] }`).
|
|
13
|
+
* - `.otto/skills.lock.json` — what was actually resolved and imported:
|
|
14
|
+
* resolved ref, checksum, import timestamp, source type, license, normalized
|
|
15
|
+
* skill name and capabilities, for deterministic diffing and drift audits.
|
|
16
|
+
*
|
|
17
|
+
* This slice supports `local` source directories (the roadmap's "local fixture
|
|
18
|
+
* directories before networked git fetch"). `git`/`archive` resolution layers on
|
|
19
|
+
* top later without changing the lock/normalization shape.
|
|
20
|
+
*/
|
|
21
|
+
/** A source's transport kind. `registry` is reserved for a later slice. */
|
|
22
|
+
export type ExternalSourceType = "git" | "local" | "archive" | "registry";
|
|
23
|
+
/** One configured external skill source (`.otto/skills/sources.json`). */
|
|
24
|
+
export type ExternalSkillSource = {
|
|
25
|
+
/** Registry key, unique within sources.json. */
|
|
26
|
+
name: string;
|
|
27
|
+
type: ExternalSourceType;
|
|
28
|
+
/** URL (git/archive) or filesystem path (local). */
|
|
29
|
+
location: string;
|
|
30
|
+
/** Pinned ref (sha/tag). Absent = unpinned (an audit finding). */
|
|
31
|
+
ref?: string;
|
|
32
|
+
};
|
|
33
|
+
/** One resolved import in `.otto/skills.lock.json`. */
|
|
34
|
+
export type ExternalSkillLockEntry = {
|
|
35
|
+
/** Normalized skill name = `.otto/skills/<skill>` directory. */
|
|
36
|
+
skill: string;
|
|
37
|
+
/** Source name it came from. */
|
|
38
|
+
source: string;
|
|
39
|
+
type: ExternalSourceType;
|
|
40
|
+
/** Package path within the source tree. */
|
|
41
|
+
upstreamPath: string;
|
|
42
|
+
/** Resolved ref the source was pinned to, if any. */
|
|
43
|
+
ref?: string;
|
|
44
|
+
/** Content checksum of the imported package. */
|
|
45
|
+
checksum: string;
|
|
46
|
+
/** Import timestamp (ISO). */
|
|
47
|
+
importedAt: string;
|
|
48
|
+
license?: string;
|
|
49
|
+
capabilities: string[];
|
|
50
|
+
};
|
|
51
|
+
export type ExternalSkillLock = {
|
|
52
|
+
entries: ExternalSkillLockEntry[];
|
|
53
|
+
};
|
|
54
|
+
/** Absolute path to the sources config (`.otto/skills/sources.json`). */
|
|
55
|
+
export declare function sourcesPath(workspaceDir: string): string;
|
|
56
|
+
/** Absolute path to the import lockfile (`.otto/skills.lock.json`). */
|
|
57
|
+
export declare function lockPath(workspaceDir: string): string;
|
|
58
|
+
/** Normalize one untrusted source entry; null when it lacks the required shape. */
|
|
59
|
+
export declare function parseSource(raw: unknown): ExternalSkillSource | null;
|
|
60
|
+
/** Read configured sources; absent/malformed → `[]` (never throws). */
|
|
61
|
+
export declare function readSources(workspaceDir: string): ExternalSkillSource[];
|
|
62
|
+
/** Write the sources config, sorted by name for deterministic diffs. */
|
|
63
|
+
export declare function writeSources(workspaceDir: string, sources: ExternalSkillSource[]): void;
|
|
64
|
+
/** Read the import lock; absent/malformed → `{ entries: [] }` (never throws). */
|
|
65
|
+
export declare function readLock(workspaceDir: string): ExternalSkillLock;
|
|
66
|
+
/** Write the lock, entries sorted by skill name for deterministic diffs. */
|
|
67
|
+
export declare function writeLock(workspaceDir: string, lock: ExternalSkillLock): void;
|
|
68
|
+
/** Add (or replace by name) a source. Pure — returns a new array. */
|
|
69
|
+
export declare function addSource(sources: ExternalSkillSource[], source: ExternalSkillSource): ExternalSkillSource[];
|
|
70
|
+
/** Remove a source by name. Pure — returns a new array. */
|
|
71
|
+
export declare function removeSource(sources: ExternalSkillSource[], name: string): ExternalSkillSource[];
|
|
72
|
+
/**
|
|
73
|
+
* Parse a leading `--- … ---` frontmatter block into flat string fields plus the
|
|
74
|
+
* remaining body. Minimal `key: value` parsing (no nested YAML) — enough for the
|
|
75
|
+
* `name`/`description`/`license`/`capabilities` fields skill packs declare.
|
|
76
|
+
*/
|
|
77
|
+
export declare function parseFrontmatter(text: string): {
|
|
78
|
+
fields: Record<string, string>;
|
|
79
|
+
body: string;
|
|
80
|
+
};
|
|
81
|
+
/** A SKILL.md package located inside a source tree, before normalization. */
|
|
82
|
+
export type DiscoveredPackage = {
|
|
83
|
+
/** Normalized skill name (also the `.otto/skills/<name>` dir). */
|
|
84
|
+
name: string;
|
|
85
|
+
/** Package path within the source tree (POSIX-style, for the lock). */
|
|
86
|
+
upstreamPath: string;
|
|
87
|
+
/** Raw SKILL.md content. */
|
|
88
|
+
raw: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Find every `SKILL.md` package under a local source directory (recursively,
|
|
92
|
+
* depth-bounded). Covers the `skills/<name>/SKILL.md` Superpowers/PM-Skills shape
|
|
93
|
+
* and `.codex-plugin`/`.claude-plugin` bundles that nest the same file. Each
|
|
94
|
+
* package's skill name comes from its SKILL.md `name:` frontmatter, else its
|
|
95
|
+
* containing directory name, slugified. Returns packages sorted by name. Absent/
|
|
96
|
+
* unreadable dir → `[]` (never throws).
|
|
97
|
+
*/
|
|
98
|
+
export declare function discoverPackages(sourceDir: string): DiscoveredPackage[];
|
|
99
|
+
/**
|
|
100
|
+
* Normalize a discovered package + its source into an unverified, inert
|
|
101
|
+
* {@link Skill} plus the resolved {@link ExternalSkillLockEntry}. The skill body
|
|
102
|
+
* is the SKILL.md content minus frontmatter; capabilities come from a
|
|
103
|
+
* `capabilities:` frontmatter field when present (else empty); trust is always
|
|
104
|
+
* `unverified` and validation empty so the loop cannot apply it. `now` is the
|
|
105
|
+
* import timestamp (injected for deterministic tests).
|
|
106
|
+
*/
|
|
107
|
+
export declare function normalizePackage(source: ExternalSkillSource, pkg: DiscoveredPackage, now: Date): {
|
|
108
|
+
skill: Skill;
|
|
109
|
+
entry: ExternalSkillLockEntry;
|
|
110
|
+
};
|
|
111
|
+
/** What a `sync` would do to one skill package. */
|
|
112
|
+
export type SyncAction = "add" | "update" | "unchanged" | "conflict";
|
|
113
|
+
export type SyncPlanItem = {
|
|
114
|
+
skill: string;
|
|
115
|
+
source: string;
|
|
116
|
+
action: SyncAction;
|
|
117
|
+
/** Set for `conflict`: the other source already claiming this name. */
|
|
118
|
+
conflictWith?: string;
|
|
119
|
+
/** Resolved skill + lock entry (carried so apply needn't re-normalize). */
|
|
120
|
+
resolved: {
|
|
121
|
+
skill: Skill;
|
|
122
|
+
entry: ExternalSkillLockEntry;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
export type SyncPlan = {
|
|
126
|
+
items: SyncPlanItem[];
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Compute a deterministic sync plan over the given local sources without writing
|
|
130
|
+
* anything — the engine behind both `sync --dry-run` and `sync`. For each source
|
|
131
|
+
* (in name order) every discovered package is classified:
|
|
132
|
+
*
|
|
133
|
+
* - `conflict` — a different source earlier in the plan already claims the name;
|
|
134
|
+
* - `add` — the skill is not present on disk;
|
|
135
|
+
* - `update` — present, but the lock's recorded checksum differs (drift);
|
|
136
|
+
* - `unchanged` — present and the checksum matches the lock.
|
|
137
|
+
*
|
|
138
|
+
* Only `local` sources resolve in this slice; other types are skipped (a later
|
|
139
|
+
* slice adds git/archive fetch ahead of this same planner).
|
|
140
|
+
*/
|
|
141
|
+
export declare function planSync(workspaceDir: string, sources: ExternalSkillSource[], now: Date): SyncPlan;
|
|
142
|
+
/**
|
|
143
|
+
* Apply a sync plan: write each `add`/`update` skill package and refresh the lock
|
|
144
|
+
* to exactly the set of resolved (non-conflict) packages. `conflict` items are
|
|
145
|
+
* skipped (logged by the caller). Returns the persisted lock. Side-effecting
|
|
146
|
+
* counterpart to {@link planSync}; the dry-run path calls `planSync` only.
|
|
147
|
+
*/
|
|
148
|
+
export declare function applySync(workspaceDir: string, plan: SyncPlan): ExternalSkillLock;
|
|
149
|
+
/** One governance problem with the external registry. */
|
|
150
|
+
export type ExternalAuditFinding = {
|
|
151
|
+
kind: "unpinned-ref" | "missing-license" | "duplicate-name" | "unsupported-format" | "stale-copy";
|
|
152
|
+
subject: string;
|
|
153
|
+
detail: string;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Audit the external registry (`otto-skills audit --external`). Surfaces:
|
|
157
|
+
* unpinned source refs, lock entries with no license, duplicate skill names
|
|
158
|
+
* across sources, sources whose type this slice cannot resolve, and stale
|
|
159
|
+
* imported copies (on-disk skill checksum drifted from the lock). Pure over the
|
|
160
|
+
* given sources/lock + a checksum probe; deterministic, sorted by kind+subject.
|
|
161
|
+
*/
|
|
162
|
+
export declare function auditExternal(sources: ExternalSkillSource[], lock: ExternalSkillLock, onDiskChecksum: (skill: string) => string | null): ExternalAuditFinding[];
|
|
163
|
+
/**
|
|
164
|
+
* Recompute the checksum of an imported skill's on-disk body (`instructions.md`)
|
|
165
|
+
* so {@link auditExternal} can compare it to the lock and flag a `stale-copy`
|
|
166
|
+
* when the package was hand-edited after import. Returns null when the skill or
|
|
167
|
+
* its body is absent. The hash domain matches {@link normalizePackage}.
|
|
168
|
+
*/
|
|
169
|
+
export declare function importedChecksum(workspaceDir: string, skill: string): string | null;
|
|
170
|
+
//# sourceMappingURL=external-skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-skills.d.ts","sourceRoot":"","sources":["../src/external-skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join, relative, sep } from "node:path";
|
|
4
|
+
import { skillDir, skillExists, toSkillName, writeSkill, } from "./skills.js";
|
|
5
|
+
const SOURCES_REL = join(".otto", "skills", "sources.json");
|
|
6
|
+
const LOCK_REL = join(".otto", "skills.lock.json");
|
|
7
|
+
const SKILL_MD = "SKILL.md";
|
|
8
|
+
const MAX_DEPTH = 8;
|
|
9
|
+
/** Absolute path to the sources config (`.otto/skills/sources.json`). */
|
|
10
|
+
export function sourcesPath(workspaceDir) {
|
|
11
|
+
return join(workspaceDir, SOURCES_REL);
|
|
12
|
+
}
|
|
13
|
+
/** Absolute path to the import lockfile (`.otto/skills.lock.json`). */
|
|
14
|
+
export function lockPath(workspaceDir) {
|
|
15
|
+
return join(workspaceDir, LOCK_REL);
|
|
16
|
+
}
|
|
17
|
+
const SOURCE_TYPES = new Set([
|
|
18
|
+
"git",
|
|
19
|
+
"local",
|
|
20
|
+
"archive",
|
|
21
|
+
"registry",
|
|
22
|
+
]);
|
|
23
|
+
function stringArray(raw) {
|
|
24
|
+
return Array.isArray(raw)
|
|
25
|
+
? raw.filter((s) => typeof s === "string")
|
|
26
|
+
: [];
|
|
27
|
+
}
|
|
28
|
+
/** Normalize one untrusted source entry; null when it lacks the required shape. */
|
|
29
|
+
export function parseSource(raw) {
|
|
30
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
31
|
+
return null;
|
|
32
|
+
const o = raw;
|
|
33
|
+
if (typeof o.name !== "string" || o.name.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
if (typeof o.location !== "string" || o.location.length === 0)
|
|
36
|
+
return null;
|
|
37
|
+
const type = typeof o.type === "string" && SOURCE_TYPES.has(o.type)
|
|
38
|
+
? o.type
|
|
39
|
+
: "local";
|
|
40
|
+
const src = { name: o.name, type, location: o.location };
|
|
41
|
+
if (typeof o.ref === "string" && o.ref.length > 0)
|
|
42
|
+
src.ref = o.ref;
|
|
43
|
+
return src;
|
|
44
|
+
}
|
|
45
|
+
/** Read configured sources; absent/malformed → `[]` (never throws). */
|
|
46
|
+
export function readSources(workspaceDir) {
|
|
47
|
+
let parsed;
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(readFileSync(sourcesPath(workspaceDir), "utf8"));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const list = parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
55
|
+
? parsed.sources
|
|
56
|
+
: parsed;
|
|
57
|
+
if (!Array.isArray(list))
|
|
58
|
+
return [];
|
|
59
|
+
const out = [];
|
|
60
|
+
for (const r of list) {
|
|
61
|
+
const s = parseSource(r);
|
|
62
|
+
if (s)
|
|
63
|
+
out.push(s);
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
/** Write the sources config, sorted by name for deterministic diffs. */
|
|
68
|
+
export function writeSources(workspaceDir, sources) {
|
|
69
|
+
const sorted = [...sources].sort((a, b) => a.name.localeCompare(b.name));
|
|
70
|
+
writeFileSync(sourcesPath(workspaceDir), JSON.stringify({ sources: sorted }, null, 2) + "\n");
|
|
71
|
+
}
|
|
72
|
+
function parseLockEntry(raw) {
|
|
73
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
74
|
+
return null;
|
|
75
|
+
const o = raw;
|
|
76
|
+
if (typeof o.skill !== "string" || typeof o.source !== "string")
|
|
77
|
+
return null;
|
|
78
|
+
if (typeof o.checksum !== "string" || typeof o.importedAt !== "string") {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const type = typeof o.type === "string" && SOURCE_TYPES.has(o.type)
|
|
82
|
+
? o.type
|
|
83
|
+
: "local";
|
|
84
|
+
const e = {
|
|
85
|
+
skill: o.skill,
|
|
86
|
+
source: o.source,
|
|
87
|
+
type,
|
|
88
|
+
upstreamPath: typeof o.upstreamPath === "string" ? o.upstreamPath : "",
|
|
89
|
+
checksum: o.checksum,
|
|
90
|
+
importedAt: o.importedAt,
|
|
91
|
+
capabilities: stringArray(o.capabilities),
|
|
92
|
+
};
|
|
93
|
+
if (typeof o.ref === "string")
|
|
94
|
+
e.ref = o.ref;
|
|
95
|
+
if (typeof o.license === "string")
|
|
96
|
+
e.license = o.license;
|
|
97
|
+
return e;
|
|
98
|
+
}
|
|
99
|
+
/** Read the import lock; absent/malformed → `{ entries: [] }` (never throws). */
|
|
100
|
+
export function readLock(workspaceDir) {
|
|
101
|
+
let parsed;
|
|
102
|
+
try {
|
|
103
|
+
parsed = JSON.parse(readFileSync(lockPath(workspaceDir), "utf8"));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return { entries: [] };
|
|
107
|
+
}
|
|
108
|
+
const list = parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
109
|
+
? parsed.entries
|
|
110
|
+
: parsed;
|
|
111
|
+
if (!Array.isArray(list))
|
|
112
|
+
return { entries: [] };
|
|
113
|
+
const entries = [];
|
|
114
|
+
for (const r of list) {
|
|
115
|
+
const e = parseLockEntry(r);
|
|
116
|
+
if (e)
|
|
117
|
+
entries.push(e);
|
|
118
|
+
}
|
|
119
|
+
return { entries };
|
|
120
|
+
}
|
|
121
|
+
/** Write the lock, entries sorted by skill name for deterministic diffs. */
|
|
122
|
+
export function writeLock(workspaceDir, lock) {
|
|
123
|
+
const entries = [...lock.entries].sort((a, b) => a.skill.localeCompare(b.skill));
|
|
124
|
+
writeFileSync(lockPath(workspaceDir), JSON.stringify({ entries }, null, 2) + "\n");
|
|
125
|
+
}
|
|
126
|
+
/** Add (or replace by name) a source. Pure — returns a new array. */
|
|
127
|
+
export function addSource(sources, source) {
|
|
128
|
+
return [...sources.filter((s) => s.name !== source.name), source];
|
|
129
|
+
}
|
|
130
|
+
/** Remove a source by name. Pure — returns a new array. */
|
|
131
|
+
export function removeSource(sources, name) {
|
|
132
|
+
return sources.filter((s) => s.name !== name);
|
|
133
|
+
}
|
|
134
|
+
/** sha256 of a buffer/string, hex (stable content checksum). */
|
|
135
|
+
function checksum(content) {
|
|
136
|
+
return createHash("sha256").update(content).digest("hex");
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Parse a leading `--- … ---` frontmatter block into flat string fields plus the
|
|
140
|
+
* remaining body. Minimal `key: value` parsing (no nested YAML) — enough for the
|
|
141
|
+
* `name`/`description`/`license`/`capabilities` fields skill packs declare.
|
|
142
|
+
*/
|
|
143
|
+
export function parseFrontmatter(text) {
|
|
144
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text);
|
|
145
|
+
if (!m)
|
|
146
|
+
return { fields: {}, body: text };
|
|
147
|
+
const fields = {};
|
|
148
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
149
|
+
const kv = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line);
|
|
150
|
+
if (kv)
|
|
151
|
+
fields[kv[1].toLowerCase()] = kv[2].trim();
|
|
152
|
+
}
|
|
153
|
+
return { fields, body: text.slice(m[0].length) };
|
|
154
|
+
}
|
|
155
|
+
function splitList(raw) {
|
|
156
|
+
if (!raw)
|
|
157
|
+
return [];
|
|
158
|
+
return raw
|
|
159
|
+
.replace(/^\[|\]$/g, "")
|
|
160
|
+
.split(",")
|
|
161
|
+
.map((s) => s.trim().replace(/^["']|["']$/g, ""))
|
|
162
|
+
.filter((s) => s.length > 0);
|
|
163
|
+
}
|
|
164
|
+
function listDirs(dir) {
|
|
165
|
+
try {
|
|
166
|
+
return readdirSync(dir, { withFileTypes: true })
|
|
167
|
+
.filter((e) => e.isDirectory())
|
|
168
|
+
.map((e) => e.name);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Find every `SKILL.md` package under a local source directory (recursively,
|
|
176
|
+
* depth-bounded). Covers the `skills/<name>/SKILL.md` Superpowers/PM-Skills shape
|
|
177
|
+
* and `.codex-plugin`/`.claude-plugin` bundles that nest the same file. Each
|
|
178
|
+
* package's skill name comes from its SKILL.md `name:` frontmatter, else its
|
|
179
|
+
* containing directory name, slugified. Returns packages sorted by name. Absent/
|
|
180
|
+
* unreadable dir → `[]` (never throws).
|
|
181
|
+
*/
|
|
182
|
+
export function discoverPackages(sourceDir) {
|
|
183
|
+
const found = [];
|
|
184
|
+
const walk = (dir, depth) => {
|
|
185
|
+
if (depth > MAX_DEPTH)
|
|
186
|
+
return;
|
|
187
|
+
const mdPath = join(dir, SKILL_MD);
|
|
188
|
+
if (existsSync(mdPath)) {
|
|
189
|
+
let raw;
|
|
190
|
+
try {
|
|
191
|
+
raw = readFileSync(mdPath, "utf8");
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
raw = "";
|
|
195
|
+
}
|
|
196
|
+
const { fields } = parseFrontmatter(raw);
|
|
197
|
+
const rel = relative(sourceDir, dir);
|
|
198
|
+
const name = toSkillName(fields.name ?? "") ||
|
|
199
|
+
toSkillName(rel.split(sep).pop() ?? "") ||
|
|
200
|
+
toSkillName(rel);
|
|
201
|
+
if (name) {
|
|
202
|
+
found.push({
|
|
203
|
+
name,
|
|
204
|
+
upstreamPath: rel === "" ? "." : rel.split(sep).join("/"),
|
|
205
|
+
raw,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return; // a package directory is a leaf; don't descend into it
|
|
209
|
+
}
|
|
210
|
+
for (const child of listDirs(dir))
|
|
211
|
+
walk(join(dir, child), depth + 1);
|
|
212
|
+
};
|
|
213
|
+
walk(sourceDir, 0);
|
|
214
|
+
return found.sort((a, b) => a.name.localeCompare(b.name));
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Normalize a discovered package + its source into an unverified, inert
|
|
218
|
+
* {@link Skill} plus the resolved {@link ExternalSkillLockEntry}. The skill body
|
|
219
|
+
* is the SKILL.md content minus frontmatter; capabilities come from a
|
|
220
|
+
* `capabilities:` frontmatter field when present (else empty); trust is always
|
|
221
|
+
* `unverified` and validation empty so the loop cannot apply it. `now` is the
|
|
222
|
+
* import timestamp (injected for deterministic tests).
|
|
223
|
+
*/
|
|
224
|
+
export function normalizePackage(source, pkg, now) {
|
|
225
|
+
const { fields, body } = parseFrontmatter(pkg.raw);
|
|
226
|
+
const capabilities = splitList(fields.capabilities);
|
|
227
|
+
const license = fields.license;
|
|
228
|
+
// Checksum the persisted body (what lands in instructions.md) so a later audit
|
|
229
|
+
// can recompute it from disk and detect hand-edits after import.
|
|
230
|
+
const instructions = body.trim() + "\n";
|
|
231
|
+
const sum = checksum(instructions);
|
|
232
|
+
const provenance = {
|
|
233
|
+
source: source.name,
|
|
234
|
+
upstreamPath: pkg.upstreamPath,
|
|
235
|
+
checksum: sum,
|
|
236
|
+
};
|
|
237
|
+
if (source.ref)
|
|
238
|
+
provenance.upstreamRef = source.ref;
|
|
239
|
+
if (license)
|
|
240
|
+
provenance.license = license;
|
|
241
|
+
const skill = {
|
|
242
|
+
name: pkg.name,
|
|
243
|
+
version: typeof fields.version === "string" ? fields.version : "0.0.0",
|
|
244
|
+
capabilities,
|
|
245
|
+
constraints: [],
|
|
246
|
+
scope: [],
|
|
247
|
+
instructions,
|
|
248
|
+
scripts: {},
|
|
249
|
+
tests: [],
|
|
250
|
+
validation: {},
|
|
251
|
+
trust: "unverified",
|
|
252
|
+
createdAt: now.toISOString(),
|
|
253
|
+
useCount: 0,
|
|
254
|
+
provenance,
|
|
255
|
+
};
|
|
256
|
+
const entry = {
|
|
257
|
+
skill: pkg.name,
|
|
258
|
+
source: source.name,
|
|
259
|
+
type: source.type,
|
|
260
|
+
upstreamPath: pkg.upstreamPath,
|
|
261
|
+
checksum: sum,
|
|
262
|
+
importedAt: now.toISOString(),
|
|
263
|
+
capabilities,
|
|
264
|
+
};
|
|
265
|
+
if (source.ref)
|
|
266
|
+
entry.ref = source.ref;
|
|
267
|
+
if (license)
|
|
268
|
+
entry.license = license;
|
|
269
|
+
return { skill, entry };
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Compute a deterministic sync plan over the given local sources without writing
|
|
273
|
+
* anything — the engine behind both `sync --dry-run` and `sync`. For each source
|
|
274
|
+
* (in name order) every discovered package is classified:
|
|
275
|
+
*
|
|
276
|
+
* - `conflict` — a different source earlier in the plan already claims the name;
|
|
277
|
+
* - `add` — the skill is not present on disk;
|
|
278
|
+
* - `update` — present, but the lock's recorded checksum differs (drift);
|
|
279
|
+
* - `unchanged` — present and the checksum matches the lock.
|
|
280
|
+
*
|
|
281
|
+
* Only `local` sources resolve in this slice; other types are skipped (a later
|
|
282
|
+
* slice adds git/archive fetch ahead of this same planner).
|
|
283
|
+
*/
|
|
284
|
+
export function planSync(workspaceDir, sources, now) {
|
|
285
|
+
const lock = readLock(workspaceDir);
|
|
286
|
+
const lockBySkill = new Map(lock.entries.map((e) => [e.skill, e]));
|
|
287
|
+
const claimedBy = new Map();
|
|
288
|
+
const items = [];
|
|
289
|
+
for (const source of [...sources].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
290
|
+
if (source.type !== "local")
|
|
291
|
+
continue;
|
|
292
|
+
for (const pkg of discoverPackages(source.location)) {
|
|
293
|
+
const resolved = normalizePackage(source, pkg, now);
|
|
294
|
+
const claimer = claimedBy.get(pkg.name);
|
|
295
|
+
if (claimer && claimer !== source.name) {
|
|
296
|
+
items.push({
|
|
297
|
+
skill: pkg.name,
|
|
298
|
+
source: source.name,
|
|
299
|
+
action: "conflict",
|
|
300
|
+
conflictWith: claimer,
|
|
301
|
+
resolved,
|
|
302
|
+
});
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
claimedBy.set(pkg.name, source.name);
|
|
306
|
+
let action;
|
|
307
|
+
const locked = lockBySkill.get(pkg.name);
|
|
308
|
+
if (!skillExists(workspaceDir, pkg.name) || !locked) {
|
|
309
|
+
action = "add";
|
|
310
|
+
}
|
|
311
|
+
else if (locked.checksum !== resolved.entry.checksum) {
|
|
312
|
+
action = "update";
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
action = "unchanged";
|
|
316
|
+
}
|
|
317
|
+
items.push({ skill: pkg.name, source: source.name, action, resolved });
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return { items };
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Apply a sync plan: write each `add`/`update` skill package and refresh the lock
|
|
324
|
+
* to exactly the set of resolved (non-conflict) packages. `conflict` items are
|
|
325
|
+
* skipped (logged by the caller). Returns the persisted lock. Side-effecting
|
|
326
|
+
* counterpart to {@link planSync}; the dry-run path calls `planSync` only.
|
|
327
|
+
*/
|
|
328
|
+
export function applySync(workspaceDir, plan) {
|
|
329
|
+
const entries = [];
|
|
330
|
+
for (const item of plan.items) {
|
|
331
|
+
if (item.action === "conflict")
|
|
332
|
+
continue;
|
|
333
|
+
if (item.action === "add" || item.action === "update") {
|
|
334
|
+
writeSkill(workspaceDir, item.resolved.skill);
|
|
335
|
+
}
|
|
336
|
+
entries.push(item.resolved.entry);
|
|
337
|
+
}
|
|
338
|
+
const lock = { entries };
|
|
339
|
+
writeLock(workspaceDir, lock);
|
|
340
|
+
return lock;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Audit the external registry (`otto-skills audit --external`). Surfaces:
|
|
344
|
+
* unpinned source refs, lock entries with no license, duplicate skill names
|
|
345
|
+
* across sources, sources whose type this slice cannot resolve, and stale
|
|
346
|
+
* imported copies (on-disk skill checksum drifted from the lock). Pure over the
|
|
347
|
+
* given sources/lock + a checksum probe; deterministic, sorted by kind+subject.
|
|
348
|
+
*/
|
|
349
|
+
export function auditExternal(sources, lock, onDiskChecksum) {
|
|
350
|
+
const findings = [];
|
|
351
|
+
for (const s of sources) {
|
|
352
|
+
if ((s.type === "git" || s.type === "archive") && !s.ref) {
|
|
353
|
+
findings.push({
|
|
354
|
+
kind: "unpinned-ref",
|
|
355
|
+
subject: s.name,
|
|
356
|
+
detail: `source "${s.name}" (${s.type}) has no pinned ref`,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
if (s.type === "registry") {
|
|
360
|
+
findings.push({
|
|
361
|
+
kind: "unsupported-format",
|
|
362
|
+
subject: s.name,
|
|
363
|
+
detail: `source type "registry" is not resolvable yet`,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const bySkill = new Map();
|
|
368
|
+
for (const e of lock.entries) {
|
|
369
|
+
(bySkill.get(e.skill) ?? bySkill.set(e.skill, []).get(e.skill)).push(e);
|
|
370
|
+
}
|
|
371
|
+
for (const [skill, es] of bySkill) {
|
|
372
|
+
if (es.length > 1) {
|
|
373
|
+
const srcs = [...new Set(es.map((e) => e.source))].sort();
|
|
374
|
+
if (srcs.length > 1) {
|
|
375
|
+
findings.push({
|
|
376
|
+
kind: "duplicate-name",
|
|
377
|
+
subject: skill,
|
|
378
|
+
detail: `skill "${skill}" imported from multiple sources: ${srcs.join(", ")}`,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
for (const e of lock.entries) {
|
|
384
|
+
if (!e.license) {
|
|
385
|
+
findings.push({
|
|
386
|
+
kind: "missing-license",
|
|
387
|
+
subject: e.skill,
|
|
388
|
+
detail: `imported skill "${e.skill}" (from ${e.source}) has no license`,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
const disk = onDiskChecksum(e.skill);
|
|
392
|
+
if (disk !== null && disk !== e.checksum) {
|
|
393
|
+
findings.push({
|
|
394
|
+
kind: "stale-copy",
|
|
395
|
+
subject: e.skill,
|
|
396
|
+
detail: `on-disk "${e.skill}" drifted from lock (re-run sync)`,
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return findings.sort((a, b) => a.kind.localeCompare(b.kind) || a.subject.localeCompare(b.subject));
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Recompute the checksum of an imported skill's on-disk body (`instructions.md`)
|
|
404
|
+
* so {@link auditExternal} can compare it to the lock and flag a `stale-copy`
|
|
405
|
+
* when the package was hand-edited after import. Returns null when the skill or
|
|
406
|
+
* its body is absent. The hash domain matches {@link normalizePackage}.
|
|
407
|
+
*/
|
|
408
|
+
export function importedChecksum(workspaceDir, skill) {
|
|
409
|
+
try {
|
|
410
|
+
const body = readFileSync(join(skillDir(workspaceDir, skill), "instructions.md"), "utf8");
|
|
411
|
+
return checksum(body);
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
//# sourceMappingURL=external-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-skills.js","sourceRoot":"","sources":["../src/external-skills.ts"],"names":[],"mappings":"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"}
|