@shrkcrft/plugin-api 0.1.0-alpha.2

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -0
  3. package/dist/ai-provider-plugin.d.ts +9 -0
  4. package/dist/ai-provider-plugin.d.ts.map +1 -0
  5. package/dist/ai-provider-plugin.js +1 -0
  6. package/dist/command-plugin.d.ts +11 -0
  7. package/dist/command-plugin.d.ts.map +1 -0
  8. package/dist/command-plugin.js +1 -0
  9. package/dist/construct.d.ts +57 -0
  10. package/dist/construct.d.ts.map +1 -0
  11. package/dist/construct.js +18 -0
  12. package/dist/convention.d.ts +77 -0
  13. package/dist/convention.d.ts.map +1 -0
  14. package/dist/convention.js +50 -0
  15. package/dist/generator-plugin.d.ts +6 -0
  16. package/dist/generator-plugin.d.ts.map +1 -0
  17. package/dist/generator-plugin.js +1 -0
  18. package/dist/index.d.ts +20 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +19 -0
  21. package/dist/knowledge-plugin.d.ts +15 -0
  22. package/dist/knowledge-plugin.d.ts.map +1 -0
  23. package/dist/knowledge-plugin.js +1 -0
  24. package/dist/mcp-tool-plugin.d.ts +9 -0
  25. package/dist/mcp-tool-plugin.d.ts.map +1 -0
  26. package/dist/mcp-tool-plugin.js +1 -0
  27. package/dist/pack-helper.d.ts +63 -0
  28. package/dist/pack-helper.d.ts.map +1 -0
  29. package/dist/pack-helper.js +40 -0
  30. package/dist/pack-manifest.d.ts +138 -0
  31. package/dist/pack-manifest.d.ts.map +1 -0
  32. package/dist/pack-manifest.js +96 -0
  33. package/dist/pack-signing.d.ts +50 -0
  34. package/dist/pack-signing.d.ts.map +1 -0
  35. package/dist/pack-signing.js +114 -0
  36. package/dist/playbook.d.ts +43 -0
  37. package/dist/playbook.d.ts.map +1 -0
  38. package/dist/playbook.js +13 -0
  39. package/dist/plugin-lifecycle-profile.d.ts +98 -0
  40. package/dist/plugin-lifecycle-profile.d.ts.map +1 -0
  41. package/dist/plugin-lifecycle-profile.js +119 -0
  42. package/dist/policy-check.d.ts +28 -0
  43. package/dist/policy-check.d.ts.map +1 -0
  44. package/dist/policy-check.js +3 -0
  45. package/dist/registration-hint.d.ts +96 -0
  46. package/dist/registration-hint.d.ts.map +1 -0
  47. package/dist/registration-hint.js +47 -0
  48. package/dist/scaffold-pattern.d.ts +56 -0
  49. package/dist/scaffold-pattern.d.ts.map +1 -0
  50. package/dist/scaffold-pattern.js +32 -0
  51. package/dist/search-tuning.d.ts +33 -0
  52. package/dist/search-tuning.d.ts.map +1 -0
  53. package/dist/search-tuning.js +3 -0
  54. package/dist/sharkcraft-plugin.d.ts +13 -0
  55. package/dist/sharkcraft-plugin.d.ts.map +1 -0
  56. package/dist/sharkcraft-plugin.js +1 -0
  57. package/dist/task-routing-hint.d.ts +49 -0
  58. package/dist/task-routing-hint.d.ts.map +1 -0
  59. package/dist/task-routing-hint.js +29 -0
  60. package/dist/template-plugin.d.ts +10 -0
  61. package/dist/template-plugin.d.ts.map +1 -0
  62. package/dist/template-plugin.js +1 -0
  63. package/package.json +49 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-manifest.d.ts","sourceRoot":"","sources":["../src/pack-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * SharkCraft pack manifest.
