@anby/cli 0.1.0 → 0.7.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,23 @@
1
+ /**
2
+ * `anby app codegen [--watch]` — PLAN-app-bootstrap-phase2 PR5.
3
+ *
4
+ * Reads `anby-app.manifest.json` and writes `.anby/types.d.ts` with
5
+ * TypeScript declaration merging that extends `@anby/platform-sdk`'s
6
+ * `AppProvidedEvents` and `AppRequiredEvents` interfaces. After this
7
+ * runs, calls to `publishEvent({ type: 'org.node.created', ... })` get
8
+ * compile-time autocomplete and typo-detection on the event name.
9
+ *
10
+ * For Vite users, prefer the `@anby/platform-sdk/vite` plugin which runs
11
+ * the same logic automatically as part of the dev server. This CLI
12
+ * exists for non-Vite runtimes (NestJS, plain Node, ESBuild, etc).
13
+ *
14
+ * `--watch` re-runs whenever the manifest file changes. Useful as a
15
+ * background process during dev: `anby app codegen --watch &`.
16
+ */
17
+ interface CodegenOptions {
18
+ manifest: string;
19
+ out: string;
20
+ watch?: boolean;
21
+ }
22
+ export declare function codegenCommand(options: CodegenOptions): Promise<void>;
23
+ export {};
@@ -0,0 +1,77 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, watch, existsSync } from 'node:fs';
2
+ import { dirname, resolve, isAbsolute } from 'node:path';
3
+ import kleur from 'kleur';
4
+ function renderTypes(provides, requires) {
5
+ const sections = [];
6
+ sections.push('// Generated by @anby/cli — DO NOT EDIT.');
7
+ sections.push('// Re-runs whenever anby-app.manifest.json changes.');
8
+ sections.push('');
9
+ sections.push("declare module '@anby/platform-sdk' {");
10
+ if (provides.length > 0) {
11
+ sections.push(' interface AppProvidedEvents {');
12
+ for (const name of provides) {
13
+ sections.push(` ${JSON.stringify(name)}: Record<string, unknown>;`);
14
+ }
15
+ sections.push(' }');
16
+ }
17
+ else {
18
+ sections.push(' interface AppProvidedEvents {}');
19
+ }
20
+ if (requires.length > 0) {
21
+ sections.push(' interface AppRequiredEvents {');
22
+ for (const name of requires) {
23
+ sections.push(` ${JSON.stringify(name)}: Record<string, unknown>;`);
24
+ }
25
+ sections.push(' }');
26
+ }
27
+ else {
28
+ sections.push(' interface AppRequiredEvents {}');
29
+ }
30
+ sections.push('}');
31
+ sections.push('');
32
+ sections.push('export {};');
33
+ sections.push('');
34
+ return sections.join('\n');
35
+ }
36
+ function generate(manifestAbs, outAbs) {
37
+ if (!existsSync(manifestAbs)) {
38
+ console.error(kleur.red(`✖ Manifest not found at ${manifestAbs}`));
39
+ process.exit(1);
40
+ }
41
+ const raw = readFileSync(manifestAbs, 'utf-8');
42
+ const parsed = JSON.parse(raw);
43
+ const provides = Array.isArray(parsed.provides?.events) ? parsed.provides.events : [];
44
+ const requires = Array.isArray(parsed.requires?.events) ? parsed.requires.events : [];
45
+ const content = renderTypes(provides, requires);
46
+ mkdirSync(dirname(outAbs), { recursive: true });
47
+ writeFileSync(outAbs, content);
48
+ console.log(kleur.green(`✔ Wrote ${outAbs} (${provides.length} provided, ${requires.length} required)`));
49
+ }
50
+ export async function codegenCommand(options) {
51
+ const manifestAbs = isAbsolute(options.manifest)
52
+ ? options.manifest
53
+ : resolve(process.cwd(), options.manifest);
54
+ const outAbs = isAbsolute(options.out)
55
+ ? options.out
56
+ : resolve(process.cwd(), options.out);
57
+ generate(manifestAbs, outAbs);
58
+ if (options.watch) {
59
+ console.log(kleur.dim(`Watching ${manifestAbs} for changes... (Ctrl+C to exit)`));
60
+ let debounce = null;
61
+ watch(manifestAbs, () => {
62
+ if (debounce)
63
+ clearTimeout(debounce);
64
+ debounce = setTimeout(() => {
65
+ try {
66
+ generate(manifestAbs, outAbs);
67
+ }
68
+ catch (err) {
69
+ console.error(kleur.red(`✖ Codegen failed: ${err.message}`));
70
+ }
71
+ }, 100);
72
+ });
73
+ // Keep process alive
74
+ await new Promise(() => { });
75
+ }
76
+ }
77
+ //# sourceMappingURL=codegen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/commands/codegen.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { validateCommand } from './validate.js';
3
3
  import { publishCommand } from './publish.js';
