@ryopc/koshi 0.2.0 โ†’ 1.0.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ๐Ÿ„ koshi โ€” Terminal-Native Decentralized SNS
2
2
 
3
- **Version 0.2.0** ยท MIT License ยท by [game_ryo](https://github.com/ryopc)
3
+ **Version 1.0.0** ยท MIT License ยท by [game_ryo](https://github.com/ryopc)
4
4
 
5
5
  > A terminal-native, decentralized social network powered by ed25519 cryptography.
6
6
 
package/bin/cli.js CHANGED
@@ -623,7 +623,7 @@ function showHelp(command = null) {
623
623
  }
624
624
 
625
625
  console.log(`\n ${chalk.bold.cyan('๐Ÿ„ koshi โ€” Terminal-Native Decentralized SNS')}`);
626
- console.log(` ${chalk.dim('Version 0.2.0')}`);
626
+ console.log(` ${chalk.dim('Version 1.0.0')}`);
627
627
  console.log(`\n ${chalk.bold('Usage:')} kb <command> [options]\n`);
628
628
  console.log(` ${chalk.bold('Commands:')}\n`);
629
629
 
@@ -647,7 +647,7 @@ function showHelp(command = null) {
647
647
  // Command: version
648
648
  // ============================================================================
649
649
  function showVersion() {
650
- console.log('koshi v0.2.0');
650
+ console.log('koshi v1.0.0');
651
651
  console.log('Terminal-native decentralized SNS');
652
652
  console.log('License: MIT');
653
653
  console.log('Author: game_ryo');
package/bin/server.js CHANGED
@@ -23,6 +23,7 @@ import { app, logger } from '../src/index.js';
23
23
  import { initWebSocket, startHeartbeat } from '../src/ws/index.js';
24
24
  import { closePool } from '../src/db/pool.js';
25
25
  import { getOnlineCount } from '../src/ws/index.js';
26
+ import { runMigration } from '../src/db/migrate.js';
26
27
 
27
28
  // Load .env file in development
28
29
  try {
@@ -52,6 +53,20 @@ if (missing.length > 0) {
52
53
  process.exit(1);
53
54
  }
54
55
 
56
+ // ============================================================================
57
+ // Auto-migration: ensure database schema is up to date on startup
58
+ // ============================================================================
59
+ // This is especially important for Render free-tier instances that hibernate.
60
+ // The preDeployCommand only runs on fresh deploys, not on wake-up, so we
61
+ // run the migration here to guarantee tables exist on every start.
62
+ // ============================================================================
63
+ const migrationResult = await runMigration();
64
+ if (!migrationResult.success) {
65
+ logger.warn({ message: migrationResult.message }, 'Auto-migration did not complete. Server will still start.');
66
+ } else {
67
+ logger.info('Auto-migration complete');
68
+ }
69
+
55
70
  // Create HTTP server
56
71
  const server = createServer(app);
57
72
 
@@ -60,8 +75,10 @@ const wss = initWebSocket(server, logger);
60
75
  startHeartbeat();
61
76
 
62
77
  // Start listening
63
- server.listen(PORT, () => {
78
+ // '0.0.0.0' ใ‚’ๆ˜Ž็คบ็š„ใซๆŒ‡ๅฎšใ—ใฆใ€Render ใฎๅค–้ƒจใ‹ใ‚‰ใฎ้€šไฟกใ‚’ๅ—ใ‘ไป˜ใ‘ใ‚‰ใ‚Œใ‚‹ใ‚ˆใ†ใซใ—ใพใ™ใ€‚
79
+ server.listen(PORT, '0.0.0.0', () => {
64
80
  logger.info(
81
+
65
82
  { port: PORT, env: process.env.NODE_ENV || 'development' },
66
83
  `๐Ÿš€ koshi server running on port ${PORT}`
67
84
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryopc/koshi",
3
- "version": "0.2.0",
3
+ "version": "1.0.0",
4
4
  "description": "Terminal-native decentralized SNS โ€” koshi board",
5
5
  "type": "module",
6
6
  "bin": {
@@ -34,13 +34,13 @@
34
34
  "pg": "^8.11.3",
35
35
  "pino": "^8.14.1",
36
36
  "pino-pretty": "^10.2.0",
37
- "uuid": "^9.0.0"
37
+ "uuid": "^14.0.0"
38
38
  },
39
39
  "license": "MIT",
40
40
  "author": "game_ryo",
41
41
  "repository": {
42
42
  "type": "git",
43
- "url": "https://github.com/ryopc/koshi"
43
+ "url": "git+https://github.com/ryopc/koshi.git"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=18.0.0"
@@ -38,8 +38,11 @@ export function generateKeypair() {
38
38
  */
39
39
  export async function signMessage(message, secretKey) {
40
40
  const skBytes = hexToBytes(secretKey);
41
+ // @noble/ed25519 v2.x expects a 32-byte private key (seed), not the full
42
+ // 64-byte tweetnacl-format key. If given 64 bytes, take only the seed.
43
+ const seedBytes = skBytes.length === 64 ? skBytes.slice(0, 32) : skBytes;
41
44
  const msgBytes = new TextEncoder().encode(message);
42
- const signature = await ed.sign(msgBytes, skBytes);
45
+ const signature = await ed.signAsync(msgBytes, seedBytes);
43
46
  return bytesToHex(signature);
44
47
  }
45
48
 
@@ -56,7 +59,8 @@ export async function verifySignature(message, signature, publicKey) {
56
59
  const msgBytes = new TextEncoder().encode(message);
57
60
  const sigBytes = hexToBytes(signature);
58
61
  const pkBytes = hexToBytes(publicKey);
59
- return await ed.verify(sigBytes, msgBytes, pkBytes);
62
+ // Use verifyAsync to avoid needing etc.sha512Sync
63
+ return await ed.verifyAsync(sigBytes, msgBytes, pkBytes);
60
64
  } catch (err) {
61
65
  // If any input is malformed (wrong length, invalid hex, etc.), return false
62
66
  return false;