@delorenj/skillex 0.1.3 → 0.3.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.
@@ -0,0 +1,9 @@
1
+ import type { Command } from "commander";
2
+ import { type ResultEnvelope } from "../index.js";
3
+ interface Output {
4
+ emit(result: ResultEnvelope<unknown>, text?: string): void;
5
+ help(command: Command): void;
6
+ }
7
+ /** Register BMAD freeze/status/explain; activation stays an explicit, separate step. */
8
+ export declare function registerBmadCommands(program: Command, output: Output): void;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { Command } from "commander";
2
+ import type { ResultEnvelope } from "../core/result.js";
3
+ interface Output {
4
+ emit(result: ResultEnvelope<unknown>, text?: string): void;
5
+ help(command: Command): void;
6
+ }
7
+ export declare function registerClientCommands(program: Command, output: Output): void;
8
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { Command } from "commander";
2
+ import type { ResultEnvelope } from "../core/result.js";
3
+ interface Output {
4
+ emit(result: ResultEnvelope<unknown>, text?: string): void;
5
+ help(command: Command): void;
6
+ }
7
+ export declare function registerIntegrationCommands(program: Command, output: Output): void;
8
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { Command } from "commander";
2
+ import type { ResultEnvelope } from "../core/result.js";
3
+ interface Output {
4
+ emit(result: ResultEnvelope<unknown>, text?: string): void;
5
+ help(command: Command): void;
6
+ }
7
+ export declare function registerRootCommands(program: Command, output: Output): void;
8
+ export {};
@@ -9,7 +9,8 @@ export interface OwnedNode {
9
9
  readonly children?: Readonly<Record<string, EntryIdentity>>;
10
10
  }
