@masslessai/push-todo 3.3.0 → 3.4.5

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "push-todo",
3
- "version": "3.3.0",
3
+ "version": "3.4.5",
4
4
  "description": "Voice tasks from Push iOS app"
5
5
  }
package/lib/cli.js CHANGED
@@ -15,7 +15,7 @@ import { ensureDaemonRunning, getDaemonStatus, startDaemon, stopDaemon } from '.
15
15
  import { getScreenshotPath, screenshotExists, openScreenshot } from './utils/screenshots.js';
16
16
  import { bold, red, cyan, dim, green } from './utils/colors.js';
17
17
 
18
- const VERSION = '3.3.0';
18
+ const VERSION = '3.4.5';
19
19
 
20
20
  const HELP_TEXT = `
21
21
  ${bold('push-todo')} - Voice tasks from Push iOS app for Claude Code
package/lib/connect.js CHANGED
@@ -1133,6 +1133,14 @@ export async function runConnect(options = {}) {
1133
1133
  console.log(' ' + '='.repeat(40));
1134
1134
  console.log('');
1135
1135
 
1136
+ // Step 1: Check for updates
1137
+ const versionInfo = await checkVersion();
1138
+ if (versionInfo.updateAvailable) {
1139
+ console.log(` ${yellow('⚠')} Update available: ${versionInfo.current} → ${versionInfo.latest}`);
1140
+ console.log(` Run: ${cyan('npm update -g @masslessai/push-todo')}`);
1141
+ console.log('');
1142
+ }
1143
+
1136
1144
  let existingKey, existingEmail;
1137
1145
  try {
1138
1146
  existingKey = getApiKey();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masslessai/push-todo",
3
- "version": "3.3.0",
3
+ "version": "3.4.5",
4
4
  "description": "Voice tasks from Push iOS app for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Bump the package version following X.Y.Z rules.
4
+ *
5
+ * Version Rules:
6
+ * - Format: X.Y.Z (major.minor.patch)
7
+ * - Z (patch): Increments 0-9, then resets to 0
8
+ * - Y (minor): Increments when Z overflows (0-9 range)
9
+ * - X (major): Increments when Y overflows (0-9 range)
10
+ *
11
+ * Examples:
12
+ * 1.1.0 → 1.1.1
13
+ * 1.1.9 → 1.2.0 (NOT 1.1.10)
14
+ * 1.9.9 → 2.0.0
15
+ *
16
+ * Usage:
17
+ * node scripts/bump-version.js # Bump patch version
18
+ * node scripts/bump-version.js --dry-run # Show what would change
19
+ * node scripts/bump-version.js --minor # Force minor bump
20
+ * node scripts/bump-version.js --major # Force major bump
21
+ */
22
+
23
+ import { readFileSync, writeFileSync } from 'fs';
24
+ import { join, dirname } from 'path';
25
+ import { fileURLToPath } from 'url';
26
+
27
+ const __dirname = dirname(fileURLToPath(import.meta.url));
28
+ const PACKAGE_ROOT = join(__dirname, '..');
29
+
30
+ // Files to update
31
+ const FILES = {
32
+ packageJson: join(PACKAGE_ROOT, 'package.json'),
33
+ pluginJson: join(PACKAGE_ROOT, '.claude-plugin', 'plugin.json'),
34
+ cliJs: join(PACKAGE_ROOT, 'lib', 'cli.js')
35
+ };
36
+
37
+ function parseVersion(version) {
38
+ const parts = version.split('.');
39
+ if (parts.length !== 3) {
40
+ throw new Error(`Invalid version format: ${version}`);
41
+ }
42
+ return parts.map(p => parseInt(p, 10));
43
+ }
44
+
45
+ function formatVersion(major, minor, patch) {
46
+ return `${major}.${minor}.${patch}`;
47
+ }
48
+
49
+ function bumpVersion(current, { forceMinor = false, forceMajor = false } = {}) {
50
+ let [major, minor, patch] = parseVersion(current);
51
+
52
+ if (forceMajor) {
53
+ return formatVersion(major + 1, 0, 0);
54
+ }
55
+
56
+ if (forceMinor) {
57
+ if (minor >= 9) {
58
+ return formatVersion(major + 1, 0, 0);
59
+ }
60
+ return formatVersion(major, minor + 1, 0);
61
+ }
62
+
63
+ // Patch bump with overflow logic
64
+ patch += 1;
65
+
66
+ if (patch > 9) {
67
+ patch = 0;
68
+ minor += 1;
69
+
70
+ if (minor > 9) {
71
+ minor = 0;
72
+ major += 1;
73
+ }
74
+ }
75
+
76
+ return formatVersion(major, minor, patch);
77
+ }
78
+
79
+ function updatePackageJson(newVersion, dryRun) {
80
+ const content = JSON.parse(readFileSync(FILES.packageJson, 'utf8'));
81
+ const oldVersion = content.version;
82
+ content.version = newVersion;
83
+
84
+ if (!dryRun) {
85
+ writeFileSync(FILES.packageJson, JSON.stringify(content, null, 2) + '\n');
86
+ }
87
+
88
+ console.log(` package.json: ${oldVersion} → ${newVersion}`);
89
+ }
90
+
91
+ function updatePluginJson(newVersion, dryRun) {
92
+ const content = JSON.parse(readFileSync(FILES.pluginJson, 'utf8'));
93
+ const oldVersion = content.version;
94
+ content.version = newVersion;
95
+
96
+ if (!dryRun) {
97
+ writeFileSync(FILES.pluginJson, JSON.stringify(content, null, 2) + '\n');
98
+ }
99
+
100
+ console.log(` plugin.json: ${oldVersion} → ${newVersion}`);
101
+ }
102
+
103
+ function updateCliJs(newVersion, dryRun) {
104
+ let content = readFileSync(FILES.cliJs, 'utf8');
105
+ const match = content.match(/const VERSION = '([^']+)'/);
106
+
107
+ if (!match) {
108
+ console.log(` cli.js: VERSION constant not found (skipped)`);
109
+ return;
110
+ }
111
+
112
+ const oldVersion = match[1];
113
+ content = content.replace(
114
+ /const VERSION = '[^']+'/,
115
+ `const VERSION = '${newVersion}'`
116
+ );
117
+
118
+ if (!dryRun) {
119
+ writeFileSync(FILES.cliJs, content);
120
+ }
121
+
122
+ console.log(` cli.js: ${oldVersion} → ${newVersion}`);
123
+ }
124
+
125
+ function main() {
126
+ const args = process.argv.slice(2);
127
+ const dryRun = args.includes('--dry-run');
128
+ const forceMinor = args.includes('--minor');
129
+ const forceMajor = args.includes('--major');
130
+
131
+ // Read current version from package.json
132
+ const packageJson = JSON.parse(readFileSync(FILES.packageJson, 'utf8'));
133
+ const currentVersion = packageJson.version;
134
+
135
+ // Calculate new version
136
+ const newVersion = bumpVersion(currentVersion, { forceMinor, forceMajor });
137
+
138
+ console.log(`\nBumping version: ${currentVersion} → ${newVersion}\n`);
139
+
140
+ // Update all files
141
+ updatePackageJson(newVersion, dryRun);
142
+ updatePluginJson(newVersion, dryRun);
143
+ updateCliJs(newVersion, dryRun);
144
+
145
+ if (dryRun) {
146
+ console.log('\n(dry run - no changes made)');
147
+ } else {
148
+ console.log('\nDone! Now commit and push to trigger publish.');
149
+ }
150
+ }
151
+
152
+ main();
@@ -44,10 +44,11 @@ const BINARY_NAME = 'push-keychain-helper';
44
44
  const BINARY_DIR = join(__dirname, '../bin');
45
45
  const BINARY_PATH = join(BINARY_DIR, BINARY_NAME);
46
46
 
47
- // GitHub release URL pattern
48
- const RELEASE_VERSION = '3.0.0';
49
- const BINARY_URL = `https://github.com/MasslessAI/push-todo-cli/releases/download/v${RELEASE_VERSION}/${BINARY_NAME}-darwin-arm64`;
50
- const BINARY_URL_X64 = `https://github.com/MasslessAI/push-todo-cli/releases/download/v${RELEASE_VERSION}/${BINARY_NAME}-darwin-x64`;
47
+ // Read version from package.json - binaries are released alongside npm package
48
+ const PACKAGE_JSON = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'));
49
+ const VERSION = PACKAGE_JSON.version;
50
+ const BINARY_URL = `https://github.com/MasslessAI/push-todo-cli/releases/download/v${VERSION}/${BINARY_NAME}-darwin-arm64`;
51
+ const BINARY_URL_X64 = `https://github.com/MasslessAI/push-todo-cli/releases/download/v${VERSION}/${BINARY_NAME}-darwin-x64`;
51
52
 
52
53
  /**
53
54
  * Set up Claude Code plugin by creating symlink.