@biznetgio/neo-app 0.4.9 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biznetgio/neo-app",
3
- "version": "0.4.9",
3
+ "version": "0.4.11",
4
4
  "description": "NEO App CLI — one-command agent onboarding, MCP server, and project ops for coding agents (Codex, Claude Code).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,7 +15,8 @@
15
15
  "node": ">=18"
16
16
  },
17
17
  "scripts": {
18
- "test": "node --test"
18
+ "test": "node --test",
19
+ "prepublishOnly": "node --test"
19
20
  },
20
21
  "dependencies": {
21
22
  "@modelcontextprotocol/sdk": "^1.0.0"
@@ -200,7 +200,13 @@ export async function deploySource(api, { projectId, src, name, port, build, env
200
200
  if (buildType && app.buildType && app.buildType !== buildType) patch.buildType = buildType;
201
201
  if (Object.keys(patch).length) {
202
202
  plan.push(`update "${svc}": ${Object.keys(patch).join(', ')}`);
203
- if (!dryRun) { await api.put(`/api/v1/apps/${app.id}`, patch); log(`updated source config (${Object.keys(patch).join(', ')})`); }
203
+ if (!dryRun) {
204
+ const upd = await api.put(`/api/v1/apps/${app.id}`, patch);
205
+ // If the source-config update needs approval, STOP — deploying now would ship
206
+ // the OLD config while the change is still pending (JNG #96 re-validation).
207
+ if (pending(upd)) return { pending: true, approvalId: upd.data.approvalId };
208
+ log(`updated source config (${Object.keys(patch).join(', ')})`);
209
+ }
204
210
  } else {
205
211
  log(`service ${svc} exists — redeploying`);
206
212
  }
package/src/index.js CHANGED
@@ -1,19 +1,7 @@
1
1
  // CLI entrypoint: parse args and dispatch. Keep this thin — logic lives in commands/.
2
2
 
3
3
  import { parseArgs } from 'node:util';
4
- import { readFileSync } from 'node:fs';
5
- import { fileURLToPath } from 'node:url';
6
- import { dirname, join } from 'node:path';
7
- import { c, fail } from './util.js';
8
-
9
- function version() {
10
- try {
11
- const p = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
12
- return JSON.parse(readFileSync(p, 'utf8')).version;
13
- } catch {
14
- return 'dev';
15
- }
16
- }
4
+ import { c, fail, pkgVersion as version } from './util.js';
17
5
 
18
6
  const HELP = `${c.bold('neo-app')} — NEO App CLI for coding agents
19
7
 
package/src/mcp/server.js CHANGED
@@ -9,6 +9,7 @@ import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprot
9
9
  import { resolveConfig } from '../config.js';
10
10
  import { getCredential } from '../creds.js';
11
11
  import { NeoApi } from '../api.js';
12
+ import { pkgVersion } from '../util.js';
12
13
  import { TOOLS } from './tools.js';
13
14
 
14
15
  export async function runMcpServer() {
@@ -19,7 +20,9 @@ export async function runMcpServer() {
19
20
  console.error(`[neo-app mcp] no credential for ${cfg.baseUrl} — run 'neo-app login' or set NEO_APP_TOKEN`);
20
21
  }
21
22
 
22
- const server = new Server({ name: 'neo-app', version: '0.3.0' }, { capabilities: { tools: {} } });
23
+ // serverInfo.version MUST equal the packed npm artifact version (handoff 3.1):
24
+ // derive it from package.json, never hard-code it.
25
+ const server = new Server({ name: 'neo-app', version: pkgVersion() }, { capabilities: { tools: {} } });
23
26
 
24
27
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
25
28
  tools: TOOLS.map((t) => ({
package/src/util.js CHANGED
@@ -1,9 +1,23 @@
1
1
  // Small shared helpers: colored status lines, a config-file backup, and a PATH check.
2
2
 
3
- import { existsSync, copyFileSync } from 'node:fs';
3
+ import { existsSync, copyFileSync, readFileSync } from 'node:fs';
4
4
  import { execFileSync } from 'node:child_process';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { dirname, join } from 'node:path';
5
7
  import readline from 'node:readline';
6
8
 
9
+ // The installed package version — the single source for `--version`, the MCP
10
+ // handshake (serverInfo.version), and any other place that must report it.
11
+ // Derived from the packed package.json so it always matches the npm artifact.
12
+ export function pkgVersion() {
13
+ try {
14
+ const p = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
15
+ return JSON.parse(readFileSync(p, 'utf8')).version;
16
+ } catch {
17
+ return 'dev';
18
+ }
19
+ }
20
+
7
21
  const useColor = process.stdout.isTTY && !process.env.NO_COLOR;
8
22
  const paint = (code, s) => (useColor ? `\x1b[${code}m${s}\x1b[0m` : s);
9
23