group-chat-mcp 0.1.6 → 0.2.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/CHANGELOG.md +18 -0
- package/README.md +10 -0
- package/STEPS.md +23 -27
- package/dist/__tests__/install-metadata-service.test.d.ts +2 -0
- package/dist/__tests__/install-metadata-service.test.d.ts.map +1 -0
- package/dist/__tests__/install-metadata-service.test.js +80 -0
- package/dist/__tests__/install-metadata-service.test.js.map +1 -0
- package/dist/__tests__/update-notice.test.d.ts +2 -0
- package/dist/__tests__/update-notice.test.d.ts.map +1 -0
- package/dist/__tests__/update-notice.test.js +122 -0
- package/dist/__tests__/update-notice.test.js.map +1 -0
- package/dist/__tests__/update-service.test.d.ts +2 -0
- package/dist/__tests__/update-service.test.d.ts.map +1 -0
- package/dist/__tests__/update-service.test.js +93 -0
- package/dist/__tests__/update-service.test.js.map +1 -0
- package/dist/__tests__/version-check-service.test.d.ts +2 -0
- package/dist/__tests__/version-check-service.test.d.ts.map +1 -0
- package/dist/__tests__/version-check-service.test.js +103 -0
- package/dist/__tests__/version-check-service.test.js.map +1 -0
- package/dist/constants/storage.d.ts +4 -0
- package/dist/constants/storage.d.ts.map +1 -1
- package/dist/constants/storage.js +4 -0
- package/dist/constants/storage.js.map +1 -1
- package/dist/gchat.d.ts +1 -0
- package/dist/gchat.d.ts.map +1 -1
- package/dist/gchat.js +34 -2
- package/dist/gchat.js.map +1 -1
- package/dist/services/install-metadata-service.d.ts +15 -0
- package/dist/services/install-metadata-service.d.ts.map +1 -0
- package/dist/services/install-metadata-service.js +59 -0
- package/dist/services/install-metadata-service.js.map +1 -0
- package/dist/services/installer-service.d.ts +3 -0
- package/dist/services/installer-service.d.ts.map +1 -1
- package/dist/services/installer-service.js +55 -46
- package/dist/services/installer-service.js.map +1 -1
- package/dist/services/update-service.d.ts +13 -0
- package/dist/services/update-service.d.ts.map +1 -0
- package/dist/services/update-service.js +76 -0
- package/dist/services/update-service.js.map +1 -0
- package/dist/services/version-check-service.d.ts +12 -0
- package/dist/services/version-check-service.d.ts.map +1 -0
- package/dist/services/version-check-service.js +109 -0
- package/dist/services/version-check-service.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/parsed-command.d.ts +4 -0
- package/dist/types/parsed-command.d.ts.map +1 -1
- package/dist/types/version-check-result.d.ts +6 -0
- package/dist/types/version-check-result.d.ts.map +1 -0
- package/dist/types/version-check-result.js +2 -0
- package/dist/types/version-check-result.js.map +1 -0
- package/dist/utils/update-utils.d.ts +2 -0
- package/dist/utils/update-utils.d.ts.map +1 -0
- package/dist/utils/update-utils.js +4 -0
- package/dist/utils/update-utils.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2026-03-24
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `gchat update` command: checks npm registry for the latest version, runs `npm install -g group-chat-mcp@latest`, and re-execs the new binary to refresh all previously installed IDE configurations
|
|
13
|
+
- Passive update notice on interactive commands (`install`, `uninstall`) when a newer npm version exists
|
|
14
|
+
- `InstallMetadataService` persists IDE+scope combos during install/uninstall so `gchat update` knows what to refresh
|
|
15
|
+
- `VersionCheckService` with 24h file-cached npm registry queries and semver comparison
|
|
16
|
+
- `formatUpdateNotice` utility for the update available message
|
|
17
|
+
- `update` and `update-post-install` command variants in `ParsedCommand`
|
|
18
|
+
- Unit and integration tests for all new services and update notice behavior
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `InstallerService` accepts `InstallMetadataService` via constructor parameter (dependency injection)
|
|
23
|
+
- `main()` exported from `gchat.ts` for testability
|
|
24
|
+
- Help text updated with `update` command
|
|
25
|
+
|
|
8
26
|
## [0.1.6] - 2026-03-23
|
|
9
27
|
|
|
10
28
|
### Added
|
package/README.md
CHANGED
|
@@ -15,6 +15,8 @@ Multi-agent communication server using the Model Context Protocol. Enables AI ag
|
|
|
15
15
|
- Pull-based inbox for clients without push notification support (`read_notifications`)
|
|
16
16
|
- File-based shared state with atomic locking
|
|
17
17
|
- Zero-config setup via `gchat install`
|
|
18
|
+
- Built-in update command (`gchat update`) with automatic IDE config refresh
|
|
19
|
+
- Passive update notices on interactive commands when a newer version is available
|
|
18
20
|
|
|
19
21
|
## Installation
|
|
20
22
|
|
|
@@ -48,6 +50,14 @@ The installer prompts for:
|
|
|
48
50
|
|
|
49
51
|
For Claude Code, the installer registers the MCP server via `claude mcp add` (requires the Claude Code CLI on PATH). For Cursor, it writes `mcp.json` with the server entry and `hooks.json` with session lifecycle hooks that register and unregister agents per chat session.
|
|
50
52
|
|
|
53
|
+
To update to the latest version:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
gchat update
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This checks the npm registry, installs the latest version, and refreshes all previously configured IDE setups. Interactive commands (`install`, `uninstall`) also display an update notice when a newer version is available.
|
|
60
|
+
|
|
51
61
|
To remove the configuration:
|
|
52
62
|
|
|
53
63
|
```bash
|
package/STEPS.md
CHANGED
|
@@ -1,43 +1,39 @@
|
|
|
1
1
|
# End Goal
|
|
2
2
|
|
|
3
|
-
Add
|
|
3
|
+
Add manual and automatic update capabilities to the `gchat` CLI, allowing users to update the globally installed `group-chat-mcp` npm package on demand and be notified (or auto-updated) when a newer version is available.
|
|
4
4
|
|
|
5
5
|
## Steps
|
|
6
6
|
|
|
7
|
-
- [ ]
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- [ ]
|
|
11
|
-
- [ ] On lock contention: wait internally (poll) until the competing message lands
|
|
12
|
-
- [ ] On lock release: read the latest message(s) from the conversation file that arrived while waiting, return them with strict instructions to read, reconsider the original intent, and resend (do NOT echo the blocked agent's original message)
|
|
13
|
-
- [ ] On timeout: break the stale lock and proceed with the blocked agent's send normally
|
|
14
|
-
- [ ] Handle lock cleanup on agent disconnect/crash to prevent deadlocks
|
|
7
|
+
- [ ] Persist install metadata during `gchat install` so `gchat update` knows which IDE+scope combos to refresh
|
|
8
|
+
- [ ] Add a version check mechanism that queries the npm registry for the latest published version, compares it to the locally installed version, and caches the result for 24 hours
|
|
9
|
+
- [ ] Integrate the version check into interactive CLI commands (install, uninstall, update) to display an update notice when a newer version is available
|
|
10
|
+
- [ ] Add a `gchat update` command that updates the globally installed package, then re-execs the new binary to refresh configs for all persisted IDE+scope combos
|
|
15
11
|
|
|
16
12
|
## Questions Answered
|
|
17
13
|
|
|
18
|
-
1. Q:
|
|
19
|
-
A:
|
|
14
|
+
1. Q: What should "automatic update" mean for gchat?
|
|
15
|
+
A: Notify only. On CLI invocation, check the npm registry in the background. If a newer version exists, print an update notice. No mutation without explicit user action via `gchat update`.
|
|
20
16
|
|
|
21
|
-
2. Q: Should the
|
|
22
|
-
A:
|
|
17
|
+
2. Q: Should the update notice appear on all commands or only interactive ones?
|
|
18
|
+
A: Interactive commands only (install, uninstall, update). Hook commands (cursor-join, cursor-leave) output JSON and must stay clean.
|
|
23
19
|
|
|
24
|
-
3. Q: Should the
|
|
25
|
-
A: Yes.
|
|
20
|
+
3. Q: Should the version check result be cached?
|
|
21
|
+
A: Yes. Cache for 24 hours in a local file. Skip the registry call if checked within that window.
|
|
26
22
|
|
|
27
|
-
4. Q:
|
|
28
|
-
A:
|
|
23
|
+
4. Q: Should `gchat update` support targeting a specific version?
|
|
24
|
+
A: No. Always install the latest published version.
|
|
29
25
|
|
|
30
|
-
5. Q:
|
|
31
|
-
A:
|
|
26
|
+
5. Q: Should `gchat update` re-run the installer after updating?
|
|
27
|
+
A: No full reinstall. After updating the npm package, detect which IDE configurations exist and apply incremental config patches (new files, updated files) without requiring the user to re-run `gchat install`.
|
|
32
28
|
|
|
33
|
-
6. Q:
|
|
34
|
-
A:
|
|
29
|
+
6. Q: How should config patching work?
|
|
30
|
+
A: Re-apply the current version's installer logic for all managed IDE+scope combos. The installer's merge logic is already idempotent — it updates existing entries without clobbering unrelated config.
|
|
35
31
|
|
|
36
|
-
7. Q:
|
|
37
|
-
A:
|
|
32
|
+
7. Q: How should `gchat update` know which IDE+scope combos to refresh?
|
|
33
|
+
A: Persist install choices in a metadata file (e.g. `~/.group-chat-mcp/install-meta.json`) during `gchat install`. `gchat update` reads this file to determine what to refresh.
|
|
38
34
|
|
|
39
|
-
8. Q:
|
|
40
|
-
A:
|
|
35
|
+
8. Q: Should the version check run in parallel with the main command or sequentially before it?
|
|
36
|
+
A: Parallel. Fire the registry check at command start, run the main command, print the update notice (if any) after the command completes. No added latency.
|
|
41
37
|
|
|
42
|
-
9. Q:
|
|
43
|
-
A:
|
|
38
|
+
9. Q: After npm install replaces the binary, should the running (old) process refresh configs or re-exec the new binary?
|
|
39
|
+
A: Re-exec the new binary. After `npm install -g` completes, spawn `gchat update --post-install` using the newly installed binary. The new process runs the new version's installer logic, guaranteeing configs match the new version's expectations.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-metadata-service.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/install-metadata-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import { InstallMetadataService } from '../services/install-metadata-service.js';
|
|
6
|
+
import { IDE } from '../enums/ide.js';
|
|
7
|
+
import { Scope } from '../enums/scope.js';
|
|
8
|
+
let tmpDir;
|
|
9
|
+
let service;
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gchat-meta-test-'));
|
|
12
|
+
service = new InstallMetadataService(tmpDir);
|
|
13
|
+
});
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
16
|
+
});
|
|
17
|
+
describe('InstallMetadataService', () => {
|
|
18
|
+
describe('addInstall', () => {
|
|
19
|
+
it('Given no metadata file exists When addInstall is called with (ClaudeCode, Global) Then the file is created with one entry', async () => {
|
|
20
|
+
await service.addInstall(IDE.ClaudeCode, Scope.Global);
|
|
21
|
+
const raw = await fs.readFile(path.join(tmpDir, 'install-meta.json'), 'utf-8');
|
|
22
|
+
const entries = JSON.parse(raw);
|
|
23
|
+
expect(entries).toEqual([{ ide: 'claudeCode', scope: 'global' }]);
|
|
24
|
+
});
|
|
25
|
+
it('Given a metadata file with (ClaudeCode, Global) When addInstall is called with (Cursor, Local) Then the file contains both entries', async () => {
|
|
26
|
+
await service.addInstall(IDE.ClaudeCode, Scope.Global);
|
|
27
|
+
await service.addInstall(IDE.Cursor, Scope.Local);
|
|
28
|
+
const raw = await fs.readFile(path.join(tmpDir, 'install-meta.json'), 'utf-8');
|
|
29
|
+
const entries = JSON.parse(raw);
|
|
30
|
+
expect(entries).toEqual([
|
|
31
|
+
{ ide: 'claudeCode', scope: 'global' },
|
|
32
|
+
{ ide: 'cursor', scope: 'local' },
|
|
33
|
+
]);
|
|
34
|
+
});
|
|
35
|
+
it('Given a metadata file with (ClaudeCode, Global) When addInstall is called with (ClaudeCode, Global) again Then the file still contains one entry', async () => {
|
|
36
|
+
await service.addInstall(IDE.ClaudeCode, Scope.Global);
|
|
37
|
+
await service.addInstall(IDE.ClaudeCode, Scope.Global);
|
|
38
|
+
const raw = await fs.readFile(path.join(tmpDir, 'install-meta.json'), 'utf-8');
|
|
39
|
+
const entries = JSON.parse(raw);
|
|
40
|
+
expect(entries).toEqual([{ ide: 'claudeCode', scope: 'global' }]);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('removeInstall', () => {
|
|
44
|
+
it('Given a metadata file with one entry When removeInstall is called for that entry Then the file is deleted', async () => {
|
|
45
|
+
await service.addInstall(IDE.ClaudeCode, Scope.Global);
|
|
46
|
+
await service.removeInstall(IDE.ClaudeCode, Scope.Global);
|
|
47
|
+
const exists = await fs.access(path.join(tmpDir, 'install-meta.json')).then(() => true).catch(() => false);
|
|
48
|
+
expect(exists).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
it('Given a metadata file with two entries When removeInstall is called for one Then the file contains the other entry', async () => {
|
|
51
|
+
await service.addInstall(IDE.ClaudeCode, Scope.Global);
|
|
52
|
+
await service.addInstall(IDE.Cursor, Scope.Local);
|
|
53
|
+
await service.removeInstall(IDE.ClaudeCode, Scope.Global);
|
|
54
|
+
const raw = await fs.readFile(path.join(tmpDir, 'install-meta.json'), 'utf-8');
|
|
55
|
+
const entries = JSON.parse(raw);
|
|
56
|
+
expect(entries).toEqual([{ ide: 'cursor', scope: 'local' }]);
|
|
57
|
+
});
|
|
58
|
+
it('Given no metadata file exists When removeInstall is called Then no error is thrown', async () => {
|
|
59
|
+
await expect(service.removeInstall(IDE.ClaudeCode, Scope.Global)).resolves.toBeUndefined();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('getInstalls', () => {
|
|
63
|
+
it('Given no metadata file exists When getInstalls is called Then an empty array is returned', async () => {
|
|
64
|
+
const installs = await service.getInstalls();
|
|
65
|
+
expect(installs).toEqual([]);
|
|
66
|
+
});
|
|
67
|
+
it('Given a metadata file with malformed entries When getInstalls is called Then only valid entries are returned', async () => {
|
|
68
|
+
const metadataPath = path.join(tmpDir, 'install-meta.json');
|
|
69
|
+
await fs.writeFile(metadataPath, JSON.stringify([42, null, { ide: 123 }, { ide: 'claudeCode', scope: 'global' }]), 'utf-8');
|
|
70
|
+
const result = await service.getInstalls();
|
|
71
|
+
expect(result).toEqual([{ ide: 'claudeCode', scope: 'global' }]);
|
|
72
|
+
});
|
|
73
|
+
it('Given a corrupt metadata file When getInstalls is called Then an empty array is returned', async () => {
|
|
74
|
+
await fs.writeFile(path.join(tmpDir, 'install-meta.json'), '{not valid json!!!', 'utf-8');
|
|
75
|
+
const installs = await service.getInstalls();
|
|
76
|
+
expect(installs).toEqual([]);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=install-metadata-service.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-metadata-service.test.js","sourceRoot":"","sources":["../../src/__tests__/install-metadata-service.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-notice.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/update-notice.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { formatUpdateNotice } from '../utils/update-utils.js';
|
|
3
|
+
import { IDE } from '../enums/ide.js';
|
|
4
|
+
import { Scope } from '../enums/scope.js';
|
|
5
|
+
const { mockCheckForUpdate, mockSelectIDE, mockSelectScope, mockClose, mockInstall, mockClaudeCodeScope, mockInit, mockReapStaleAgents, mockRegisterAgent, mockGetOrCreateProjectConversation, mockJoinConversation, mockGetConversation, mockWriteSessionAgent, } = vi.hoisted(() => ({
|
|
6
|
+
mockCheckForUpdate: vi.fn(),
|
|
7
|
+
mockSelectIDE: vi.fn(),
|
|
8
|
+
mockSelectScope: vi.fn(),
|
|
9
|
+
mockClose: vi.fn(),
|
|
10
|
+
mockInstall: vi.fn(),
|
|
11
|
+
mockClaudeCodeScope: vi.fn().mockReturnValue('global'),
|
|
12
|
+
mockInit: vi.fn(),
|
|
13
|
+
mockReapStaleAgents: vi.fn(),
|
|
14
|
+
mockRegisterAgent: vi.fn().mockResolvedValue({ id: 'agent-1', profile: { name: 'test' }, conversations: [] }),
|
|
15
|
+
mockGetOrCreateProjectConversation: vi.fn().mockResolvedValue({ id: 'conv-1', participants: [] }),
|
|
16
|
+
mockJoinConversation: vi.fn(),
|
|
17
|
+
mockGetConversation: vi.fn().mockResolvedValue({ id: 'conv-1', participants: ['agent-1'] }),
|
|
18
|
+
mockWriteSessionAgent: vi.fn(),
|
|
19
|
+
}));
|
|
20
|
+
vi.mock('../services/version-check-service.js', () => {
|
|
21
|
+
return {
|
|
22
|
+
VersionCheckService: vi.fn(function () {
|
|
23
|
+
this.checkForUpdate = mockCheckForUpdate;
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
vi.mock('../utils/prompt-utils.js', () => {
|
|
28
|
+
return {
|
|
29
|
+
PromptUtils: vi.fn(function () {
|
|
30
|
+
this.selectIDE = mockSelectIDE;
|
|
31
|
+
this.selectScope = mockSelectScope;
|
|
32
|
+
this.close = mockClose;
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
vi.mock('../services/installer-service.js', () => {
|
|
37
|
+
return {
|
|
38
|
+
InstallerService: vi.fn(function () {
|
|
39
|
+
this.install = mockInstall;
|
|
40
|
+
this.uninstall = vi.fn();
|
|
41
|
+
this.claudeCodeScope = mockClaudeCodeScope;
|
|
42
|
+
this.resolveSettingsPath = vi.fn().mockReturnValue('/tmp/settings.json');
|
|
43
|
+
}),
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
vi.mock('../services/state-service.js', () => {
|
|
47
|
+
return {
|
|
48
|
+
StateService: vi.fn(function () {
|
|
49
|
+
this.init = mockInit;
|
|
50
|
+
this.reapStaleAgents = mockReapStaleAgents;
|
|
51
|
+
this.registerAgent = mockRegisterAgent;
|
|
52
|
+
this.getOrCreateProjectConversation = mockGetOrCreateProjectConversation;
|
|
53
|
+
this.joinConversation = mockJoinConversation;
|
|
54
|
+
this.getConversation = mockGetConversation;
|
|
55
|
+
}),
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
vi.mock('../services/session-state-service.js', () => {
|
|
59
|
+
return {
|
|
60
|
+
SessionStateService: vi.fn(function () {
|
|
61
|
+
this.writeSessionAgent = mockWriteSessionAgent;
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
vi.mock('../utils/notification-utils.js', () => {
|
|
66
|
+
return {
|
|
67
|
+
writeNotificationToParticipants: vi.fn(),
|
|
68
|
+
writeProfileSetupNotification: vi.fn(),
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
describe('formatUpdateNotice', () => {
|
|
72
|
+
it('Given ("0.1.6", "0.2.0") When called Then it returns the formatted update notice string', () => {
|
|
73
|
+
const result = formatUpdateNotice('0.1.6', '0.2.0');
|
|
74
|
+
expect(result).toBe('\nUpdate available: 0.1.6 → 0.2.0. Run `gchat update` to install.\n');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('update notice behavior', () => {
|
|
78
|
+
let errorSpy;
|
|
79
|
+
let logSpy;
|
|
80
|
+
let originalArgv;
|
|
81
|
+
beforeEach(() => {
|
|
82
|
+
originalArgv = process.argv;
|
|
83
|
+
process.argv = ['node', 'gchat.js', 'install'];
|
|
84
|
+
mockSelectIDE.mockResolvedValue([IDE.ClaudeCode]);
|
|
85
|
+
mockSelectScope.mockResolvedValue(Scope.Global);
|
|
86
|
+
mockInstall.mockResolvedValue(undefined);
|
|
87
|
+
errorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
88
|
+
logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
89
|
+
});
|
|
90
|
+
afterEach(() => {
|
|
91
|
+
process.argv = originalArgv;
|
|
92
|
+
errorSpy.mockRestore();
|
|
93
|
+
logSpy.mockRestore();
|
|
94
|
+
vi.clearAllMocks();
|
|
95
|
+
});
|
|
96
|
+
it('Given VersionCheckService returns null When an interactive command completes Then no notice is printed', async () => {
|
|
97
|
+
mockCheckForUpdate.mockResolvedValue(null);
|
|
98
|
+
const { main } = await import('../gchat.js');
|
|
99
|
+
await main();
|
|
100
|
+
expect(errorSpy).not.toHaveBeenCalled();
|
|
101
|
+
});
|
|
102
|
+
it('Given VersionCheckService returns updateAvailable: true When an interactive command completes Then the update notice is printed', async () => {
|
|
103
|
+
mockCheckForUpdate.mockResolvedValue({ current: '0.1.6', latest: '0.2.0', updateAvailable: true });
|
|
104
|
+
const { main } = await import('../gchat.js');
|
|
105
|
+
await main();
|
|
106
|
+
expect(errorSpy).toHaveBeenCalledWith(formatUpdateNotice('0.1.6', '0.2.0'));
|
|
107
|
+
});
|
|
108
|
+
it('Given VersionCheckService returns updateAvailable: false When an interactive command completes Then no notice is printed', async () => {
|
|
109
|
+
mockCheckForUpdate.mockResolvedValue({ current: '0.2.0', latest: '0.2.0', updateAvailable: false });
|
|
110
|
+
const { main } = await import('../gchat.js');
|
|
111
|
+
await main();
|
|
112
|
+
expect(errorSpy).not.toHaveBeenCalled();
|
|
113
|
+
});
|
|
114
|
+
it('Given a hook command (cursor-join) is executed Then the version check is not fired', async () => {
|
|
115
|
+
vi.clearAllMocks();
|
|
116
|
+
process.argv = ['node', 'gchat.js', 'cursor-join', '--project', '/tmp/test', '--server-pid', '1234'];
|
|
117
|
+
const { main } = await import('../gchat.js');
|
|
118
|
+
await main();
|
|
119
|
+
expect(mockCheckForUpdate).not.toHaveBeenCalled();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=update-notice.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-notice.test.js","sourceRoot":"","sources":["../../src/__tests__/update-notice.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,MAAM,EACJ,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,QAAQ,EACR,mBAAmB,EACnB,iBAAiB,EACjB,kCAAkC,EAClC,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,GACtB,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpB,kBAAkB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC3B,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;IACtB,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE;IACxB,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;IAClB,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE;IACpB,mBAAmB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC;IACtD,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;IACjB,mBAAmB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC5B,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;IAC7G,kCAAkC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IACjG,oBAAoB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC7B,mBAAmB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;IAC3F,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE;CAC/B,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACnD,OAAO;QACL,mBAAmB,EAAE,EAAE,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,kBAAkB,CAAC;QAC3C,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACvC,OAAO;QACL,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,SAAS,GAAG,aAAa,CAAC;YAC/B,IAAI,CAAC,WAAW,GAAG,eAAe,CAAC;YACnC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACzB,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAC/C,OAAO;QACL,gBAAgB,EAAE,EAAE,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC;YAC3B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACzB,IAAI,CAAC,eAAe,GAAG,mBAAmB,CAAC;YAC3C,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;QAC3E,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC3C,OAAO;QACL,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;YACrB,IAAI,CAAC,eAAe,GAAG,mBAAmB,CAAC;YAC3C,IAAI,CAAC,aAAa,GAAG,iBAAiB,CAAC;YACvC,IAAI,CAAC,8BAA8B,GAAG,kCAAkC,CAAC;YACzE,IAAI,CAAC,gBAAgB,GAAG,oBAAoB,CAAC;YAC7C,IAAI,CAAC,eAAe,GAAG,mBAAmB,CAAC;QAC7C,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACnD,OAAO;QACL,mBAAmB,EAAE,EAAE,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,iBAAiB,GAAG,qBAAqB,CAAC;QACjD,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC7C,OAAO;QACL,+BAA+B,EAAE,EAAE,CAAC,EAAE,EAAE;QACxC,6BAA6B,EAAE,EAAE,CAAC,EAAE,EAAE;KACvC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,yFAAyF,EAAE,GAAG,EAAE;QACjG,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAI,QAAqC,CAAC;IAC1C,IAAI,MAAmC,CAAC;IACxC,IAAI,YAAsB,CAAC;IAE3B,UAAU,CAAC,GAAG,EAAE;QACd,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;QAC5B,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,aAAa,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QAClD,eAAe,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChD,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACzC,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACnE,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;QAC5B,QAAQ,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,CAAC,WAAW,EAAE,CAAC;QACrB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wGAAwG,EAAE,KAAK,IAAI,EAAE;QACtH,kBAAkB,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,IAAI,EAAE,CAAC;QACb,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iIAAiI,EAAE,KAAK,IAAI,EAAE;QAC/I,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;QACnG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,IAAI,EAAE,CAAC;QACb,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0HAA0H,EAAE,KAAK,IAAI,EAAE;QACxI,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACpG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,IAAI,EAAE,CAAC;QACb,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,KAAK,IAAI,EAAE;QAClG,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;QACrG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,IAAI,EAAE,CAAC;QACb,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-service.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/update-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import { parseCommand } from '../gchat.js';
|
|
4
|
+
import { UpdateService } from '../services/update-service.js';
|
|
5
|
+
import { IDE } from '../enums/ide.js';
|
|
6
|
+
import { Scope } from '../enums/scope.js';
|
|
7
|
+
vi.mock('node:child_process', () => ({
|
|
8
|
+
execFileSync: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
describe('parseCommand', () => {
|
|
11
|
+
it('Given args ["update"] When parseCommand is called Then it returns { command: "update" }', () => {
|
|
12
|
+
const result = parseCommand(['update']);
|
|
13
|
+
expect(result).toEqual({ command: 'update' });
|
|
14
|
+
});
|
|
15
|
+
it('Given args ["update", "--post-install"] When parseCommand is called Then it returns { command: "update-post-install" }', () => {
|
|
16
|
+
const result = parseCommand(['update', '--post-install']);
|
|
17
|
+
expect(result).toEqual({ command: 'update-post-install' });
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe('UpdateService', () => {
|
|
21
|
+
let mockVersionCheck;
|
|
22
|
+
let mockInstallMetadata;
|
|
23
|
+
let mockInstaller;
|
|
24
|
+
let updateService;
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
mockVersionCheck = {
|
|
27
|
+
checkForUpdate: vi.fn(),
|
|
28
|
+
getLocalVersion: vi.fn().mockReturnValue('0.2.0'),
|
|
29
|
+
};
|
|
30
|
+
mockInstallMetadata = {
|
|
31
|
+
getInstalls: vi.fn(),
|
|
32
|
+
};
|
|
33
|
+
mockInstaller = {
|
|
34
|
+
install: vi.fn(),
|
|
35
|
+
};
|
|
36
|
+
updateService = new UpdateService(mockVersionCheck, mockInstallMetadata, mockInstaller);
|
|
37
|
+
});
|
|
38
|
+
describe('performUpdate', () => {
|
|
39
|
+
it('Given checkForUpdate returns updateAvailable: false When performUpdate is called Then it prints "Already up to date" and does not run npm install', async () => {
|
|
40
|
+
mockVersionCheck.checkForUpdate.mockResolvedValue({
|
|
41
|
+
current: '0.2.0', latest: '0.2.0', updateAvailable: false,
|
|
42
|
+
});
|
|
43
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
44
|
+
await updateService.performUpdate();
|
|
45
|
+
expect(logSpy).toHaveBeenCalledWith('Already up to date (0.2.0)');
|
|
46
|
+
logSpy.mockRestore();
|
|
47
|
+
});
|
|
48
|
+
it('Given checkForUpdate returns updateAvailable: true When performUpdate is called Then it runs npm install and re-execs gchat', async () => {
|
|
49
|
+
mockVersionCheck.checkForUpdate.mockResolvedValue({
|
|
50
|
+
current: '0.1.6', latest: '0.2.0', updateAvailable: true,
|
|
51
|
+
});
|
|
52
|
+
const mockedExecFileSync = vi.mocked(execFileSync);
|
|
53
|
+
mockedExecFileSync.mockImplementation((file, args) => {
|
|
54
|
+
if (file === 'which')
|
|
55
|
+
return '/usr/local/bin/gchat';
|
|
56
|
+
return '';
|
|
57
|
+
});
|
|
58
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
59
|
+
await updateService.performUpdate();
|
|
60
|
+
expect(logSpy).toHaveBeenCalledWith('Updating group-chat-mcp 0.1.6 → 0.2.0...');
|
|
61
|
+
expect(mockedExecFileSync).toHaveBeenCalledWith('npm', ['install', '-g', 'group-chat-mcp@latest'], { stdio: 'inherit' });
|
|
62
|
+
expect(mockedExecFileSync).toHaveBeenCalledWith('/usr/local/bin/gchat', ['update', '--post-install'], { stdio: 'inherit' });
|
|
63
|
+
logSpy.mockRestore();
|
|
64
|
+
});
|
|
65
|
+
it('Given checkForUpdate returns null When performUpdate is called Then it throws an error', async () => {
|
|
66
|
+
mockVersionCheck.checkForUpdate.mockResolvedValue(null);
|
|
67
|
+
await expect(updateService.performUpdate()).rejects.toThrow('Failed to check for updates. Please try again later.');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('performPostInstall', () => {
|
|
71
|
+
it('Given install metadata has entries When performPostInstall is called Then it calls InstallerService.install for each entry', async () => {
|
|
72
|
+
mockInstallMetadata.getInstalls.mockResolvedValue([
|
|
73
|
+
{ ide: IDE.ClaudeCode, scope: Scope.Global },
|
|
74
|
+
{ ide: IDE.Cursor, scope: Scope.Local },
|
|
75
|
+
]);
|
|
76
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
77
|
+
await updateService.performPostInstall();
|
|
78
|
+
expect(mockInstaller.install).toHaveBeenCalledTimes(2);
|
|
79
|
+
expect(mockInstaller.install).toHaveBeenCalledWith({ ide: IDE.ClaudeCode, scope: Scope.Global });
|
|
80
|
+
expect(mockInstaller.install).toHaveBeenCalledWith({ ide: IDE.Cursor, scope: Scope.Local });
|
|
81
|
+
logSpy.mockRestore();
|
|
82
|
+
});
|
|
83
|
+
it('Given install metadata is empty When performPostInstall is called Then it prints "No install metadata found" and does not call InstallerService.install', async () => {
|
|
84
|
+
mockInstallMetadata.getInstalls.mockResolvedValue([]);
|
|
85
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
86
|
+
await updateService.performPostInstall();
|
|
87
|
+
expect(logSpy).toHaveBeenCalledWith('No install metadata found. Run `gchat install` to configure your IDE.');
|
|
88
|
+
expect(mockInstaller.install).not.toHaveBeenCalled();
|
|
89
|
+
logSpy.mockRestore();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=update-service.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-service.test.js","sourceRoot":"","sources":["../../src/__tests__/update-service.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-check-service.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/version-check-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import { VersionCheckService } from '../services/version-check-service.js';
|
|
6
|
+
import { VERSION_CHECK_FILE } from '../constants/storage.js';
|
|
7
|
+
let tmpDir;
|
|
8
|
+
let service;
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gchat-version-check-test-'));
|
|
11
|
+
service = new VersionCheckService(tmpDir);
|
|
12
|
+
vi.spyOn(VersionCheckService.prototype, 'getLocalVersion').mockReturnValue('0.1.6');
|
|
13
|
+
});
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
vi.restoreAllMocks();
|
|
16
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
17
|
+
});
|
|
18
|
+
describe('VersionCheckService', () => {
|
|
19
|
+
describe('getLocalVersion', () => {
|
|
20
|
+
it('Given the package.json exists When getLocalVersion is called Then it returns a valid semver string', () => {
|
|
21
|
+
vi.restoreAllMocks();
|
|
22
|
+
const svc = new VersionCheckService(tmpDir);
|
|
23
|
+
const version = svc.getLocalVersion();
|
|
24
|
+
expect(version).toMatch(/^\d+\.\d+\.\d+/);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('checkForUpdate', () => {
|
|
28
|
+
it('Given a fresh cache with latest "0.2.0" and local version "0.1.6" When checkForUpdate is called Then it returns updateAvailable true without hitting the registry', async () => {
|
|
29
|
+
const cachePath = path.join(tmpDir, VERSION_CHECK_FILE);
|
|
30
|
+
await fs.writeFile(cachePath, JSON.stringify({ latest: '0.2.0', checkedAt: Date.now() }), 'utf-8');
|
|
31
|
+
const fetchSpy = vi.spyOn(service, 'fetchLatestVersion');
|
|
32
|
+
const result = await service.checkForUpdate();
|
|
33
|
+
expect(result).toEqual({
|
|
34
|
+
current: '0.1.6',
|
|
35
|
+
latest: '0.2.0',
|
|
36
|
+
updateAvailable: true,
|
|
37
|
+
});
|
|
38
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
39
|
+
});
|
|
40
|
+
it('Given a fresh cache with latest "0.1.6" and local version "0.1.6" When checkForUpdate is called Then it returns updateAvailable false', async () => {
|
|
41
|
+
const cachePath = path.join(tmpDir, VERSION_CHECK_FILE);
|
|
42
|
+
await fs.writeFile(cachePath, JSON.stringify({ latest: '0.1.6', checkedAt: Date.now() }), 'utf-8');
|
|
43
|
+
const result = await service.checkForUpdate();
|
|
44
|
+
expect(result).toEqual({
|
|
45
|
+
current: '0.1.6',
|
|
46
|
+
latest: '0.1.6',
|
|
47
|
+
updateAvailable: false,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
it('Given an expired cache When checkForUpdate is called Then it queries the registry and writes a new cache', async () => {
|
|
51
|
+
const cachePath = path.join(tmpDir, VERSION_CHECK_FILE);
|
|
52
|
+
const expiredTime = Date.now() - 86_400_000 - 1;
|
|
53
|
+
await fs.writeFile(cachePath, JSON.stringify({ latest: '0.1.5', checkedAt: expiredTime }), 'utf-8');
|
|
54
|
+
vi.spyOn(service, 'fetchLatestVersion').mockResolvedValue('0.2.0');
|
|
55
|
+
const result = await service.checkForUpdate();
|
|
56
|
+
expect(result).toEqual({
|
|
57
|
+
current: '0.1.6',
|
|
58
|
+
latest: '0.2.0',
|
|
59
|
+
updateAvailable: true,
|
|
60
|
+
});
|
|
61
|
+
const raw = await fs.readFile(cachePath, 'utf-8');
|
|
62
|
+
const cached = JSON.parse(raw);
|
|
63
|
+
expect(cached.latest).toBe('0.2.0');
|
|
64
|
+
});
|
|
65
|
+
it('Given no cache file When checkForUpdate is called Then it queries the registry and writes a new cache', async () => {
|
|
66
|
+
vi.spyOn(service, 'fetchLatestVersion').mockResolvedValue('0.2.0');
|
|
67
|
+
const result = await service.checkForUpdate();
|
|
68
|
+
expect(result).toEqual({
|
|
69
|
+
current: '0.1.6',
|
|
70
|
+
latest: '0.2.0',
|
|
71
|
+
updateAvailable: true,
|
|
72
|
+
});
|
|
73
|
+
const cachePath = path.join(tmpDir, VERSION_CHECK_FILE);
|
|
74
|
+
const raw = await fs.readFile(cachePath, 'utf-8');
|
|
75
|
+
const cached = JSON.parse(raw);
|
|
76
|
+
expect(cached.latest).toBe('0.2.0');
|
|
77
|
+
});
|
|
78
|
+
it('Given the npm registry is unreachable and no cache exists When checkForUpdate is called Then it returns null', async () => {
|
|
79
|
+
vi.spyOn(service, 'fetchLatestVersion').mockResolvedValue(null);
|
|
80
|
+
const result = await service.checkForUpdate();
|
|
81
|
+
expect(result).toBeNull();
|
|
82
|
+
});
|
|
83
|
+
it('Given a corrupt cache file When checkForUpdate is called Then it queries the registry', async () => {
|
|
84
|
+
const cachePath = path.join(tmpDir, VERSION_CHECK_FILE);
|
|
85
|
+
await fs.writeFile(cachePath, 'not-json!!!', 'utf-8');
|
|
86
|
+
vi.spyOn(service, 'fetchLatestVersion').mockResolvedValue('0.2.0');
|
|
87
|
+
const result = await service.checkForUpdate();
|
|
88
|
+
expect(result).toEqual({
|
|
89
|
+
current: '0.1.6',
|
|
90
|
+
latest: '0.2.0',
|
|
91
|
+
updateAvailable: true,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
it('Given getLocalVersion throws When checkForUpdate is called Then it returns null', async () => {
|
|
95
|
+
vi.spyOn(VersionCheckService.prototype, 'getLocalVersion').mockImplementation(() => {
|
|
96
|
+
throw new Error('cannot read package.json');
|
|
97
|
+
});
|
|
98
|
+
const result = await service.checkForUpdate();
|
|
99
|
+
expect(result).toBeNull();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=version-check-service.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-check-service.test.js","sourceRoot":"","sources":["../../src/__tests__/version-check-service.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,4 +4,8 @@ export declare const CONVERSATIONS_FILE = "conversations.json";
|
|
|
4
4
|
export declare const MESSAGES_DIR = "messages";
|
|
5
5
|
export declare const INBOXES_DIR = "inboxes";
|
|
6
6
|
export declare const SESSIONS_DIR = "sessions";
|
|
7
|
+
export declare const INSTALL_META_FILE = "install-meta.json";
|
|
8
|
+
export declare const VERSION_CHECK_FILE = "version-check.json";
|
|
9
|
+
export declare const VERSION_CHECK_TTL_MS = 86400000;
|
|
10
|
+
export declare const NPM_REGISTRY_TIMEOUT_MS = 3000;
|
|
7
11
|
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/constants/storage.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,QAA6C,CAAC;AACnE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,YAAY,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/constants/storage.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,QAA6C,CAAC;AACnE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,oBAAoB,WAAa,CAAC;AAC/C,eAAO,MAAM,uBAAuB,OAAQ,CAAC"}
|