@synoikia/create-plugin 0.1.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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/dist/build.d.ts +16 -0
  4. package/dist/build.js +32 -0
  5. package/dist/build.js.map +1 -0
  6. package/dist/check.d.ts +7 -0
  7. package/dist/check.js +49 -0
  8. package/dist/check.js.map +1 -0
  9. package/dist/cli.d.ts +2 -0
  10. package/dist/cli.js +104 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/create.d.ts +2 -0
  13. package/dist/create.js +56 -0
  14. package/dist/create.js.map +1 -0
  15. package/dist/files.d.ts +12 -0
  16. package/dist/files.js +42 -0
  17. package/dist/files.js.map +1 -0
  18. package/dist/index.d.ts +10 -0
  19. package/dist/index.js +8 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/prompts.d.ts +46 -0
  22. package/dist/prompts.js +112 -0
  23. package/dist/prompts.js.map +1 -0
  24. package/dist/repo-root.d.ts +10 -0
  25. package/dist/repo-root.js +47 -0
  26. package/dist/repo-root.js.map +1 -0
  27. package/dist/repo.d.ts +68 -0
  28. package/dist/repo.js +222 -0
  29. package/dist/repo.js.map +1 -0
  30. package/dist/scaffold.d.ts +68 -0
  31. package/dist/scaffold.js +296 -0
  32. package/dist/scaffold.js.map +1 -0
  33. package/dist/vitest.d.ts +12 -0
  34. package/dist/vitest.js +17 -0
  35. package/dist/vitest.js.map +1 -0
  36. package/package.json +56 -0
  37. package/templates/plugin/blank/plugin.yaml +22 -0
  38. package/templates/plugin/blank/src/plugin.ts +74 -0
  39. package/templates/plugin/blank/test/plugin.test.ts +33 -0
  40. package/templates/plugin/common/README.md +23 -0
  41. package/templates/plugin/common/RUNBOOK.md +10 -0
  42. package/templates/plugin/common/src/index.ts +4 -0
  43. package/templates/plugin/common/tsconfig.build.json +9 -0
  44. package/templates/plugin/common/tsconfig.json +7 -0
  45. package/templates/plugin/common/vitest.config.ts +1 -0
  46. package/templates/plugin/openapi-rest/plugin.yaml +49 -0
  47. package/templates/plugin/openapi-rest/src/plugin.ts +89 -0
  48. package/templates/plugin/openapi-rest/test/e2e.test.ts +49 -0
  49. package/templates/plugin/openapi-rest/test/fake-upstream.ts +63 -0
  50. package/templates/plugin/openapi-rest/test/plugin.test.ts +66 -0
  51. package/templates/plugin/static-rest/plugin.yaml +61 -0
  52. package/templates/plugin/static-rest/src/plugin.ts +70 -0
  53. package/templates/plugin/static-rest/test/e2e.test.ts +46 -0
  54. package/templates/plugin/static-rest/test/fake-upstream.ts +39 -0
  55. package/templates/plugin/static-rest/test/plugin.test.ts +67 -0
  56. package/templates/plugin/websocket-rpc/plugin.yaml +45 -0
  57. package/templates/plugin/websocket-rpc/src/client.ts +96 -0
  58. package/templates/plugin/websocket-rpc/src/plugin.ts +98 -0
  59. package/templates/plugin/websocket-rpc/test/e2e.test.ts +46 -0
  60. package/templates/plugin/websocket-rpc/test/fake-upstream.ts +63 -0
  61. package/templates/plugin/websocket-rpc/test/plugin.test.ts +67 -0
  62. package/templates/repo/base/README.md +27 -0
  63. package/templates/repo/base/_github/workflows/ci.yml +27 -0
  64. package/templates/repo/base/_gitignore +6 -0
  65. package/templates/repo/base/_nvmrc +1 -0
  66. package/templates/repo/base/_prettierignore +3 -0
  67. package/templates/repo/base/_prettierrc +5 -0
  68. package/templates/repo/base/eslint.config.js +17 -0
  69. package/templates/repo/base/package.json +34 -0
  70. package/templates/repo/base/plugin-files.d.ts +10 -0
  71. package/templates/repo/base/pnpm-workspace.yaml +11 -0
  72. package/templates/repo/base/tsconfig.base.json +21 -0
  73. package/templates/repo/base/vitest.shared.ts +9 -0
  74. package/templates/repo/claude/CLAUDE.md +38 -0
  75. package/templates/repo/claude/_claude/agents/security-reviewer.md +33 -0
  76. package/templates/repo/claude/_claude/hooks/format.mjs +20 -0
  77. package/templates/repo/claude/_claude/hooks/guard-paths.mjs +43 -0
  78. package/templates/repo/claude/_claude/hooks/session-start.sh +13 -0
  79. package/templates/repo/claude/_claude/settings.json +21 -0
  80. package/templates/repo/claude/_claude/skills/add-plugin/SKILL.md +39 -0
  81. package/templates/repo/claude/_claude/skills/release-plugin/SKILL.md +18 -0
  82. package/templates/repo/release/RELEASING.md +27 -0
  83. package/templates/repo/release/_github/workflows/release.yml +89 -0