3
+ *
4
+ * A "pack" is a third-party npm package that ships SharkCraft assets —
5
+ * knowledge entries, rules, paths, templates, pipelines, MCP-tool registrations,
6
+ * AI-provider adapters, etc.
7
+ *
8
+ * The pack itself is just an npm package whose `package.json` declares a
9
+ * `sharkcraft.manifest` entry pointing at a TS/JS file that default-exports an
10
+ * `ISharkCraftPackManifest`. The discovery scanner (planned for v0.2) finds
11
+ * these manifests in `node_modules/` and registers their contributions.
12
+ *
13
+ * Today this file declares the types and a small validator. The discovery
14
+ * runner is intentionally out of scope for v0.1 — see docs/packs.md.
15
+ */
16
+ /**
17
+ * Lightweight runtime validation of a pack manifest. We do not use zod here
18
+ * because plugin-api should remain dependency-light; consumers can layer zod
19
+ * on top if they want.
20
+ */
21
+ export function validatePackManifest(value) {
22
+ const issues = [];
23
+ if (!value || typeof value !== 'object') {
24
+ return { valid: false, issues: [{ field: '<root>', message: 'manifest must be an object' }] };
25
+ }
26
+ const obj = value;
27
+ if (obj.schema !== 'sharkcraft.pack/v1') {
28
+ issues.push({ field: 'schema', message: 'schema must be "sharkcraft.pack/v1"' });
29
+ }
30
+ const info = obj.info;
31
+ if (!info || typeof info !== 'object') {
32
+ issues.push({ field: 'info', message: 'info is required' });
33
+ }
34
+ else {
35
+ if (typeof info.name !== 'string' || info.name.length === 0) {
36
+ issues.push({ field: 'info.name', message: 'info.name must be a non-empty string' });
37
+ }
38
+ if (typeof info.version !== 'string' || info.version.length === 0) {
39
+ issues.push({ field: 'info.version', message: 'info.version must be a non-empty string' });
40
+ }
41
+ }
42
+ const contributions = obj.contributions;
43
+ if (!contributions || typeof contributions !== 'object') {
44
+ issues.push({ field: 'contributions', message: 'contributions is required' });
45
+ }
46
+ else {
47
+ for (const key of [
48
+ 'knowledgeFiles',
49
+ 'ruleFiles',
50
+ 'pathFiles',
51
+ 'templateFiles',
52
+ 'pipelineFiles',
53
+ 'docsFiles',
54
+ 'presetFiles',
55
+ 'boundaryFiles',
56
+ 'contextTestFiles',
57
+ 'agentTestFiles',
58
+ 'mcpToolFiles',
59
+ 'aiProviderFiles',
60
+ 'scaffoldPatternFiles',
61
+ 'policyCheckFiles',
62
+ 'constructFiles',
63
+ 'constructFacetFiles',
64
+ 'playbookFiles',
65
+ 'searchTuningFiles',
66
+ 'feedbackRuleFiles',
67
+ 'decisionFiles',
68
+ 'pathConventionFiles',
69
+ 'pluginLifecycleProfileFiles',
70
+ 'contractTemplateFiles',
71
+ 'migrationProfileFiles',
72
+ 'conventionFiles',
73
+ 'helperFiles',
74
+ 'taskRoutingHintFiles',
75
+ 'registrationHintFiles',
76
+ ]) {
77
+ const v = contributions[key];
78
+ if (v === undefined)
79
+ continue;
80
+ if (!Array.isArray(v) ||
81
+ v.some((entry) => typeof entry !== 'string' || entry.length === 0)) {
82
+ issues.push({
83
+ field: `contributions.${key}`,
84
+ message: 'must be an array of non-empty strings',
85
+ });
86
+ }
87
+ }
88
+ }
89
+ return { valid: issues.length === 0, issues };
90
+ }
91
+ /**
92
+ * Convenience for pack authors to write a manifest with type help.
93
+ */
94
+ export function definePackManifest(input) {
95
+ return input;
96
+ }
@@ -0,0 +1,50 @@
1
+ import type { ISharkCraftPackManifest, ISharkCraftPackSignature } from './pack-manifest.js';
2
+ export declare const PACK_SECRET_ENV = "SHARKCRAFT_PACK_SECRET";
3
+ export declare const PACK_SIGNATURE_ALGO = "sha256";
4
+ /**
5
+ * Well-known dev secret. Any developer can produce a dev signature
6
+ * mid-session without holding the release secret. The dev secret only
7
+ * proves "someone signed this with the dev tooling"; release paths reject
8
+ * dev signatures unless `--allow-dev-signature` is set.
9
+ */
10
+ export declare const PACK_DEV_SECRET = "sharkcraft-dev-signature-not-for-release";
11
+ /**
12
+ * Canonical JSON for the signed portion of a pack manifest. Excludes the
13
+ * signature field itself so the signature can be inserted afterwards without
14
+ * disturbing the digest.
15
+ */
16
+ export declare function canonicalizePackManifest(manifest: ISharkCraftPackManifest): string;
17
+ export interface SignPackManifestOptions {
18
+ secret?: string;
19
+ keyId?: string;
20
+ /**
21
+ * When true, use the well-known dev secret and mark the signature
22
+ * `dev: true`. Lets agents sign mid-session without the release secret;
23
+ * release apply paths reject dev signatures unless explicitly allowed.
24
+ */
25
+ dev?: boolean;
26
+ }
27
+ export type SignPackResult = {
28
+ ok: true;
29
+ manifest: ISharkCraftPackManifest;
30
+ signature: ISharkCraftPackSignature;
31
+ } | {
32
+ ok: false;
33
+ status: 'missing-secret';
34
+ message: string;
35
+ };
36
+ export declare function signPackManifest(manifest: ISharkCraftPackManifest, options?: SignPackManifestOptions): SignPackResult;
37
+ export type VerifyPackResult = {
38
+ ok: true;
39
+ status: 'verified';
40
+ dev: boolean;
41
+ } | {
42
+ ok: false;
43
+ status: 'missing-signature' | 'missing-secret' | 'invalid-signature';
44
+ message: string;
45
+ };
46
+ export interface VerifyPackManifestOptions {
47
+ secret?: string;
48
+ }
49
+ export declare function verifyPackManifest(manifest: ISharkCraftPackManifest, options?: VerifyPackManifestOptions): VerifyPackResult;
50
+ //# sourceMappingURL=pack-signing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-signing.d.ts","sourceRoot":"","sources":["../src/pack-signing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE5F,eAAO,MAAM,eAAe,2BAA2B,CAAC;AACxD,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAC5C;;;;;GAKG;AACH,eAAO,MAAM,eAAe,6CAA6C,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,MAAM,CAGlF;AAwBD,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,uBAAuB,CAAC;IAAC,SAAS,EAAE,wBAAwB,CAAA;CAAE,GACpF;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,uBAAuB,EACjC,OAAO,GAAE,uBAA4B,GACpC,cAAc,CA2BhB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAC9C;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,mBAAmB,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;IACrE,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,uBAAuB,EACjC,OAAO,GAAE,yBAA8B,GACtC,gBAAgB,CAuClB"}
@@ -0,0 +1,114 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ export const PACK_SECRET_ENV = 'SHARKCRAFT_PACK_SECRET';
3
+ export const PACK_SIGNATURE_ALGO = 'sha256';
4
+ /**
5
+ * Well-known dev secret. Any developer can produce a dev signature
6
+ * mid-session without holding the release secret. The dev secret only
7
+ * proves "someone signed this with the dev tooling"; release paths reject
8
+ * dev signatures unless `--allow-dev-signature` is set.
9
+ */
10
+ export const PACK_DEV_SECRET = 'sharkcraft-dev-signature-not-for-release';
11
+ /**
12
+ * Canonical JSON for the signed portion of a pack manifest. Excludes the
13
+ * signature field itself so the signature can be inserted afterwards without
14
+ * disturbing the digest.
15
+ */
16
+ export function canonicalizePackManifest(manifest) {
17
+ const { signature: _signature, ...rest } = manifest;
18
+ return canonicalJson(rest);
19
+ }
20
+ function canonicalJson(value) {
21
+ if (value === null || typeof value !== 'object')
22
+ return JSON.stringify(value);
23
+ if (Array.isArray(value)) {
24
+ return '[' + value.map((v) => canonicalJson(v)).join(',') + ']';
25
+ }
26
+ const keys = Object.keys(value).sort();
27
+ const parts = [];
28
+ for (const k of keys) {
29
+ const v = value[k];
30
+ if (v === undefined)
31
+ continue;
32
+ parts.push(JSON.stringify(k) + ':' + canonicalJson(v));
33
+ }
34
+ return '{' + parts.join(',') + '}';
35
+ }
36
+ function readSecret(secret) {
37
+ if (secret !== undefined && secret.length > 0)
38
+ return secret;
39
+ const fromEnv = process.env[PACK_SECRET_ENV];
40
+ if (fromEnv && fromEnv.length > 0)
41
+ return fromEnv;
42
+ return null;
43
+ }
44
+ export function signPackManifest(manifest, options = {}) {
45
+ // Dev mode: use the well-known dev secret. Real secret (env / flag)
46
+ // is ignored in dev mode so the signature stays portable and verifiable
47
+ // by any verifier that opts into dev verification.
48
+ const useDev = options.dev === true;
49
+ const secret = useDev ? PACK_DEV_SECRET : readSecret(options.secret);
50
+ if (!secret) {
51
+ return {
52
+ ok: false,
53
+ status: 'missing-secret',
54
+ message: `Cannot sign pack manifest: set ${PACK_SECRET_ENV} or pass --secret (or use --dev for a non-release dev signature).`,
55
+ };
56
+ }
57
+ const canon = canonicalizePackManifest(manifest);
58
+ const hmac = createHmac(PACK_SIGNATURE_ALGO, secret).update(canon).digest('hex');
59
+ const signature = {
60
+ algo: PACK_SIGNATURE_ALGO,
61
+ hmac,
62
+ signedAt: new Date().toISOString(),
63
+ };
64
+ if (options.keyId !== undefined)
65
+ signature.keyId = options.keyId;
66
+ if (useDev)
67
+ signature.dev = true;
68
+ return {
69
+ ok: true,
70
+ manifest: { ...manifest, signature },
71
+ signature,
72
+ };
73
+ }
74
+ export function verifyPackManifest(manifest, options = {}) {
75
+ const sig = manifest.signature;
76
+ if (!sig) {
77
+ return { ok: false, status: 'missing-signature', message: 'Manifest has no signature.' };
78
+ }
79
+ if (sig.algo !== PACK_SIGNATURE_ALGO) {
80
+ return {
81
+ ok: false,
82
+ status: 'invalid-signature',
83
+ message: `Unsupported signature algorithm: ${sig.algo}`,
84
+ };
85
+ }
86
+ // Dev signatures verify against the well-known dev secret. Callers
87
+ // see `dev: true` in the result and can choose to reject (release path) or
88
+ // accept (local-only flows).
89
+ const isDev = sig.dev === true;
90
+ const secret = isDev ? PACK_DEV_SECRET : readSecret(options.secret);
91
+ if (!secret) {
92
+ return {
93
+ ok: false,
94
+ status: 'missing-secret',
95
+ message: `Cannot verify pack manifest: set ${PACK_SECRET_ENV} or pass --secret.`,
96
+ };
97
+ }
98
+ const canon = canonicalizePackManifest(manifest);
99
+ const expected = createHmac(PACK_SIGNATURE_ALGO, secret).update(canon).digest();
100
+ let given;
101
+ try {
102
+ given = Buffer.from(sig.hmac, 'hex');
103
+ }
104
+ catch {
105
+ return { ok: false, status: 'invalid-signature', message: 'Signature is not valid hex.' };
106
+ }
107
+ if (given.length !== expected.length) {
108
+ return { ok: false, status: 'invalid-signature', message: 'Signature length mismatch.' };
109
+ }
110
+ if (!timingSafeEqual(given, expected)) {
111
+ return { ok: false, status: 'invalid-signature', message: 'Signature does not match.' };
112
+ }
113
+ return { ok: true, status: 'verified', dev: isDev };
114
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Playbooks: named, reusable human/agent recipes. A playbook bundles a
3
+ * preset, a pipeline, recommended templates, and a step-by-step runbook
4
+ * with optional verification commands and safety notes. They're the
5
+ * generic equivalent of older project-specific recipes without baking
6
+ * those into the SharkCraft engine.
7
+ *
8
+ * Playbooks are NEVER auto-executed; they are structured runbooks that the
9
+ * agent or human reads and follows.
10
+ */
11
+ export interface IPlaybookStep {
12
+ id: string;
13
+ title: string;
14
+ description?: string;
15
+ /** Shell commands to run (read-only / non-destructive recommended). */
16
+ commands?: readonly string[];
17
+ /** MCP tools to call to discover context. */
18
+ mcpTools?: readonly string[];
19
+ /** When true, this step requires explicit human review before continuing. */
20
+ humanReview?: boolean;
21
+ /** Commands the human should run to validate the step's effect. */
22
+ verificationCommands?: readonly string[];
23
+ /** Free-form safety notes. */
24
+ safetyNotes?: readonly string[];
25
+ }
26
+ export interface IPlaybookInput {
27
+ id: string;
28
+ title: string;
29
+ description?: string;
30
+ tags?: readonly string[];
31
+ /** Task kinds this playbook is suitable for (e.g. 'generate', 'review'). */
32
+ taskKinds?: readonly string[];
33
+ recommendedPresetIds?: readonly string[];
34
+ recommendedPipelineIds?: readonly string[];
35
+ recommendedTemplateIds?: readonly string[];
36
+ steps: readonly IPlaybookStep[];
37
+ /** Expected outputs after the playbook completes. */
38
+ outputs?: readonly string[];
39
+ /** Example tasks the playbook addresses. */
40
+ examples?: readonly string[];
41
+ }
42
+ export declare function definePlaybook(input: IPlaybookInput): IPlaybookInput;
43
+ //# sourceMappingURL=playbook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playbook.d.ts","sourceRoot":"","sources":["../src/playbook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,8BAA8B;IAC9B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,qDAAqD;IACrD,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,CAEpE"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Playbooks: named, reusable human/agent recipes. A playbook bundles a
3
+ * preset, a pipeline, recommended templates, and a step-by-step runbook
4
+ * with optional verification commands and safety notes. They're the
5
+ * generic equivalent of older project-specific recipes without baking
6
+ * those into the SharkCraft engine.
7
+ *
8
+ * Playbooks are NEVER auto-executed; they are structured runbooks that the
9
+ * agent or human reads and follows.
10
+ */
11
+ export function definePlaybook(input) {
12
+ return input;
13
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Plugin lifecycle profile (generic).
3
+ *
4
+ * A pack can contribute one or more lifecycle profiles describing where its
5
+ * plugins live, what their barrels and key-tables look like, and which
6
+ * registry files participate. The engine reads these profiles and plans
7
+ * plugin rename / remove operations against them.
8
+ *
9
+ * The engine never embeds project-specific plugin layouts; all of that comes
10
+ * from a profile. Pack contributions are static data — no executable code.
11
+ */
12
+ export declare enum PluginLifecycleRootKind {
13
+ Api = "api",
14
+ Cross = "cross",
15
+ Ui = "ui",
16
+ Angular = "angular",
17
+ React = "react",
18
+ Node = "node",
19
+ Runtime = "runtime",
20
+ Other = "other"
21
+ }
22
+ export interface IPluginLifecycleRoot {
23
+ readonly id: string;
24
+ readonly path: string;
25
+ readonly kind?: PluginLifecycleRootKind;
26
+ readonly pluginFolderSegment?: string;
27
+ }
28
+ export declare enum BarrelSort {
29
+ Alphabetical = "alphabetical",
30
+ Preserve = "preserve",
31
+ Append = "append"
32
+ }
33
+ export interface IPluginLifecycleBarrel {
34
+ readonly id: string;
35
+ readonly path: string;
36
+ readonly exportSegment?: string;
37
+ readonly sort?: BarrelSort;
38
+ }
39
+ export declare enum CaseStyle {
40
+ UpperSnake = "upperSnake",
41
+ Pascal = "pascal",
42
+ Camel = "camel",
43
+ Kebab = "kebab"
44
+ }
45
+ export interface IPluginLifecycleKeyTable {
46
+ readonly path: string;
47
+ readonly keyCase: CaseStyle;
48
+ readonly valueCase: CaseStyle;
49
+ readonly entryAnchor?: string;
50
+ readonly id?: string;
51
+ }
52
+ export declare enum PluginRegistryFileKind {
53
+ PluginKey = "plugin-key",
54
+ UserPluginEntry = "user-plugin-entry",
55
+ Defaults = "defaults",
56
+ Event = "event",
57
+ Command = "command",
58
+ Composer = "composer",
59
+ Other = "other"
60
+ }
61
+ export interface IPluginLifecycleRegistryFile {
62
+ readonly id: string;
63
+ readonly path: string;
64
+ readonly kind: PluginRegistryFileKind;
65
+ readonly entryPattern?: string;
66
+ }
67
+ export interface IPluginLifecycleNaming {
68
+ readonly pluginIdCase?: CaseStyle;
69
+ readonly classNameSuffix?: string;
70
+ }
71
+ export interface IPluginLifecycleProfile {
72
+ readonly id: string;
73
+ readonly title: string;
74
+ readonly description?: string;
75
+ readonly pluginRoots: readonly IPluginLifecycleRoot[];
76
+ readonly barrels?: readonly IPluginLifecycleBarrel[];
77
+ readonly keyTable?: IPluginLifecycleKeyTable;
78
+ readonly registryFiles?: readonly IPluginLifecycleRegistryFile[];
79
+ readonly naming?: IPluginLifecycleNaming;
80
+ readonly validationCommands?: readonly string[];
81
+ readonly safetyNotes?: readonly string[];
82
+ readonly appliesWhen?: readonly string[];
83
+ readonly tags?: readonly string[];
84
+ }
85
+ export interface IPluginLifecycleProfileValidationIssue {
86
+ readonly field: string;
87
+ readonly message: string;
88
+ }
89
+ export interface IPluginLifecycleProfileValidationResult {
90
+ readonly valid: boolean;
91
+ readonly issues: readonly IPluginLifecycleProfileValidationIssue[];
92
+ }
93
+ /**
94
+ * Validate a plugin lifecycle profile shape. Lightweight runtime check; no
95
+ * dependency on zod (plugin-api stays dependency-light, like pack-manifest).
96
+ */
97
+ export declare function validatePluginLifecycleProfile(value: unknown): IPluginLifecycleProfileValidationResult;
98
+ //# sourceMappingURL=plugin-lifecycle-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-lifecycle-profile.d.ts","sourceRoot":"","sources":["../src/plugin-lifecycle-profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Plugin lifecycle profile (generic).
3
+ *
4
+ * A pack can contribute one or more lifecycle profiles describing where its
5
+ * plugins live, what their barrels and key-tables look like, and which
6
+ * registry files participate. The engine reads these profiles and plans
7
+ * plugin rename / remove operations against them.
8
+ *
9
+ * The engine never embeds project-specific plugin layouts; all of that comes
10
+ * from a profile. Pack contributions are static data — no executable code.
11
+ */
12
+ export var PluginLifecycleRootKind;
13
+ (function (PluginLifecycleRootKind) {
14
+ PluginLifecycleRootKind["Api"] = "api";
15
+ PluginLifecycleRootKind["Cross"] = "cross";
16
+ PluginLifecycleRootKind["Ui"] = "ui";
17
+ PluginLifecycleRootKind["Angular"] = "angular";
18
+ PluginLifecycleRootKind["React"] = "react";
19
+ PluginLifecycleRootKind["Node"] = "node";
20
+ PluginLifecycleRootKind["Runtime"] = "runtime";
21
+ PluginLifecycleRootKind["Other"] = "other";
22
+ })(PluginLifecycleRootKind || (PluginLifecycleRootKind = {}));
23
+ export var BarrelSort;
24
+ (function (BarrelSort) {
25
+ BarrelSort["Alphabetical"] = "alphabetical";
26
+ BarrelSort["Preserve"] = "preserve";
27
+ BarrelSort["Append"] = "append";
28
+ })(BarrelSort || (BarrelSort = {}));
29
+ export var CaseStyle;
30
+ (function (CaseStyle) {
31
+ CaseStyle["UpperSnake"] = "upperSnake";
32
+ CaseStyle["Pascal"] = "pascal";
33
+ CaseStyle["Camel"] = "camel";
34
+ CaseStyle["Kebab"] = "kebab";
35
+ })(CaseStyle || (CaseStyle = {}));
36
+ export var PluginRegistryFileKind;
37
+ (function (PluginRegistryFileKind) {
38
+ PluginRegistryFileKind["PluginKey"] = "plugin-key";
39
+ PluginRegistryFileKind["UserPluginEntry"] = "user-plugin-entry";
40
+ PluginRegistryFileKind["Defaults"] = "defaults";
41
+ PluginRegistryFileKind["Event"] = "event";
42
+ PluginRegistryFileKind["Command"] = "command";
43
+ PluginRegistryFileKind["Composer"] = "composer";
44
+ PluginRegistryFileKind["Other"] = "other";
45
+ })(PluginRegistryFileKind || (PluginRegistryFileKind = {}));
46
+ /**
47
+ * Validate a plugin lifecycle profile shape. Lightweight runtime check; no
48
+ * dependency on zod (plugin-api stays dependency-light, like pack-manifest).
49
+ */
50
+ export function validatePluginLifecycleProfile(value) {
51
+ const issues = [];
52
+ if (!value || typeof value !== 'object') {
53
+ return { valid: false, issues: [{ field: '<root>', message: 'profile must be an object' }] };
54
+ }
55
+ const obj = value;
56
+ if (typeof obj.id !== 'string' || obj.id.length === 0) {
57
+ issues.push({ field: 'id', message: 'id must be a non-empty string' });
58
+ }
59
+ if (typeof obj.title !== 'string' || obj.title.length === 0) {
60
+ issues.push({ field: 'title', message: 'title must be a non-empty string' });
61
+ }
62
+ if (!Array.isArray(obj.pluginRoots) || obj.pluginRoots.length === 0) {
63
+ issues.push({ field: 'pluginRoots', message: 'pluginRoots must be a non-empty array' });
64
+ }
65
+ else {
66
+ obj.pluginRoots.forEach((root, idx) => {
67
+ if (!root || typeof root !== 'object') {
68
+ issues.push({ field: `pluginRoots[${idx}]`, message: 'root must be an object' });
69
+ return;
70
+ }
71
+ const r = root;
72
+ if (typeof r.id !== 'string' || r.id.length === 0) {
73
+ issues.push({ field: `pluginRoots[${idx}].id`, message: 'id required' });
74
+ }
75
+ if (typeof r.path !== 'string' || r.path.length === 0) {
76
+ issues.push({ field: `pluginRoots[${idx}].path`, message: 'path required' });
77
+ }
78
+ });
79
+ }
80
+ if (obj.barrels !== undefined) {
81
+ if (!Array.isArray(obj.barrels)) {
82
+ issues.push({ field: 'barrels', message: 'barrels must be an array' });
83
+ }
84
+ else {
85
+ obj.barrels.forEach((b, idx) => {
86
+ if (!b || typeof b !== 'object') {
87
+ issues.push({ field: `barrels[${idx}]`, message: 'barrel must be an object' });
88
+ return;
89
+ }
90
+ const br = b;
91
+ if (typeof br.id !== 'string' || br.id.length === 0) {
92
+ issues.push({ field: `barrels[${idx}].id`, message: 'id required' });
93
+ }
94
+ if (typeof br.path !== 'string' || br.path.length === 0) {
95
+ issues.push({ field: `barrels[${idx}].path`, message: 'path required' });
96
+ }
97
+ });
98
+ }
99
+ }
100
+ if (obj.keyTable !== undefined && obj.keyTable !== null) {
101
+ const k = obj.keyTable;
102
+ if (typeof k !== 'object') {
103
+ issues.push({ field: 'keyTable', message: 'keyTable must be an object' });
104
+ }
105
+ else {
106
+ if (typeof k.path !== 'string' || k.path.length === 0) {
107
+ issues.push({ field: 'keyTable.path', message: 'path required' });
108
+ }
109
+ const validCase = new Set(['upperSnake', 'pascal', 'camel', 'kebab']);
110
+ if (typeof k.keyCase !== 'string' || !validCase.has(k.keyCase)) {
111
+ issues.push({ field: 'keyTable.keyCase', message: 'keyCase must be one of upperSnake|pascal|camel|kebab' });
112
+ }
113
+ if (typeof k.valueCase !== 'string' || !validCase.has(k.valueCase)) {
114
+ issues.push({ field: 'keyTable.valueCase', message: 'valueCase must be one of upperSnake|pascal|camel|kebab' });
115
+ }
116
+ }
117
+ }
118
+ return { valid: issues.length === 0, issues };
119
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Pack-contributed policy check declaration. Packs that ship
3
+ * `policyCheckFiles` default-export an array of these definitions.
4
+ *
5
+ * SharkCraft's policy engine executes the predicate against the current
6
+ * inspection plus plan/bundle targets. A predicate must be a pure function
7
+ * (no shell, no network).
8
+ */
9
+ export type PolicySeverityLabel = 'info' | 'warning' | 'error' | 'critical';
10
+ export type PolicyCheckTypeLabel = 'path' | 'import' | 'ownership' | 'command' | 'template' | 'plan' | 'bundle' | 'session';
11
+ export interface IPackPolicyCheckEvaluation {
12
+ message: string;
13
+ suggestedFix?: string;
14
+ context?: Record<string, unknown>;
15
+ }
16
+ export interface IPackPolicyCheck {
17
+ id: string;
18
+ title: string;
19
+ severity?: PolicySeverityLabel;
20
+ checkType?: PolicyCheckTypeLabel;
21
+ evaluate: (input: {
22
+ projectRoot: string;
23
+ planTargets: readonly string[];
24
+ bundleAffectedFiles: readonly string[];
25
+ }) => boolean | IPackPolicyCheckEvaluation;
26
+ }
27
+ export declare function definePackPolicyCheck(check: IPackPolicyCheck): IPackPolicyCheck;
28
+ //# sourceMappingURL=policy-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-check.d.ts","sourceRoot":"","sources":["../src/policy-check.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAE5E,MAAM,MAAM,oBAAoB,GAC5B,MAAM,GACN,QAAQ,GACR,WAAW,GACX,SAAS,GACT,UAAU,GACV,MAAM,GACN,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;QAC/B,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;KACxC,KAAK,OAAO,GAAG,0BAA0B,CAAC;CAC5C;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,CAE/E"}
@@ -0,0 +1,3 @@
1
+ export function definePackPolicyCheck(check) {
2
+ return check;
3
+ }