11
11
  export interface SourceRevision {
12
- readonly kind: "catalog" | "pack";
12
+ /** Legacy receipts recorded "pack" for whole-root pack sources; they stay readable. */
13
+ readonly kind: "catalog" | "pack" | "set";
13
14
  readonly path: string;
14
15
  readonly commit: string | null;
15
16
  readonly reason: string | null;
@@ -0,0 +1,9 @@
1
+ import type { BmadFreezeData, BmadFreezeOptions } from "./bmad-types.js";
2
+ import { type ResultEnvelope } from "./result.js";
3
+ /**
4
+ * Freeze the BMAD skills and per-client commands of a BMAD-enabled project into a
5
+ * versioned reference-only registry pack (ADR-0001). Import is offline, idempotent,
6
+ * and guarded: same-version repeats change nothing, and a differing existing canonical
7
+ * body is refused rather than overwritten.
8
+ */
9
+ export declare function freezeBmadPack(source: string, options?: BmadFreezeOptions): Promise<ResultEnvelope<BmadFreezeData | null>>;
@@ -0,0 +1,40 @@
1
+ import type { BmadCommandInventory, BmadProvenance, BmadSkillManifestEntry } from "./bmad-types.js";
2
+ /** Per-client command layouts discovered on a BMAD-enabled project. Not exhaustive. */
3
+ export declare const BMAD_COMMAND_CLIENTS: ReadonlyArray<{
4
+ client: string;
5
+ layout: string;
6
+ }>;
7
+ export declare const BMAD_PACK_NAME = "bmad";
8
+ export declare function sha256File(path: string): Promise<string>;
9
+ /** Expand `~` exactly like other skillex path options; the result must be a real directory. */
10
+ export declare function resolveBmadSource(source: string, options: {
11
+ cwd?: string;
12
+ }): Promise<string>;
13
+ /** Read the source's own manifests. Entirely offline; nothing is fetched. */
14
+ export declare function inspectBmadSource(sourceRoot: string): Promise<BmadProvenance>;
15
+ /**
16
+ * Membership source of truth: the source's skill-manifest.csv, reconciled against the
17
+ * rendered .agents/skills tree. Rendered bmad-* directories absent from the manifest are
18
+ * inventoried as foreign (installer-owned), never imported silently.
19
+ */
20
+ export declare function readBmadSkillManifest(sourceRoot: string): Promise<{
21
+ entries: BmadSkillManifestEntry[];
22
+ path: string;
23
+ }>;
24
+ export interface BmadCommandScan {
25
+ readonly inventory: BmadCommandInventory;
26
+ readonly totalFiles: number;
27
+ readonly danglingFiles: number;
28
+ }
29
+ export declare function bmadCommandRefs(content: string): string[];
30
+ /**
31
+ * Copy each client's command layout byte-for-byte. Original assets are preserved; files
32
+ * whose `_bmad/...` references are dangling in the source install are imported but
33
+ * reported, never silently rewritten into shims.
34
+ */
35
+ export declare function scanBmadCommands(sourceRoot: string, packVersionPath: string): Promise<BmadCommandScan>;
36
+ /** Absolute, safe version directory; refuses any traversal outside the pack family. */
37
+ export declare function bmadPackPath(registryRoot: string, version: string): string;
38
+ /** The rendered skill bytes are the only complete source: the source's own tree is pruned. */
39
+ export declare function renderedSkillDir(sourceRoot: string, name: string): string;
40
+ export declare function requireRenderedSkill(sourceRoot: string, name: string): Promise<string>;
@@ -0,0 +1,10 @@
1
+ import type { BmadExplainData, BmadExplainOptions, BmadStatusData, BmadStatusOptions } from "./bmad-types.js";
2
+ import { type ResultEnvelope } from "./result.js";
3
+ /**
4
+ * Read-only traceability for the BMAD canonical skills present in a registry. Every
5
+ * frozen BMAD skill is traced against its recorded baseline digest; undeclared pack
6
+ * children are reported as traceability gaps instead of a misleading green verify.
7
+ */
8
+ export declare function inspectBmadStatus(options?: BmadStatusOptions): Promise<ResultEnvelope<BmadStatusData | null>>;
9
+ /** Read-only explanation of one canonical BMAD skill: provenance, baseline, references. */
10
+ export declare function explainBmadSkill(name: string, options?: BmadExplainOptions): Promise<ResultEnvelope<BmadExplainData | null>>;
@@ -0,0 +1,150 @@
1
+ import type { CatalogLockOptions } from "./catalog-lock.js";
2
+ import type { RegistryOptions, RegistrySelection } from "./selection.js";
3
+ /** Freeze operates only on real local directories; registry URLs are never fetched. */
4
+ export interface BmadFreezeOptions extends RegistryOptions, CatalogLockOptions {
5
+ readonly version?: string;
6
+ readonly dryRun?: boolean;
7
+ readonly replace?: boolean;
8
+ readonly commands?: boolean;
9
+ }
10
+ export interface BmadSourceModule {
11
+ readonly name: string;
12
+ readonly version: string;
13
+ readonly source: string | null;
14
+ readonly repoUrl: string | null;
15
+ readonly sha: string | null;
16
+ }
17
+ export interface BmadSourceInstallation {
18
+ readonly version: string;
19
+ readonly installDate: string | null;
20
+ readonly lastUpdated: string | null;
21
+ }
22
+ /** Evidence captured offline from the source install's own manifests. */
23
+ export interface BmadProvenance {
24
+ readonly sourceRoot: string;
25
+ readonly installation: BmadSourceInstallation;
26
+ readonly modules: readonly BmadSourceModule[];
27
+ readonly skillManifestSha256: string | null;
28
+ readonly filesManifestSha256: string | null;
29
+ readonly filesManifestDeclared: number;
30
+ readonly filesManifestMissing: number;
31
+ }
32
+ export type BmadInventoryStatus = "imported" | "unchanged" | "skipped" | "failed";
33
+ export interface BmadSkillInventory {
34
+ readonly name: string;
35
+ readonly sourcePath: string;
36
+ readonly status: BmadInventoryStatus;
37
+ readonly digest: string | null;
38
+ readonly recordedDigest: string | null;
39
+ }
40
+ /** Skills installed by the source but outside the frozen manifest, inventoried separately. */
41
+ export interface BmadForeignSkill {
42
+ readonly name: string;
43
+ readonly path: string;
44
+ }
45
+ export interface BmadSkillManifestEntry {
46
+ readonly canonicalId: string;
47
+ readonly name: string;
48
+ readonly description: string | null;
49
+ readonly module: string | null;
50
+ readonly path: string | null;
51
+ }
52
+ export interface BmadCommandClient {
53
+ readonly client: string;
54
+ readonly layout: string;
55
+ readonly directory: string;
56
+ readonly imported: number;
57
+ readonly dangling: number;
58
+ }
59
+ export interface BmadCommandFile {
60
+ readonly name: string;
61
+ readonly client: string;
62
+ readonly layout: string;
63
+ readonly path: string;
64
+ readonly sourcePath: string;
65
+ readonly sha256: string;
66
+ readonly size: number;
67
+ readonly bmadRefs: readonly string[];
68
+ readonly danglingRefs: readonly string[];
69
+ }
70
+ export interface BmadCommandInventory {
71
+ readonly clients: readonly BmadCommandClient[];
72
+ readonly files: readonly BmadCommandFile[];
73
+ }
74
+ export interface BmadFreezeChange {
75
+ readonly action: string;
76
+ readonly path: string;
77
+ readonly source?: string;
78
+ }
79
+ export interface BmadFreezeData {
80
+ readonly registry: RegistrySelection;
81
+ readonly pack: {
82
+ readonly name: string;
83
+ readonly version: string;
84
+ readonly path: string;
85
+ };
86
+ readonly provenance: BmadProvenance;
87
+ readonly sourceRoot: string;
88
+ readonly dryRun: boolean;
89
+ readonly skills: readonly BmadSkillInventory[];
90
+ readonly foreignSkills: readonly BmadForeignSkill[];
91
+ readonly skillsDeclared: number;
92
+ readonly skillsImported: number;
93
+ readonly skillsUnchanged: number;
94
+ readonly skillsSkipped: number;
95
+ readonly skillsFailed: number;
96
+ readonly commands: BmadCommandInventory;
97
+ readonly commandFiles: number;
98
+ readonly danglingCommands: number;
99
+ readonly changes: readonly BmadFreezeChange[];
100
+ }
101
+ export interface BmadStatusOptions extends RegistryOptions {
102
+ readonly signal?: {
103
+ readonly aborted: boolean;
104
+ };
105
+ }
106
+ export type BmadCanonicalState = "ok" | "missing" | "foreign" | "modified";
107
+ export interface BmadCanonicalStatus {
108
+ readonly name: string;
109
+ readonly path: string;
110
+ readonly state: BmadCanonicalState;
111
+ readonly digest: string | null;
112
+ readonly recordedDigest: string | null;
113
+ readonly references: readonly string[];
114
+ readonly provenance: Readonly<Record<string, unknown>> | null;
115
+ }
116
+ export interface BmadStatusData {
117
+ readonly registry: RegistrySelection;
118
+ readonly skills: readonly BmadCanonicalStatus[];
119
+ readonly traced: number;
120
+ readonly drifted: readonly string[];
121
+ readonly untraced: readonly string[];
122
+ readonly pack: string | null;
123
+ readonly packMembers: readonly string[];
124
+ readonly packVerified: boolean | null;
125
+ readonly findings: readonly import("./result.js").Diagnostic[];
126
+ }
127
+ export interface BmadExplainOptions extends RegistryOptions {
128
+ readonly signal?: {
129
+ readonly aborted: boolean;
130
+ };
131
+ }
132
+ export interface BmadReference {
133
+ readonly kind: "pack" | "set" | "skill";
134
+ readonly name: string;
135
+ readonly version?: string;
136
+ }
137
+ export interface BmadSkillExplanation {
138
+ readonly name: string;
139
+ readonly canonicalPath: string | null;
140
+ readonly digest: string | null;
141
+ readonly recordedDigest: string | null;
142
+ readonly modifiedLocally: boolean | null;
143
+ readonly bmadVersion: string | null;
144
+ readonly references: readonly BmadReference[];
145
+ readonly findings: readonly import("./result.js").Diagnostic[];
146
+ }
147
+ export interface BmadExplainData {
148
+ readonly registry: RegistrySelection;
149
+ readonly skill: BmadSkillExplanation;
150
+ }
@@ -15,6 +15,11 @@ export interface CatalogWriteResult {
15
15
  }
16
16
  export interface CatalogWriteOptions extends RegistryOptions, CatalogLockOptions {
17
17
  readonly dryRun?: boolean;
18
+ /**
19
+ * Override the receipt's imported_from label, e.g. a sanitized Git URL
20
+ * instead of an ephemeral clone path, so provenance outlives the clone.
21
+ */
22
+ readonly importedFrom?: string;
18
23
  }
19
24
  export interface CreateSkillOptions extends CatalogWriteOptions {
20
25
  readonly description?: string;
@@ -0,0 +1,74 @@
1
+ import { type ResultEnvelope } from "./result.js";
2
+ import type { ResolveOptions } from "./selection.js";
3
+ export interface ClientIsolationOptions extends Omit<ResolveOptions, "scope" | "inheritGlobal"> {
4
+ readonly client?: string;
5
+ readonly apply?: boolean;
6
+ readonly dryRun?: boolean;
7
+ /** Explicitly permit the project block to override shared user permissions, never agent rules. */
8
+ readonly overridePermissions?: boolean;
9
+ readonly stateHome?: string;
10
+ readonly timeoutMs?: number;
11
+ }
12
+ export interface ClientVerifyOptions extends Omit<ClientIsolationOptions, "apply" | "dryRun"> {
13
+ /** A caller-owned, existing probe session. Verification never creates sessions. */
14
+ readonly session?: string;
15
+ readonly agent?: string;
16
+ }
17
+ interface Rule {
18
+ action: string;
19
+ resource: string;
20
+ effect: "allow" | "deny" | "ask";
21
+ }
22
+ export interface ClientIsolationPlan {
23
+ readonly client: "opencode";
24
+ readonly project: string;
25
+ readonly set: string | null;
26
+ readonly members: readonly string[];
27
+ readonly config: string;
28
+ readonly receipt: string;
29
+ readonly changes: readonly {
30
+ path: string;
31
+ action: "create" | "update" | "remove";
32
+ }[];
33
+ readonly recovery: boolean;
34
+ readonly overrides: readonly {
35
+ path: string;
36
+ rule: number;
37
+ }[];
38
+ }
39
+ export interface ClientIsolationResult extends ClientIsolationPlan {
40
+ readonly dryRun: boolean;
41
+ readonly applied: boolean;
42
+ readonly runtimeVerified: false;
43
+ }
44
+ export interface ClientVerification {
45
+ readonly client: "opencode";
46
+ readonly project: string;
47
+ readonly set: string;
48
+ readonly session: string;
49
+ readonly agent: string;
50
+ readonly evidence: "opencode-v2-permission-evaluator";
51
+ readonly registryCount: number;
52
+ readonly checked: readonly {
53
+ id: string;
54
+ expected: Rule["effect"];
55
+ effect: Rule["effect"];
56
+ request: string;
57
+ }[];
58
+ readonly advertised: readonly string[];
59
+ }
60
+ /** Native V2 API envelope; a transport seam for fixtures, not an alternate evaluator. */
61
+ export type OpenCodeRequest = (method: "get" | "post", path: string, body?: Readonly<Record<string, unknown>>) => Promise<unknown>;
62
+ export declare class ClientIsolationCommand {
63
+ readonly options: ClientIsolationOptions;
64
+ readonly remove: boolean;
65
+ constructor(options: ClientIsolationOptions, remove?: boolean);
66
+ plan(): Promise<ClientIsolationPlan>;
67
+ execute(): Promise<ResultEnvelope<ClientIsolationResult | null>>;
68
+ }
69
+ export declare function isolateClient(options: ClientIsolationOptions): Promise<ResultEnvelope<ClientIsolationResult | null>>;
70
+ /** Removes only receipt-owned rules; works after the project set has been unset. */
71
+ export declare function unisolateClient(options: ClientIsolationOptions): Promise<ResultEnvelope<ClientIsolationResult | null>>;
72
+ /** Checks the actual permission service, including agent and session overrides, without inference. */
73
+ export declare function verifyClientIsolation(options: ClientVerifyOptions, request?: OpenCodeRequest): Promise<ResultEnvelope<ClientVerification | null>>;
74
+ export {};
@@ -8,6 +8,14 @@ interface LinkIdentity {
8
8
  readonly raw: string;
9
9
  readonly target: string;
10
10
  }
11
+ export interface CompositionDocument {
12
+ readonly path: string;
13
+ readonly bytes: Buffer;
14
+ readonly before?: {
15
+ bytes: Buffer;
16
+ info: Stats;
17
+ };
18
+ }
11
19
  export interface CompositionPlan {
12
20
  readonly registry: RegistrySelection;
13
21
  readonly composition: CompositionDetails;
@@ -15,14 +23,8 @@ export interface CompositionPlan {
15
23
  readonly changes: CompositionChange[];
16
24
  readonly directories: Map<string, Stats>;
17
25
  readonly links: Map<string, LinkIdentity>;
18
- manifest?: {
19
- path: string;
20
- bytes: Buffer;
21
- before?: {
22
- bytes: Buffer;
23
- info: Stats;
24
- };
25
- };
26
+ manifest?: CompositionDocument;
27
+ origin?: CompositionDocument;
26
28
  }
27
29
  export declare function compositionError<T>(command: string, error: unknown): ResultEnvelope<T | null>;
28
30
  export declare function conflict(path: string, message?: string): never;
@@ -17,7 +17,7 @@ export interface CompositionDetails {
17
17
  readonly description?: string;
18
18
  }
19
19
  export interface CompositionChange {
20
- readonly action: "create-directory" | "create-link" | "remove-link" | "write-manifest";
20
+ readonly action: "create-directory" | "create-link" | "remove-link" | "write-manifest" | "write-origin";
21
21
  readonly path: string;
22
22
  readonly target?: string;
23
23
  }
@@ -0,0 +1,59 @@
1
+ import type { CompositionChange, CompositionMutationData, CompositionOptions } from "./composition-types.js";
2
+ import { type ResultEnvelope } from "./result.js";
3
+ import type { RegistrySelection, ScopeName } from "./selection.js";
4
+ import { type DerivedSetDeclaration, type SetOrigin } from "./set-origin.js";
5
+ export interface DerivationOwner {
6
+ readonly scope: ScopeName;
7
+ readonly root: string;
8
+ }
9
+ export interface DerivationInputs {
10
+ readonly base: string | null;
11
+ readonly packs: readonly string[];
12
+ readonly skills: readonly string[];
13
+ readonly removed: readonly string[];
14
+ }
15
+ export interface DerivationPreview {
16
+ readonly registry: RegistrySelection;
17
+ readonly owner: DerivationOwner;
18
+ readonly name: string;
19
+ readonly path: string;
20
+ readonly inputs: DerivationInputs;
21
+ readonly members: readonly {
22
+ readonly name: string;
23
+ readonly path: string;
24
+ }[];
25
+ readonly creates: boolean;
26
+ readonly changes: readonly CompositionChange[];
27
+ }
28
+ /** Membership a derived set must materialize: base ∪ packs ∪ skills − removed. */
29
+ export declare function desiredDerivedMembers(registry: string, inputs: DerivationInputs, ancestors?: ReadonlySet<string>): Promise<Map<string, string>>;
30
+ /** Validate the complete derived projection, not just the links that survived. */
31
+ export declare function verifyDerivedMembers(registry: string, inventory: {
32
+ readonly path: string;
33
+ readonly names: readonly string[];
34
+ }, derived: DerivedSetDeclaration, ancestors?: ReadonlySet<string>): Promise<void>;
35
+ /** Read the current derivation state of a set, if it is a derived set at all. */
36
+ export declare function derivedState(registry: string, name: string): Promise<{
37
+ path: string;
38
+ origin: SetOrigin & {
39
+ derived: DerivedSetDeclaration;
40
+ };
41
+ members: string[];
42
+ } | undefined>;
43
+ /** The name of the derived set this scope owns for the given base. */
44
+ export declare function ownedDerivedName(base: string | null, ownerRoot: string): string;
45
+ /** Read-only derivation preview for command planning and dry runs. */
46
+ export declare function planDerivedSet(options: CompositionOptions & {
47
+ owner: DerivationOwner;
48
+ inputs: DerivationInputs;
49
+ }): Promise<DerivationPreview>;
50
+ /** Materialize (or update) the scope-owned derived set. Registry-only write. */
51
+ export declare function materializeDerivedSet(options: CompositionOptions & {
52
+ owner: DerivationOwner;
53
+ inputs: DerivationInputs;
54
+ }): Promise<ResultEnvelope<CompositionMutationData | null>>;
55
+ /** Remove only an owned derived set, serialized with every composition writer. */
56
+ export declare function retireDerivedSet(options: CompositionOptions, owner: DerivationOwner, name: string): Promise<ResultEnvelope<{
57
+ retired: string | null;
58
+ removed: readonly string[];
59
+ } | null>>;
@@ -9,7 +9,7 @@ export interface PathObservation {
9
9
  readonly rawTarget: string | null;
10
10
  readonly target: string | null;
11
11
  readonly reachable: boolean;
12
- readonly ownership: "owned" | "foreign" | "changed" | "pack" | "none";
12
+ readonly ownership: "owned" | "foreign" | "changed" | "set" | "none";
13
13
  }
14
14
  export interface SkillObservation extends PathObservation {
15
15
  readonly name: string;
@@ -30,7 +30,7 @@ export interface StatusScope {
30
30
  readonly scope: ScopeName;
31
31
  readonly root: string;
32
32
  readonly manifestPath: string;
33
- readonly mode: "composed" | "pack" | null;
33
+ readonly mode: "composed" | "set" | null;
34
34
  readonly desired: readonly string[] | null;
35
35
  readonly actual: {
36
36
  readonly root: PathObservation;
@@ -41,7 +41,7 @@ export interface StatusScope {
41
41
  readonly actual: number;
42
42
  readonly owned: number;
43
43
  readonly foreign: number;
44
- readonly pack: number;
44
+ readonly set: number;
45
45
  readonly missing: number | null;
46
46
  };
47
47
  readonly aliases: readonly AliasObservation[];
@@ -0,0 +1,131 @@
1
+ import type { CompositionOptions } from "./composition-types.js";
2
+ import { type Diagnostic } from "./result.js";
3
+ export interface SourceEntry {
4
+ readonly name: string;
5
+ readonly path: string;
6
+ readonly disposition: "mapped" | "unmapped" | "divergent" | "broken" | "foreign";
7
+ readonly canonical?: string;
8
+ /** Real directory an explicit import would copy from (links resolve first). */
9
+ readonly importPath?: string;
10
+ readonly reason?: string;
11
+ }
12
+ export interface SourceProvenance {
13
+ readonly type: "path" | "git";
14
+ readonly label: string;
15
+ readonly commit?: string;
16
+ }
17
+ export interface SourceInventory {
18
+ readonly label: string;
19
+ readonly kind: "path" | "git";
20
+ readonly root: string | undefined;
21
+ readonly entries: readonly SourceEntry[];
22
+ readonly provenance: SourceProvenance;
23
+ readonly temporary: string | undefined;
24
+ readonly findings: readonly Diagnostic[];
25
+ }
26
+ export interface SourceOptions {
27
+ readonly cwd?: string;
28
+ readonly home?: string;
29
+ readonly signal?: {
30
+ readonly aborted: boolean;
31
+ };
32
+ }
33
+ /** One source skill that has no canonical definition yet. */
34
+ export interface PendingImport {
35
+ readonly name: string;
36
+ readonly path: string;
37
+ /** Stable provenance label: sanitized URL (plus commit for Git), never a clone temp path. */
38
+ readonly label: string;
39
+ }
40
+ export interface MembershipOptions {
41
+ /** Collect unmapped entries for explicit import instead of refusing on them. */
42
+ readonly importMissing?: boolean;
43
+ }
44
+ export interface SourceMembership {
45
+ readonly names: string[];
46
+ readonly findings: Diagnostic[];
47
+ readonly imports: PendingImport[];
48
+ }
49
+ /** Options shared by source-backed set/pack creation. */
50
+ export interface SourceCreationOptions extends CompositionOptions {
51
+ readonly fromRoot?: string;
52
+ readonly from?: readonly string[];
53
+ readonly import?: boolean;
54
+ }
55
+ /** The membership slice of {@link PlannedSources} that composition planning consumes. */
56
+ export interface SourceMembershipPlan {
57
+ readonly members: readonly string[];
58
+ readonly pending: ReadonlyMap<string, string>;
59
+ readonly provenance: Record<string, unknown> | undefined;
60
+ }
61
+ /**
62
+ * Remove URL credentials anywhere they appear — labels, provenance, findings,
63
+ * and Git transport errors all pass through here — so a token or password
64
+ * embedded for transport is never echoed back.
65
+ */
66
+ export declare function sanitizeSourceLabel(source: string): string;
67
+ export declare function releaseInventory(inventory: SourceInventory): Promise<void>;
68
+ export declare function inventorySkillRoot(registry: string, path: string, options?: SourceOptions): Promise<SourceInventory>;
69
+ /**
70
+ * Inventory one explicitly requested source: an existing local path is read in
71
+ * place; a Git remote is acquired (clone --depth 1) because it was explicitly
72
+ * requested, with its commit pinned into provenance. Nothing is executed from
73
+ * the acquired tree and nothing is imported implicitly.
74
+ */
75
+ export declare function inventorySource(registry: string, source: string, options?: SourceOptions, pinned?: SourceProvenance): Promise<SourceInventory>;
76
+ /**
77
+ * Merge inventories into canonical member names. Mapped entries become
78
+ * members; divergent and broken entries are errors; foreign entries are
79
+ * preserved and reported. Unmapped entries are errors unless importMissing
80
+ * collected them for explicit import — a requested entry is never skipped
81
+ * silently.
82
+ */
83
+ export declare function membersFromInventories(registry: string, inventories: readonly SourceInventory[], options?: MembershipOptions): Promise<SourceMembership>;
84
+ /**
85
+ * Acquire every declared source. When a later source fails, every inventory
86
+ * acquired so far — including its ephemeral clone — is released before the
87
+ * error propagates, so a failed acquisition never strands a temp tree.
88
+ */
89
+ export declare function acquireInventories(registryRoot: string, options: SourceCreationOptions): Promise<SourceInventory[]>;
90
+ /** Sources fully planned: membership merged, every import validated write-free. */
91
+ export interface PlannedSources {
92
+ readonly inventories: readonly SourceInventory[];
93
+ readonly names: readonly string[];
94
+ /** Canonical destinations the planned imports will occupy (dry-run results). */
95
+ readonly pending: ReadonlyMap<string, string>;
96
+ readonly imports: readonly PendingImport[];
97
+ readonly findings: readonly Diagnostic[];
98
+ }
99
+ /**
100
+ * Acquire all sources and plan membership without a single write: every
101
+ * would-be import is validated through the standing `skill import` machinery
102
+ * in dry-run first, so an invalid name or unreadable source refuses before
103
+ * any catalog byte moves. Import failures surface as error findings.
104
+ */
105
+ export declare function planSourceMembers(registryRoot: string, options: SourceCreationOptions): Promise<PlannedSources>;
106
+ /** An import that actually landed in the catalog. */
107
+ export interface ExecutedImport {
108
+ readonly name: string;
109
+ readonly path: string;
110
+ }
111
+ /** Result of executing planned imports for real. */
112
+ export interface ImportExecution {
113
+ readonly executed: readonly ExecutedImport[];
114
+ readonly findings: readonly Diagnostic[];
115
+ }
116
+ /**
117
+ * Execute planned imports for real, reusing the standing `skill import`
118
+ * machinery. A failing import never invents a rollback or deletes the
119
+ * definitions earlier imports already wrote — they are standalone
120
+ * receipt-bearing units — but their survival is disclosed truthfully so the
121
+ * refusal is never a silent partial state.
122
+ */
123
+ export declare function executeImports(imports: readonly PendingImport[], options: SourceCreationOptions): Promise<ImportExecution>;
124
+ export declare function provenanceFrom(inventories: readonly SourceInventory[], imported?: readonly string[]): Promise<Record<string, unknown> | undefined>;
125
+ /**
126
+ * Validate member names with the shared manifest authority and resolve each
127
+ * to its canonical target. `pending` carries dry-run import destinations for
128
+ * names whose canonical does not exist yet; every other name must resolve for
129
+ * real or the operation refuses.
130
+ */
131
+ export declare function resolveMemberTargets(registry: string, names: readonly string[], label: string, pending?: ReadonlyMap<string, string>): Promise<Map<string, string>>;
@@ -0,0 +1,15 @@
1
+ import { type ResultEnvelope } from "./result.js";
2
+ import type { SelectionOptions, SelectionResult } from "./selection-command-types.js";
3
+ export interface NormalizeOptions extends SelectionOptions {
4
+ /** Apply the planned repair. Without it, normalize is a write-free preview. */
5
+ readonly apply?: boolean;
6
+ /** Explicit base for a legacy multi-set selection; never guessed from array order. */
7
+ readonly baseSet?: string;
8
+ }
9
+ /**
10
+ * Normalize one scope's selection declaration to the corrected set/pack
11
+ * contract: inventory legacy or conflicted state, fold it into deterministic
12
+ * exact-membership references, and preview (default) or apply the repair
13
+ * through the shared selection transaction.
14
+ */
15
+ export declare function normalizeScope(options?: NormalizeOptions): Promise<ResultEnvelope<SelectionResult | null>>;
@@ -1,8 +1,16 @@
1
1
  import type { CompositionMutationData, CompositionOptions, PackListData, PackShowData } from "./composition-types.js";
2
2
  import { type ResultEnvelope } from "./result.js";
3
+ export interface CreatePackOptions extends CompositionOptions {
4
+ /** Existing local skill root whose entries become member references. */
5
+ readonly fromRoot?: string;
6
+ /** Repeatable explicit sources: existing paths or Git remotes. */
7
+ readonly from?: readonly string[];
8
+ /** Import source skills that have no canonical definition instead of refusing. */
9
+ readonly import?: boolean;
10
+ }
3
11
  export declare function listPacks(options?: CompositionOptions): Promise<ResultEnvelope<PackListData | null>>;
4
12
  export declare function showPack(ref: string, options?: CompositionOptions): Promise<ResultEnvelope<PackShowData | null>>;
5
13
  export declare function verifyPack(ref: string, options?: CompositionOptions): Promise<ResultEnvelope<PackShowData | null>>;
6
- export declare function createPack(name: string, version: string, options?: CompositionOptions): Promise<ResultEnvelope<CompositionMutationData | null>>;
14
+ export declare function createPack(name: string, version: string, options?: CreatePackOptions): Promise<ResultEnvelope<CompositionMutationData | null>>;
7
15
  export declare function addPackSkills(ref: string, names: readonly string[], options?: CompositionOptions): Promise<ResultEnvelope<CompositionMutationData | null>>;
8
16
  export declare function removePackSkills(ref: string, names: readonly string[], options?: CompositionOptions): Promise<ResultEnvelope<CompositionMutationData | null>>;
@@ -1,4 +1,6 @@
1
1
  import type { ProfileLocalEntry, ProfileLocation, ProfileOptions } from "./profile-types.js";
2
2
  export declare function strictProfile(profile: ProfileLocation, options: ProfileOptions): Promise<boolean>;
3
+ /** Persist a profile's selection boundary independently of the caller's HOME. */
4
+ export declare function profileInheritsGlobal(profile: ProfileLocation): Promise<boolean>;
3
5
  export declare function assertStrictProfile(profile: ProfileLocation, options: ProfileOptions, local: readonly ProfileLocalEntry[]): Promise<boolean>;
4
6
  export declare function publishStrictPolicy(profile: ProfileLocation): Promise<void>;