4
4
  import { installCommand } from './install.js';
5
5
  import { listCommand } from './list.js';
6
+ import { codegenCommand } from './codegen.js';
6
7
  /**
7
8
  * All app-lifecycle commands live under `anby app <verb>` so we can add
8
9
  * other command namespaces later (`anby tenant`, `anby events`, etc.)
@@ -30,6 +31,8 @@ export function registerAppCommands(program) {
30
31
  .option('--public-url <url>', 'Public URL where this service is reachable')
31
32
  .option('--changelog <text>', 'Optional changelog note attached to this version')
32
33
  .option('--featured', 'Flag the app as featured in the setup wizard')
34
+ .option('--save-to <path>', 'Write the assembled ANBY_APP_TOKEN to this file (e.g. .env.local)')
35
+ .option('--platform-url <url>', 'Override the platform base URL embedded in the token (defaults to registry URL with /registry stripped)')
33
36
  .action(publishCommand);
34
37
  app
35
38
  .command('install')
@@ -44,5 +47,12 @@ export function registerAppCommands(program) {
44
47
  .option('--tenant <tenantId>', 'Show installed apps for this tenant')
45
48
  .option('--registry <url>', 'Registry base URL', process.env.REGISTRY_URL || 'http://localhost:3003')
46
49
  .action(listCommand);
50
+ app
51
+ .command('codegen')
52
+ .description('Generate TypeScript types from anby-app.manifest.json (event names, etc)')
53
+ .option('--manifest <path>', 'Path to manifest file', './anby-app.manifest.json')
54
+ .option('--out <path>', 'Output path for generated types', './.anby/types.d.ts')
55
+ .option('--watch', 'Watch the manifest and regenerate on change')
56
+ .action(codegenCommand);
47
57
  }
48
58
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAEnE,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,gEAAgE,CAAC;SAC7E,MAAM,CAAC,WAAW,EAAE,iDAAiD,CAAC;SACtE,MAAM,CAAC,eAAe,EAAE,yBAAyB,CAAC;SAClD,MAAM,CAAC,eAAe,EAAE,cAAc,EAAE,MAAM,CAAC;SAC/C,MAAM,CAAC,WAAW,CAAC,CAAC;IAEvB,GAAG;SACA,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,mEAAmE,CAAC;SAChF,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,0BAA0B,CAAC;SAChF,MAAM,CAAC,eAAe,CAAC,CAAC;IAE3B,GAAG;SACA,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,0BAA0B,CAAC;SAChF,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB,CAAC;SACpG,MAAM,CAAC,oBAAoB,EAAE,4CAA4C,CAAC;SAC1E,MAAM,CAAC,oBAAoB,EAAE,kDAAkD,CAAC;SAChF,MAAM,CAAC,YAAY,EAAE,8CAA8C,CAAC;SACpE,MAAM,CAAC,cAAc,CAAC,CAAC;IAE1B,GAAG;SACA,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,cAAc,CAAC,qBAAqB,EAAE,WAAW,CAAC;SAClD,cAAc,CAAC,eAAe,EAAE,mBAAmB,CAAC;SACpD,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB,CAAC;SACpG,MAAM,CAAC,cAAc,CAAC,CAAC;IAE1B,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,6DAA6D,CAAC;SAC1E,MAAM,CAAC,qBAAqB,EAAE,qCAAqC,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB,CAAC;SACpG,MAAM,CAAC,WAAW,CAAC,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAEnE,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,gEAAgE,CAAC;SAC7E,MAAM,CAAC,WAAW,EAAE,iDAAiD,CAAC;SACtE,MAAM,CAAC,eAAe,EAAE,yBAAyB,CAAC;SAClD,MAAM,CAAC,eAAe,EAAE,cAAc,EAAE,MAAM,CAAC;SAC/C,MAAM,CAAC,WAAW,CAAC,CAAC;IAEvB,GAAG;SACA,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,mEAAmE,CAAC;SAChF,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,0BAA0B,CAAC;SAChF,MAAM,CAAC,eAAe,CAAC,CAAC;IAE3B,GAAG;SACA,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,0BAA0B,CAAC;SAChF,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB,CAAC;SACpG,MAAM,CAAC,oBAAoB,EAAE,4CAA4C,CAAC;SAC1E,MAAM,CAAC,oBAAoB,EAAE,kDAAkD,CAAC;SAChF,MAAM,CAAC,YAAY,EAAE,8CAA8C,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,mEAAmE,CAAC;SAC/F,MAAM,CAAC,sBAAsB,EAAE,yGAAyG,CAAC;SACzI,MAAM,CAAC,cAAc,CAAC,CAAC;IAE1B,GAAG;SACA,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,cAAc,CAAC,qBAAqB,EAAE,WAAW,CAAC;SAClD,cAAc,CAAC,eAAe,EAAE,mBAAmB,CAAC;SACpD,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB,CAAC;SACpG,MAAM,CAAC,cAAc,CAAC,CAAC;IAE1B,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,6DAA6D,CAAC;SAC1E,MAAM,CAAC,qBAAqB,EAAE,qCAAqC,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB,CAAC;SACpG,MAAM,CAAC,WAAW,CAAC,CAAC;IAEvB,GAAG;SACA,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,0EAA0E,CAAC;SACvF,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,0BAA0B,CAAC;SAChF,MAAM,CAAC,cAAc,EAAE,iCAAiC,EAAE,oBAAoB,CAAC;SAC/E,MAAM,CAAC,SAAS,EAAE,6CAA6C,CAAC;SAChE,MAAM,CAAC,cAAc,CAAC,CAAC;AAC5B,CAAC"}
@@ -4,9 +4,19 @@ interface InitOptions {
4
4
  port?: string;
5
5
  }
6
6
  /**
7
- * Writes an `anby-app.manifest.json` skeleton that passes the AJV
8
- * schema out of the box. Refuses to overwrite an existing file so a
9
- * developer can't accidentally clobber their real manifest.
7
+ * One-stop project bootstrap for an Anby app.
8
+ *
9
+ * Run once after `npm create remix` (or any Vite-based stack):
10
+ *
11
+ * 1. Writes `anby-app.manifest.json` skeleton
12
+ * 2. Patches `vite.config.ts` to load `anbyVitePlugin()` from
13
+ * `@anby/platform-sdk/vite` (idempotent — skips if already wired)
14
+ * 3. Adds `public/_anby/` to `.gitignore`
15
+ *
16
+ * After this single command the app is ready for the Marketplace
17
+ * Submit-app form: every dev/build run regenerates
18
+ * `public/_anby/manifest.json`, which the marketplace shell fetches
19
+ * directly. The publisher never edits any code by hand.
10
20
  */