@@ -0,0 +1,47 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /** The plugin repository root: the nearest directory up from `start` with a `pnpm-workspace.yaml`. */
5
+ export function findRepoRoot(start = process.cwd()) {
6
+ let dir = path.resolve(start);
7
+ for (;;) {
8
+ if (existsSync(path.join(dir, 'pnpm-workspace.yaml')))
9
+ return dir;
10
+ const parent = path.dirname(dir);
11
+ if (parent === dir)
12
+ throw new Error(`No plugin repository (pnpm-workspace.yaml) above ${start}`);
13
+ dir = parent;
14
+ }
15
+ }
16
+ /** This package's directory. */
17
+ export const PACKAGE_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
18
+ export const TEMPLATES_DIR = path.join(PACKAGE_DIR, 'templates');
19
+ function installedVersion(name) {
20
+ let dir = PACKAGE_DIR;
21
+ for (;;) {
22
+ const file = path.join(dir, 'node_modules', ...name.split('/'), 'package.json');
23
+ if (existsSync(file))
24
+ return JSON.parse(readFileSync(file, 'utf8')).version;
25
+ const parent = path.dirname(dir);
26
+ if (parent === dir)
27
+ return undefined;
28
+ dir = parent;
29
+ }
30
+ }
31
+ /**
32
+ * The range generated packages should use for one of this tool's own dependencies: as published
33
+ * (`pnpm pack` turns `workspace:` ranges into real ones), else from the installed version.
34
+ */
35
+ export function dependencyRange(name) {
36
+ const own = JSON.parse(readFileSync(path.join(PACKAGE_DIR, 'package.json'), 'utf8'));
37
+ if (name === own.name)
38
+ return `^${own.version}`;
39
+ const declared = own.dependencies?.[name] ?? own.peerDependencies?.[name] ?? own.devDependencies?.[name];
40
+ if (declared && !declared.startsWith('workspace:'))
41
+ return declared;
42
+ const version = installedVersion(name);
43
+ if (!version)
44
+ throw new Error(`Cannot tell which version of ${name} to use`);
45
+ return `^${version}`;
46
+ }
47
+ //# sourceMappingURL=repo-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-root.js","sourceRoot":"","sources":["../src/repo-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,sGAAsG;AACtG,MAAM,UAAU,YAAY,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE;IAChD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,SAAS,CAAC;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,KAAK,EAAE,CAAC,CAAC;QACjG,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED,gCAAgC;AAChC,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC5F,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAEjE,SAAS,gBAAgB,CAAC,IAAY;IACpC,IAAI,GAAG,GAAG,WAAW,CAAC;IACtB,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;QAChF,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,OAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAA0B,CAAC,OAAO,CAAC;QACtG,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,SAAS,CAAC;QACrC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAMlF,CAAC;IACF,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI;QAAE,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC;IACzG,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpE,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,SAAS,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,EAAE,CAAC;AACvB,CAAC"}
package/dist/repo.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Builds a signed plugin repository that Synoikia installs plugins from (design §4.2–4.3). Every
3
+ * plugin version is a GitHub release `<id>-v<version>` holding `<id>-<version>.tgz` and its minisign
4
+ * signature; `index.json` lists every released version and lives on the fixed `index` release. A
5
+ * release workflow runs the steps in order, signing between `pack` and `index`:
6
+ *
7
+ * pack build and pack each plugin whose manifest version isn't in the current index yet
8
+ * index merge the new versions, with their signatures, into the current index
9
+ * verify install the new versions with Synoikia's own repository service, pinned to minisign.pub
10
+ * publish create the version releases, then replace index.json on the `index` release
11
+ *
12
+ * Released versions are never rebuilt or removed: to ship a change, bump the plugin's version.
13
+ */
14
+ export interface RepoOptions {
15
+ /** The repository root (holding `plugins/` and `minisign.pub`). */
16
+ root: string;
17
+ /** `owner/name` on GitHub. Default: root package.json `synoikia.repository`, else the `origin` remote. */
18
+ repository?: string;
19
+ /** Output directory, relative to the root. Default `.repo`. */
20
+ out?: string;
21
+ /** The currently published index, relative to the root. Default `.repo-current/index.json`. */
22
+ current?: string;
23
+ /** Command that builds one plugin (receives the plugin directory). Default `pnpm --filter <dir> run build`. */
24
+ buildPlugin?: (dir: string) => void;
25
+ log?: (line: string) => void;
26
+ }
27
+ interface Release {
28
+ id: string;
29
+ version: string;
30
+ tag: string;
31
+ file: string;
32
+ sha256: string;
33
+ name: string;
34
+ description?: string;
35
+ sdk: string;
36
+ minCoreVersion?: string;
37
+ }
38
+ interface IndexVersion {
39
+ version: string;
40
+ sdk: string;
41
+ minCoreVersion?: string;
42
+ url: string;
43
+ sha256: string;
44
+ signature: string;
45
+ }
46
+ interface RepoIndex {
47
+ schema: number;
48
+ name: string;
49
+ homepage: string;
50
+ publicKey: string;
51
+ plugins: {
52
+ id: string;
53
+ name: string;
54
+ description?: string;
55
+ versions: IndexVersion[];
56
+ }[];
57
+ }
58
+ /** `git@github.com:owner/name.git` or `https://github.com/owner/name(.git)` → `owner/name`. */
59
+ export declare function repositoryFromRemote(remote: string): string | undefined;
60
+ export declare function createRepoTool(opts: RepoOptions): {
61
+ repository: string;
62
+ out: string;
63
+ pack: () => Release[];
64
+ index: () => RepoIndex;
65
+ verify: () => Promise<void>;
66
+ publish: () => void;
67
+ };
68
+ export {};
package/dist/repo.js ADDED
@@ -0,0 +1,222 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
3
+ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import path from 'node:path';
6
+ const INDEX_TAG = 'index';
7
+ const readJson = (file) => JSON.parse(readFileSync(file, 'utf8'));
8
+ /** `git@github.com:owner/name.git` or `https://github.com/owner/name(.git)` → `owner/name`. */
9
+ export function repositoryFromRemote(remote) {
10
+ const m = /github\.com[:/]([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/.exec(remote.trim());
11
+ return m ? `${m[1]}/${m[2]}` : undefined;
12
+ }
13
+ function resolveRepository(root, explicit) {
14
+ if (explicit)
15
+ return explicit;
16
+ const pkg = readJson(path.join(root, 'package.json'));
17
+ if (pkg.synoikia?.repository)
18
+ return pkg.synoikia.repository;
19
+ try {
20
+ const remote = execFileSync('git', ['remote', 'get-url', 'origin'], { cwd: root, encoding: 'utf8' });
21
+ const repo = repositoryFromRemote(remote);
22
+ if (repo)
23
+ return repo;
24
+ }
25
+ catch {
26
+ // no git remote
27
+ }
28
+ throw new Error('Set "synoikia": { "repository": "owner/name" } in package.json, or pass --repository');
29
+ }
30
+ export function createRepoTool(opts) {
31
+ const root = path.resolve(opts.root);
32
+ const repository = resolveRepository(root, opts.repository);
33
+ if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository))
34
+ throw new Error(`Invalid repository ${repository}`);
35
+ const downloadBase = `https://github.com/${repository}/releases/download`;
36
+ const out = path.resolve(root, opts.out ?? '.repo');
37
+ const releasesFile = path.join(out, 'releases.json');
38
+ const log = opts.log ?? ((line) => console.log(line));
39
+ const indexName = readJson(path.join(root, 'package.json')).synoikia?.name;
40
+ const publicKey = () => readFileSync(path.join(root, 'minisign.pub'), 'utf8').trim().split('\n').at(-1).trim();
41
+ const buildPlugin = opts.buildPlugin ??
42
+ ((dir) => execFileSync('pnpm', ['--filter', `./${path.relative(root, dir)}`, 'run', 'build'], {
43
+ cwd: root,
44
+ stdio: 'inherit',
45
+ }));
46
+ function currentIndex() {
47
+ const file = path.resolve(root, opts.current ?? '.repo-current/index.json');
48
+ const empty = {
49
+ schema: 1,
50
+ name: indexName ?? 'Synoikia plugins',
51
+ homepage: `https://github.com/${repository}`,
52
+ publicKey: publicKey(),
53
+ plugins: [],
54
+ };
55
+ if (!existsSync(file))
56
+ return empty;
57
+ const index = readJson(file);
58
+ if (index.publicKey !== empty.publicKey) {
59
+ throw new Error('The published index has a different public key than minisign.pub; refusing to extend it.');
60
+ }
61
+ return index;
62
+ }
63
+ const released = (index, id, version) => index.plugins.some((p) => p.id === id && p.versions.some((v) => v.version === version));
64
+ function pack() {
65
+ const index = currentIndex();
66
+ mkdirSync(out, { recursive: true });
67
+ const releases = [];
68
+ const pluginsDir = path.join(root, 'plugins');
69
+ for (const id of readdirSync(pluginsDir).sort()) {
70
+ const dir = path.join(pluginsDir, id);
71
+ if (!existsSync(path.join(dir, 'manifest.json')))
72
+ continue;
73
+ const manifest = readJson(path.join(dir, 'manifest.json'));
74
+ const pkg = readJson(path.join(dir, 'package.json'));
75
+ if (manifest.id !== id)
76
+ throw new Error(`plugins/${id}: manifest id is ${manifest.id}`);
77
+ if (pkg.version !== manifest.version) {
78
+ throw new Error(`plugins/${id}: package.json ${pkg.version} and manifest.json ${manifest.version} differ`);
79
+ }
80
+ if (released(index, id, manifest.version))
81
+ continue;
82
+ buildPlugin(dir);
83
+ const file = `${id}-${manifest.version}.tgz`;
84
+ // Flat layout, what core installs: manifest.json, package.json, dist/. Sorted, with fixed times and
85
+ // owners, so the same sources give the same bytes.
86
+ const tarball = execFileSync('tar', [
87
+ '--sort=name',
88
+ '--mtime=1970-01-01 00:00:00Z',
89
+ '--owner=0',
90
+ '--group=0',
91
+ '--numeric-owner',
92
+ '-C',
93
+ dir,
94
+ '-cf',
95
+ '-',
96
+ 'manifest.json',
97
+ 'package.json',
98
+ 'dist',
99
+ ], { maxBuffer: 256 * 1024 * 1024 });
100
+ const gz = execFileSync('gzip', ['-n', '-9'], { input: tarball, maxBuffer: 256 * 1024 * 1024 });
101
+ writeFileSync(path.join(out, file), gz);
102
+ releases.push({
103
+ id,
104
+ version: manifest.version,
105
+ tag: `${id}-v${manifest.version}`,
106
+ file,
107
+ sha256: createHash('sha256').update(gz).digest('hex'),
108
+ name: manifest.name,
109
+ description: manifest.description,
110
+ sdk: manifest.sdk,
111
+ minCoreVersion: pkg.synoikia?.minCoreVersion,
112
+ });
113
+ log(`packed ${file}`);
114
+ }
115
+ writeFileSync(releasesFile, JSON.stringify(releases, null, 2) + '\n');
116
+ log(releases.length ? `${releases.length} new version(s)` : 'nothing new to release');
117
+ return releases;
118
+ }
119
+ function index() {
120
+ const idx = currentIndex();
121
+ for (const r of readJson(releasesFile)) {
122
+ const sigFile = path.join(out, `${r.file}.minisig`);
123
+ if (!existsSync(sigFile))
124
+ throw new Error(`${r.file} is not signed`);
125
+ let plugin = idx.plugins.find((p) => p.id === r.id);
126
+ if (!plugin)
127
+ idx.plugins.push((plugin = { id: r.id, name: r.name, versions: [] }));
128
+ plugin.name = r.name;
129
+ if (r.description)
130
+ plugin.description = r.description;
131
+ plugin.versions.push({
132
+ version: r.version,
133
+ sdk: r.sdk,
134
+ ...(r.minCoreVersion ? { minCoreVersion: r.minCoreVersion } : {}),
135
+ url: `${downloadBase}/${r.tag}/${r.file}`,
136
+ sha256: r.sha256,
137
+ signature: readFileSync(sigFile, 'utf8'),
138
+ });
139
+ }
140
+ idx.plugins.sort((a, b) => a.id.localeCompare(b.id));
141
+ writeFileSync(path.join(out, 'index.json'), JSON.stringify(idx, null, 2) + '\n');
142
+ return idx;
143
+ }
144
+ async function verify() {
145
+ const releases = readJson(releasesFile);
146
+ if (!releases.length)
147
+ return log('nothing to verify');
148
+ // Only this run's versions are local; the check installs exactly those, from the index as published.
149
+ const full = readJson(path.join(out, 'index.json'));
150
+ const subset = {
151
+ ...full,
152
+ plugins: full.plugins
153
+ .map((p) => ({
154
+ ...p,
155
+ versions: p.versions.filter((v) => releases.some((r) => r.id === p.id && r.version === v.version)),
156
+ }))
157
+ .filter((p) => p.versions.length),
158
+ };
159
+ const file = path.join(out, 'verify-index.json');
160
+ writeFileSync(file, JSON.stringify(subset));
161
+ let testing;
162
+ try {
163
+ testing = await import('@synoikia/core/testing');
164
+ }
165
+ catch {
166
+ throw new Error('verify needs @synoikia/core installed (a dev dependency of the plugin repository)');
167
+ }
168
+ const verified = await testing.verifyPluginRepository({ index: file, assets: out, publicKey: publicKey() });
169
+ for (const v of verified) {
170
+ if (!v.signatureVerified)
171
+ throw new Error(`${v.id}@${v.version}: signature not verified`);
172
+ log(`verified ${v.id}@${v.version}`);
173
+ }
174
+ }
175
+ function publish() {
176
+ const releases = readJson(releasesFile);
177
+ if (!releases.length)
178
+ return log('nothing to publish');
179
+ const gh = (...a) => execFileSync('gh', a, { cwd: root, stdio: 'inherit' });
180
+ const exists = (tag) => {
181
+ try {
182
+ execFileSync('gh', ['release', 'view', tag], { cwd: root, stdio: 'ignore' });
183
+ return true;
184
+ }
185
+ catch {
186
+ return false;
187
+ }
188
+ };
189
+ for (const r of releases) {
190
+ const tarball = path.join(out, r.file);
191
+ // Left by a run that stopped before updating the index. Released bytes never change: continue only
192
+ // if the tarball there is exactly this run's (packing is deterministic), and only then refresh its
193
+ // signature, which the index about to be published carries.
194
+ if (exists(r.tag)) {
195
+ const dir = mkdtempSync(path.join(tmpdir(), 'synoikia-release-'));
196
+ try {
197
+ execFileSync('gh', ['release', 'download', r.tag, '--pattern', r.file, '--dir', dir], {
198
+ cwd: root,
199
+ stdio: 'ignore',
200
+ });
201
+ const published = createHash('sha256')
202
+ .update(readFileSync(path.join(dir, r.file)))
203
+ .digest('hex');
204
+ if (published !== r.sha256)
205
+ throw new Error(`${r.tag} is already released with different contents; bump the version instead`);
206
+ }
207
+ finally {
208
+ rmSync(dir, { recursive: true, force: true });
209
+ }
210
+ gh('release', 'upload', r.tag, `${tarball}.minisig`, '--clobber');
211
+ continue;
212
+ }
213
+ gh('release', 'create', r.tag, tarball, `${tarball}.minisig`, '--title', `${r.name} ${r.version}`, '--notes', `${r.name} ${r.version}, signed with the key in minisign.pub. Install it from Synoikia's Plugins page.`, '--latest=false');
214
+ }
215
+ if (!exists(INDEX_TAG)) {
216
+ gh('release', 'create', INDEX_TAG, '--title', 'Plugin index', '--notes', 'The index Synoikia reads this repository from. Replaced on every release.', '--latest=false');
217
+ }
218
+ gh('release', 'upload', INDEX_TAG, path.join(out, 'index.json'), '--clobber');
219
+ }
220
+ return { repository, out, pack, index, verify, publish };
221
+ }
222
+ //# sourceMappingURL=repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.js","sourceRoot":"","sources":["../src/repo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Scaffolding: a new plugin repository (`pnpm create @synoikia/plugin`) and a new plugin inside one
3
+ * (`pnpm new`). Templates are plain files with `{{name}}` placeholders; only known names are replaced
4
+ * and nothing in a template runs. Files whose name starts with `_` are written with a leading `.`
5
+ * (npm drops some dotfiles from published packages). Generated code uses only the published SDK and
6
+ * core APIs, and the generated manifest already follows the secret rules `synoikia-plugin check`
7
+ * enforces.
8
+ */
9
+ export declare const ARCHETYPES: {
10
+ readonly 'openapi-rest': "REST API that serves an OpenAPI spec: the catalog is the spec, rules lock and describe";
11
+ readonly 'static-rest': "REST API without a spec: operations are declared in plugin.yaml";
12
+ readonly 'websocket-rpc': "JSON-RPC 2.0 over WebSocket: methods declared in plugin.yaml";
13
+ readonly blank: "A minimal plugin to fill in by hand";
14
+ };
15
+ export type Archetype = keyof typeof ARCHETYPES;
16
+ export declare const AUTH_KINDS: {
17
+ readonly bearer: "Bearer token (Authorization: Bearer …)";
18
+ readonly 'api-key': "API key header (e.g. X-Api-Key)";
19
+ readonly basic: "Username and password (HTTP Basic)";
20
+ readonly none: "No authentication";
21
+ };
22
+ export type AuthKind = keyof typeof AUTH_KINDS;
23
+ export interface NewPluginOptions {
24
+ /** The plugin repository root. */
25
+ root: string;
26
+ id: string;
27
+ name: string;
28
+ /** Sandbox namespace; defaults to the id in camelCase. */
29
+ namespace?: string;
30
+ description?: string;
31
+ archetype: Archetype;
32
+ auth: AuthKind;
33
+ /** Header for `api-key` auth. Default `X-Api-Key`. */
34
+ apiKeyHeader?: string;
35
+ /** Override dependency ranges (tests). */
36
+ ranges?: Partial<Record<'sdk' | 'core' | 'cli', string>>;
37
+ }
38
+ export declare const ID_PATTERN: RegExp;
39
+ export declare const camelCase: (id: string) => string;
40
+ export declare const pascalCase: (id: string) => string;
41
+ /** Problems with a plugin id or namespace, or undefined. */
42
+ export declare function validateId(id: string, root?: string): string | undefined;
43
+ export declare function validateName(name: string): string | undefined;
44
+ export declare function validateDescription(text: string): string | undefined;
45
+ export declare function validateNamespace(ns: string): string | undefined;
46
+ /** Replaces `{{name}}` for the names in `vars`; anything else (e.g. `{{connection.baseUrl}}`) stays. */
47
+ export declare function fill(text: string, vars: Record<string, string>): string;
48
+ /** Copies a template directory, filling placeholders. Refuses to overwrite an existing file. */
49
+ export declare function renderTemplate(from: string, to: string, vars: Record<string, string>, written?: string[]): string[];
50
+ /** The generated manifest: connection form, secrets, network hosts and binding. */
51
+ export declare function manifestFor(opts: NewPluginOptions, namespace: string): Record<string, unknown>;
52
+ /** Writes `plugins/<id>/` from the archetype's template. Returns the files written. */
53
+ export declare function newPlugin(opts: NewPluginOptions): string[];
54
+ export interface CreateRepoOptions {
55
+ /** The new repository's directory (must not exist, or be empty). */
56
+ dir: string;
57
+ /** `owner/name` on GitHub, for the release index. */
58
+ repository?: string;
59
+ /** Add the signed-release workflow. */
60
+ release?: boolean;
61
+ /** Add the Claude Code setup (CLAUDE.md, skills, hooks, security reviewer). */
62
+ claude?: boolean;
63
+ ranges?: Partial<Record<'core' | 'cli', string>>;
64
+ }
65
+ /** Writes a new plugin repository. Returns the files written. */
66
+ export declare function createRepo(opts: CreateRepoOptions): string[];
67
+ /** `pnpm install` in the repository (links a new plugin, updates the lockfile). */
68
+ export declare function install(root: string): void;