11
21
  export declare function initCommand(options: InitOptions): Promise<void>;
12
22
  export {};
@@ -1,17 +1,36 @@
1
- import { writeFile, access } from 'node:fs/promises';
1
+ import { writeFile, readFile, access } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
3
  import kleur from 'kleur';
4
4
  /**
5
- * Writes an `anby-app.manifest.json` skeleton that passes the AJV
6
- * schema out of the box. Refuses to overwrite an existing file so a
7
- * developer can't accidentally clobber their real manifest.
5
+ * One-stop project bootstrap for an Anby app.
6
+ *
7
+ * Run once after `npm create remix` (or any Vite-based stack):
8
+ *
9
+ * 1. Writes `anby-app.manifest.json` skeleton
10
+ * 2. Patches `vite.config.ts` to load `anbyVitePlugin()` from
11
+ * `@anby/platform-sdk/vite` (idempotent — skips if already wired)
12
+ * 3. Adds `public/_anby/` to `.gitignore`
13
+ *
14
+ * After this single command the app is ready for the Marketplace
15
+ * Submit-app form: every dev/build run regenerates
16
+ * `public/_anby/manifest.json`, which the marketplace shell fetches
17
+ * directly. The publisher never edits any code by hand.
8
18
  */
9
19
  export async function initCommand(options) {
20
+ await writeManifest(options);
21
+ await patchViteConfig();
22
+ await patchGitignore();
23
+ const port = Number.parseInt(options.port ?? '3099', 10);
24
+ console.log('');
25
+ console.log(kleur.green('✔ Anby app bootstrap complete'));
26
+ console.log(kleur.dim(` Next: npm run dev — then submit ${kleur.cyan(`http://localhost:${port}`)} via the Marketplace UI`));
27
+ }
28
+ async function writeManifest(options) {
10
29
  const target = resolve('anby-app.manifest.json');
11
30
  try {
12
31
  await access(target);
13
- console.error(kleur.red(`✖ ${target} already exists — refusing to overwrite`));
14
- process.exit(1);
32
+ console.log(kleur.dim(`• ${target} already exists — leaving it alone`));
33
+ return;
15
34
  }
16
35
  catch {
17
36
  // ok — file doesn't exist
@@ -50,6 +69,111 @@ export async function initCommand(options) {
50
69
  };
51
70
  await writeFile(target, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
52
71
  console.log(kleur.green(`✔ Wrote ${target}`));
53
- console.log(kleur.dim(` Next: anby app validate && anby app publish --public-url http://localhost:${port}`));
72
+ }
73
+ /**
74
+ * Idempotently patch `vite.config.ts` (or `.js`/`.mts`/`.mjs`) to load
75
+ * `anbyVitePlugin()`. The patch is a deliberately small textual edit:
76
+ * we add the import line near the existing imports and inject
77
+ * `anbyVitePlugin(),` as the first entry of the `plugins: [` array.
78
+ *
79
+ * If the file is too unusual to patch safely (no `plugins: [` literal),
80
+ * we print a clear instruction for the publisher to add the lines by
81
+ * hand. Either way the manifest skeleton has already been written, so
82
+ * the command stays useful even when the patch fails.
83
+ */
84
+ async function patchViteConfig() {
85
+ const candidates = [
86
+ 'vite.config.ts',
87
+ 'vite.config.mts',
88
+ 'vite.config.js',
89
+ 'vite.config.mjs',
90
+ ];
91
+ let target = null;
92
+ for (const name of candidates) {
93
+ try {
94
+ await access(resolve(name));
95
+ target = name;
96
+ break;
97
+ }
98
+ catch {
99
+ // try next
100
+ }
101
+ }
102
+ if (!target) {
103
+ console.log(kleur.dim('• No vite.config.* found — skipping plugin wiring. Add `anbyVitePlugin()` from `@anby/platform-sdk/vite` to your bundler manually.'));
104
+ return;
105
+ }
106
+ const path = resolve(target);
107
+ const original = await readFile(path, 'utf-8');
108
+ if (original.includes('anbyVitePlugin')) {
109
+ console.log(kleur.dim(`• ${target} already wires anbyVitePlugin — no patch needed`));
110
+ return;
111
+ }
112
+ const importLine = "import { anbyVitePlugin } from '@anby/platform-sdk/vite';";
113
+ // Insert the import after the last existing top-level `import ... from`
114
+ // line so we don't accidentally split a multi-line import statement.
115
+ const importRegex = /^import .+ from .+;?\s*$/gm;
116
+ let lastImportEnd = -1;
117
+ for (const match of original.matchAll(importRegex)) {
118
+ if (match.index !== undefined) {
119
+ lastImportEnd = match.index + match[0].length;
120
+ }
121
+ }
122
+ let withImport;
123
+ if (lastImportEnd >= 0) {
124
+ withImport =
125
+ original.slice(0, lastImportEnd) +
126
+ '\n' +
127
+ importLine +
128
+ original.slice(lastImportEnd);
129
+ }
130
+ else {
131
+ withImport = importLine + '\n' + original;
132
+ }
133
+ // Inject `anbyVitePlugin(),` as the first item of the `plugins: [` array.
134
+ // We match `plugins:` followed by `[` and any whitespace, and insert
135
+ // right after the `[`. Idempotency is enforced by the earlier
136
+ // `includes('anbyVitePlugin')` check above.
137
+ const pluginsArrayRegex = /(plugins\s*:\s*\[)(\s*)/;
138
+ if (!pluginsArrayRegex.test(withImport)) {
139
+ console.log(kleur.yellow(`! Could not find a \`plugins: [...]\` array in ${target}. ` +
140
+ `Add ${kleur.cyan('anbyVitePlugin()')} to your plugins manually.`));
141
+ return;
142
+ }
143
+ const patched = withImport.replace(pluginsArrayRegex, (_, head, ws) => `${head}${ws}anbyVitePlugin(),${ws}`);
144
+ await writeFile(path, patched, 'utf-8');
145
+ console.log(kleur.green(`✔ Patched ${target} to load anbyVitePlugin`));
146
+ }
147
+ /**
148
+ * Append `public/_anby/` to `.gitignore` so the auto-generated wire
149
+ * manifest doesn't pollute commits. Idempotent — does nothing if the
150
+ * line is already present, and creates the file if missing.
151
+ */
152
+ async function patchGitignore() {
153
+ const path = resolve('.gitignore');
154
+ const line = 'public/_anby/';
155
+ let existing = '';
156
+ try {
157
+ existing = await readFile(path, 'utf-8');
158
+ }
159
+ catch {
160
+ // file doesn't exist — we'll create it below
161
+ }
162
+ // Match either `public/_anby/` or `public/_anby` on its own line, with
163
+ // optional trailing slash and surrounding whitespace.
164
+ const alreadyIgnored = existing
165
+ .split(/\r?\n/)
166
+ .map((l) => l.trim())
167
+ .some((l) => l === line || l === 'public/_anby');
168
+ if (alreadyIgnored) {
169
+ console.log(kleur.dim('• .gitignore already covers public/_anby/ — no change'));
170
+ return;
171
+ }
172
+ const block = (existing.length === 0 || existing.endsWith('\n') ? '' : '\n') +
173
+ '\n# Anby — auto-generated wire manifest (do not commit)\n' +
174
+ line +
175
+ '\n';
176
+ await writeFile(path, existing + block, 'utf-8');
177
+ console.log(kleur.green('✔ Added public/_anby/ to .gitignore'));
54
178
  }
55
179
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,MAAM,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,KAAK,MAAM,yCAAyC,CAAC,CAChE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IAED,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,oBAAoB,CAAC;IAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC;IACtC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IAEzD,MAAM,QAAQ,GAAG;QACf,OAAO,EAAE,+CAA+C;QACxD,EAAE;QACF,OAAO,EAAE,OAAO;QAChB,IAAI;QACJ,WAAW,EAAE,GAAG,IAAI,4BAA4B;QAChD,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE;YACP,IAAI,EAAE,OAAO;YACb,IAAI;YACJ,WAAW,EAAE,aAAa;YAC1B,UAAU,EAAE,aAAa;SAC1B;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAChD,WAAW,EAAE,SAAS;SACvB;QACD,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACtC,QAAQ,EAAE;YACR,QAAQ,EAAE,CAAC,MAAM,CAAC;YAClB,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;SACvC;QACD,WAAW,EAAE,CAAC,gBAAgB,CAAC;QAC/B,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;KACjC,CAAC;IAEF,MAAM,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+EAA+E,IAAI,EAAE,CAAC,CAAC,CAAC;AAChH,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,17 @@ interface PublishOptions {
4
4
  publicUrl?: string;
5
5
  changelog?: string;
6
6
  featured?: boolean;
7
+ /**
8
+ * If set, the CLI writes the assembled ANBY_APP_TOKEN to this path
9
+ * (e.g. ".env.local"). Without this flag the token is only printed
10
+ * to stdout — the dev is responsible for capturing it.
11
+ */
12
+ saveTo?: string;
13
+ /**
14
+ * Override the platform base URL embedded in the token. Defaults to
15
+ * the registry URL with the /registry suffix stripped.
16
+ */
17
+ platformUrl?: string;
7
18
  }
8
19
  export declare function publishCommand(options: PublishOptions): Promise<void>;
9
20
  export {};
@@ -1,5 +1,7 @@
1
1
  import kleur from 'kleur';
2
+ import { writeFile } from 'node:fs/promises';
2
3
  import { publishAppFromManifest } from '@anby/platform-sdk';
4
+ import { assembleToken } from '../lib/token.js';
3
5
  export async function publishCommand(options) {
4
6
  const result = await publishAppFromManifest({
5
7
  manifestPath: options.manifest,
@@ -16,5 +18,39 @@ export async function publishCommand(options) {
16
18
  if (result.app.publicUrl) {
17
19
  console.log(kleur.dim(` publicUrl: ${result.app.publicUrl}`));
18
20
  }
21
+ // PLAN-app-bootstrap PR3: assemble + print ANBY_APP_TOKEN if the registry
22
+ // returned a fresh private key (only happens on first publish for an app).
23
+ if (result.privateKey) {
24
+ const platformUrl = options.platformUrl ?? options.registry.replace(/\/registry\/?$/, '');
25
+ const token = assembleToken({
26
+ appId: result.app.id,
27
+ platformUrl,
28
+ privateKey: result.privateKey,
29
+ });
30
+ console.log('');
31
+ console.log(kleur.bold().yellow('━━━ ANBY_APP_TOKEN (shown ONCE — store it safely) ━━━'));
32
+ console.log('');
33
+ console.log(token);
34
+ console.log('');
35
+ console.log(kleur.dim('Paste this into your app environment as ANBY_APP_TOKEN.\n' +
36
+ 'It contains your app signing key. Treat it as a secret.\n' +
37
+ 'If you lose it, run `anby app rotate-token <appId>` to issue a new one.'));
38
+ console.log(kleur.bold().yellow('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
39
+ if (options.saveTo) {
40
+ const envLine = `ANBY_APP_TOKEN=${token}\n`;
41
+ try {
42
+ await writeFile(options.saveTo, envLine, { mode: 0o600 });
43
+ console.log(kleur.green(`✔ Token written to ${options.saveTo}`));
44
+ }
45
+ catch (err) {
46
+ console.error(kleur.red(`✖ Failed to write token to ${options.saveTo}: ${err.message}`));
47
+ process.exit(1);
48
+ }
49
+ }
50
+ }
51
+ else {
52
+ console.log(kleur.dim('(No new ANBY_APP_TOKEN issued — this app already has a registered keypair.\n' +
53
+ ' To rotate, run `anby app rotate-token ' + result.app.id + '`.)'));
54
+ }
19
55
  }
20
56
  //# sourceMappingURL=publish.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAU5D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC1D,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC;QAC1C,YAAY,EAAE,OAAO,CAAC,QAAQ;QAC9B,WAAW,EAAE,OAAO,CAAC,QAAQ;QAC7B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CACT,eAAe,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,YAAY,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,CACvF,CACF,CAAC;IACF,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * ANBY_APP_TOKEN assembly helper.
3
+ *
4
+ * Mirrors the parser in @anby/platform-sdk/src/bootstrap. Kept in the CLI
5
+ * (rather than imported from the SDK) so the CLI doesn't have to ship the
6
+ * SDK's whole runtime just for one base64 wrapper.
7
+ *
8
+ * Format: anby_v1_<base64url(json)>
9
+ * json = { v: 1, appId, platformUrl, privateKey }
10
+ */
11
+ export declare const ANBY_TOKEN_PREFIX = "anby_v1_";
12
+ export interface AssembleTokenInput {
13
+ appId: string;
14
+ platformUrl: string;
15
+ privateKey: string;
16
+ }
17
+ export declare function assembleToken(input: AssembleTokenInput): string;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * ANBY_APP_TOKEN assembly helper.
3
+ *
4
+ * Mirrors the parser in @anby/platform-sdk/src/bootstrap. Kept in the CLI
5
+ * (rather than imported from the SDK) so the CLI doesn't have to ship the
6
+ * SDK's whole runtime just for one base64 wrapper.
7
+ *
8
+ * Format: anby_v1_<base64url(json)>
9
+ * json = { v: 1, appId, platformUrl, privateKey }
10
+ */
11
+ export const ANBY_TOKEN_PREFIX = 'anby_v1_';
12
+ export function assembleToken(input) {
13
+ if (!input.appId || !input.platformUrl || !input.privateKey) {
14
+ throw new Error('assembleToken: appId, platformUrl, and privateKey are required');
15
+ }
16
+ if (!input.privateKey.includes('PRIVATE KEY')) {
17
+ throw new Error('assembleToken: privateKey must be a PEM');
18
+ }
19
+ const payload = {
20
+ v: 1,
21
+ appId: input.appId,
22
+ platformUrl: input.platformUrl.replace(/\/$/, ''),
23
+ privateKey: input.privateKey,
24
+ };
25
+ return ANBY_TOKEN_PREFIX + Buffer.from(JSON.stringify(payload)).toString('base64url');
26
+ }
27
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/lib/token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAQ5C,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,OAAO,GAAG;QACd,CAAC,EAAE,CAAU;QACb,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACjD,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC;IACF,OAAO,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACxF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anby/cli",
3
- "version": "0.1.0",
3
+ "version": "0.7.0",
4
4
  "description": "Anby Platform CLI — scaffold, validate, publish, and install Anby apps",
5
5
  "keywords": [
6
6
  "anby",
@@ -11,13 +11,13 @@
11
11
  ],
12
12
  "license": "MIT",
13
13
  "author": "ANBY",
14
- "homepage": "https://github.com/bravebits-labs/anby-platform#readme",
14
+ "homepage": "https://github.com/bravebits-labs/anby-platform-packages#readme",
15
15
  "bugs": {
16
- "url": "https://github.com/bravebits-labs/anby-platform/issues"
16
+ "url": "https://github.com/bravebits-labs/anby-platform-packages/issues"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "git+https://github.com/bravebits-labs/anby-platform.git",
20
+ "url": "git+https://github.com/bravebits-labs/anby-platform-packages.git",
21
21
  "directory": "packages/anby-cli"
22
22
  },
23
23
  "type": "module",
@@ -42,8 +42,8 @@
42
42
  "prepublishOnly": "npm run build"
43
43
  },
44
44
  "dependencies": {
45
- "@anby/manifest-schema": "^0.1.0",
46
- "@anby/platform-sdk": "^0.1.0",
45
+ "@anby/manifest-schema": "^0.1.1",
46
+ "@anby/platform-sdk": "^0.7.0",
47
47
  "commander": "^12.1.0",
48
48
  "kleur": "^4.1.5"
49
49
  },