@genspark/cli 1.0.12 → 1.0.13

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  **One CLI. Every AI capability.** Search, generate, analyze, communicate — all from your terminal.
4
4
 
5
- `gsk` is the command-line interface for the [Genspark](https://www.genspark.ai) AI platform. It unifies **30+ AI tools** behind a single binary: web search, image/video/audio generation with 40+ models, document analysis, media transcription, cloud file management, email, calendar, AI phone calls, stock data, social media data (Twitter, Instagram, Reddit), and autonomous AI agents — all with clean JSON output for seamless integration with AI coding assistants, automation pipelines, and scripts.
5
+ `gsk` is the command-line interface for the [Genspark](https://www.genspark.ai) AI platform. It unifies **90+ AI tools** behind a single binary: web search, image/video/audio generation with 40+ models, document analysis, media transcription, cloud file management, email (Gmail & Outlook), calendar, GitHub, Slack, Notion, Microsoft Teams, OneDrive, SharePoint, AI phone calls, stock data, social media data (Twitter, Instagram, Reddit), and autonomous AI agents — all with clean JSON output for seamless integration with AI coding assistants, automation pipelines, and scripts.
6
6
 
7
7
  ### Capability Map
8
8
 
@@ -16,8 +16,11 @@
16
16
  | 🧠 **Analysis** | Image/video/audio understanding, OCR, video style replication |
17
17
  | 📝 **Transcribe** | Whisper, Gemini, ElevenLabs Scribe |
18
18
  | ☁️ **AI Drive** | Cloud file storage, download, compress |
19
- | 📧 **Email** | Gmail & Outlook: read, search, send |
20
- | 📅 **Calendar** | Google & Outlook: list, create events |
19
+ | 📧 **Email** | Gmail & Outlook: read, search, send, reply, forward, archive, labels, attachments |
20
+ | 📅 **Calendar** | Google & Outlook: list, create, delete events |
21
+ | 💬 **Collaboration** | Slack, Microsoft Teams, Notion — send messages, search, manage channels/pages |
22
+ | 📂 **Cloud Storage** | Google Drive, OneDrive, SharePoint, Google Sheets, Google Docs, Google Contacts |
23
+ | 🐙 **GitHub** | List repos, search/create/update issues |
21
24
  | 📞 **Phone** | AI-powered phone calls to businesses |
22
25
  | 📈 **Stocks** | Real-time stock prices |
23
26
  | 📱 **Social Media** | Twitter/X, Instagram, Reddit — search posts/users, get comments, connections, and more (30 APIs) |
@@ -37,8 +40,7 @@
37
40
  - [Media Analysis & Transcription](#media-analysis--transcription)
38
41
  - [AI Drive (Cloud Storage)](#ai-drive-cloud-storage)
39
42
  - [AI Agents & Tasks](#ai-agents--tasks)
40
- - [Email](#email)
41
- - [Calendar](#calendar)
43
+ - [Service-Level Tools](#service-level-tools)
42
44
  - [AI Phone Calls](#ai-phone-calls)
43
45
  - [Stock Prices](#stock-prices)
44
46
  - [Social Media](#social-media)
@@ -503,188 +505,160 @@ gsk stock AAPL
503
505
  gsk stock MSFT
504
506
  ```
505
507
 
506
- ### email
508
+ ### Service-Level Tools
507
509
 
508
- Read and send emails from your connected Gmail or Outlook account.
510
+ External service integrations are available as **service-level tools** each service is a single command with an `action` parameter that dispatches to the underlying operation.
509
511
 
510
- > **Requirements:** Connect Gmail or Outlook in [Genspark Account Settings → Integrations](https://www.genspark.ai/settings/integrations).
512
+ > **Requirements:** Connect services in [Genspark Account Settings → Integrations](https://www.genspark.ai/settings/integrations).
511
513
 
512
- #### email list
514
+ #### gmail
513
515
 
514
- List emails from a folder.
516
+ Gmail operations: search, read, send, reply, forward, delete, archive, move, mark_as_read, add_label, remove_label, create_label, get_attachment, list_send_as.
515
517
 
516
518
  ```bash
517
- # List inbox (default)
518
- gsk email list
519
-
520
- # List sent folder, limit to 5 emails
521
- gsk email list sent -n 5
519
+ gsk gmail search --query "from:boss subject:report"
520
+ gsk gmail read --id 19cbfecd7fb14d46
521
+ gsk gmail send --to user@example.com --subject "Hello" --body "<p>Hi!</p>"
522
+ gsk gmail forward --message_id 19cbfecd7fb14d46 --to colleague@example.com
523
+ gsk gmail archive --message_id 19cbfecd7fb14d46
524
+ ```
522
525
 
523
- # List only unread emails
524
- gsk email list --unread_only
526
+ #### outlook_email
525
527
 
526
- # List emails after a specific date
527
- gsk email list --after_date 2026-03-01
528
+ Outlook Email operations: search, read, send, reply, reply_draft, forward, delete, archive, move, mark_as_read, add_category, remove_category, get_attachment, group_list, group_search, group_read, group_reply.
528
529
 
529
- # Use a specific account (when multiple accounts are connected)
530
- gsk email list -a user@gmail.com
530
+ ```bash
531
+ gsk outlook_email search --queryString "quarterly report"
532
+ gsk outlook_email read --messageId AAMkAG...
533
+ gsk outlook_email send --to user@example.com --subject "Update" --body "Hi!"
531
534
  ```
532
535
 
533
- | Option | Default | Description |
534
- |--------|---------|-------------|
535
- | `[folder]` | `inbox` | Folder: `inbox`, `sent`, `drafts`, `trash`, `spam`, `archive`, or a custom label |
536
- | `-n, --limit <n>` | `20` | Maximum number of emails to return |
537
- | `--unread_only` | `false` | Return only unread emails |
538
- | `--after_date <YYYY-MM-DD>` | — | Return emails after this date |
539
- | `--before_date <YYYY-MM-DD>` | — | Return emails before this date |
540
- | `-a, --from_account <email>` | — | Account email address (for multi-account) |
541
-
542
- #### email read
536
+ #### google_calendar
543
537
 
544
- Read a specific email by ID.
538
+ Google Calendar operations: list, create, delete.
545
539
 
546
540
  ```bash
547
- # Read a specific email (get ID from email list output)
548
- gsk email read 19cbfecd7fb14d46
541
+ gsk google_calendar list
542
+ gsk google_calendar create --summary "Team Sync" --start_time "2026-04-20T10:00:00Z" --end_time "2026-04-20T11:00:00Z"
543
+ ```
549
544
 
550
- # Ask a specific question about the email
551
- gsk email read 19cbfecd7fb14d46 "What action is required?"
545
+ #### outlook_calendar
552
546
 
553
- # Specify account for multi-account setups
554
- gsk email read 19cbfecd7fb14d46 -a user@gmail.com
555
- ```
547
+ Outlook Calendar operations: list, create, delete.
556
548
 
557
- | Option | Default | Description |
558
- |--------|---------|-------------|
559
- | `<id>` | — | Email ID from `email list` or `email search` (**required**) |
560
- | `-a, --from_account <email>` | — | Account email address (for multi-account) |
549
+ ```bash
550
+ gsk outlook_calendar list
551
+ ```
561
552
 
562
- #### email search
553
+ #### meeting
563
554
 
564
- Search emails using a query string.
555
+ Meeting notes operations: list, search, get.
565
556
 
566
557
  ```bash
567
- # Search by subject
568
- gsk email search "meeting agenda"
558
+ gsk meeting list
559
+ gsk meeting search --keyword "quarterly planning"
560
+ gsk meeting get --task_id "e02fd0f1-..."
561
+ ```
569
562
 
570
- # Gmail query syntax
571
- gsk email search "from:boss@company.com subject:budget"
563
+ #### google_drive
572
564
 
573
- # Search with date range
574
- gsk email search "invoice" --after_date 2026-01-01 --before_date 2026-03-01
565
+ Google Drive file operations: search, read, upload.
575
566
 
576
- # Limit results
577
- gsk email search "quarterly report" -n 5
567
+ ```bash
568
+ gsk google_drive search --query "budget 2026"
569
+ gsk google_drive read --file_id 1hq9kH63sc...
578
570
  ```
579
571
 
580
- | Option | Default | Description |
581
- |--------|---------|-------------|
582
- | `<query>` | — | Search query (Gmail GQL or Outlook KQL) (**required**) |
583
- | `-n, --limit <n>` | `20` | Maximum number of results |
584
- | `--after_date <YYYY-MM-DD>` | — | Return emails after this date |
585
- | `--before_date <YYYY-MM-DD>` | — | Return emails before this date |
586
- | `-a, --from_account <email>` | — | Account email address (for multi-account) |
587
-
588
- #### email send
572
+ #### google_sheets
589
573
 
590
- Send a new email.
574
+ Google Sheets operations: create, read, write, append, search, export.
591
575
 
592
576
  ```bash
593
- # Send a plain text email
594
- gsk email send --to recipient@example.com --subject "Hello" --body "Hi there!"
595
-
596
- # Send to multiple recipients
597
- gsk email send --to "alice@example.com,bob@example.com" --subject "Team Update" --body "..."
577
+ gsk google_sheets search --query "sales report"
578
+ gsk google_sheets read --spreadsheet_id 1ABC... --range "Sheet1!A1:D10"
579
+ ```
598
580
 
599
- # Send HTML email
600
- gsk email send --to user@example.com --subject "Newsletter" --body "<h1>Title</h1><p>...</p>" --content_type text/html
581
+ #### google_docs
601
582
 
602
- # Send with CC and BCC
603
- gsk email send --to recipient@example.com --subject "Meeting" --body "..." --cc manager@company.com --bcc archive@company.com
583
+ Google Docs operations: create, read, append, search.
604
584
 
605
- # Send from a specific account
606
- gsk email send --to user@example.com --subject "Hi" --body "..." -a sender@gmail.com
585
+ ```bash
586
+ gsk google_docs search --query "meeting notes"
587
+ gsk google_docs read --document_id 1ABC...
607
588
  ```
608
589
 
609
- | Option | Default | Description |
610
- |--------|---------|-------------|
611
- | `--to <addresses>` | — | Recipient(s), comma-separated (**required**) |
612
- | `--subject <text>` | — | Email subject (**required**) |
613
- | `--body <text>` | — | Email body (**required**) |
614
- | `--cc <addresses>` | — | CC recipient(s), comma-separated |
615
- | `--bcc <addresses>` | — | BCC recipient(s), comma-separated |
616
- | `--content_type <type>` | `text/plain` | Body content type: `text/plain` or `text/html` |
617
- | `-a, --from_account <email>` | — | Account to send from (for multi-account) |
590
+ #### google_contacts
618
591
 
619
- ### calendar
592
+ Google Contacts operations: search, get, create, update.
620
593
 
621
- List and create calendar events from your connected Google Calendar or Outlook account.
594
+ ```bash
595
+ gsk google_contacts search --query "John"
596
+ ```
597
+
598
+ #### github
622
599
 
623
- > **Requirements:** Connect Google Calendar or Outlook in [Genspark Account Settings → Integrations](https://www.genspark.ai/settings/integrations).
600
+ GitHub operations: list_repos, search_issues, create_issue, update_issue.
601
+
602
+ ```bash
603
+ gsk github list_repos
604
+ gsk github search_issues --q "repo:owner/repo is:open label:bug"
605
+ gsk github create_issue --owner myorg --repo myrepo --title "Bug report" --body "Description..."
606
+ ```
624
607
 
625
- #### calendar list
608
+ #### slack
626
609
 
627
- List upcoming calendar events.
610
+ Slack messaging operations: send, search, lookup.
628
611
 
629
612
  ```bash
630
- # List events in the next 7 days (default)
631
- gsk calendar list
613
+ gsk slack search --query "deployment update"
614
+ gsk slack lookup --lookup_type channels --search_query "engineering"
615
+ gsk slack send --recipient "#general" --message "Hello team!"
616
+ ```
632
617
 
633
- # List events in a specific time range
634
- gsk calendar list --time_min 2026-03-10T00:00:00Z --time_max 2026-03-15T23:59:59Z
618
+ #### notion
635
619
 
636
- # Search for events by keyword
637
- gsk calendar list --filter_query "standup"
620
+ Notion page operations: search, read, create.
638
621
 
639
- # Use a specific calendar account
640
- gsk calendar list -a user@gmail.com
622
+ ```bash
623
+ gsk notion search --query "project roadmap"
624
+ gsk notion read --page_id 2ce8b6a5-...
641
625
  ```
642
626
 
643
- | Option | Default | Description |
644
- |--------|---------|-------------|
645
- | `--time_min <ISO8601>` | now | Start of time range (e.g., `2026-03-10T00:00:00Z`) |
646
- | `--time_max <ISO8601>` | +7 days | End of time range |
647
- | `--filter_query <text>` | — | Filter events by title/subject keyword |
648
- | `-a, --from_account <email>` | — | Calendar account email (for multi-account) |
627
+ #### microsoft_teams
628
+
629
+ Microsoft Teams operations: send, list_channels, list_chats, list_teams, search, search_users, create_chat.
649
630
 
650
- #### calendar create
631
+ ```bash
632
+ gsk microsoft_teams list_teams
633
+ gsk microsoft_teams list_channels --team_id 6c0db3a9-...
634
+ gsk microsoft_teams search --query "release notes"
635
+ ```
636
+
637
+ #### onedrive
651
638
 
652
- Create a new calendar event.
639
+ OneDrive file operations: list, search, read.
653
640
 
654
641
  ```bash
655
- # Create a simple event
656
- gsk calendar create --summary "Team Meeting" --start_time "2026-03-10T14:00:00-08:00" --end_time "2026-03-10T15:00:00-08:00"
642
+ gsk onedrive search --query "presentation"
643
+ gsk onedrive list --folder_path "/Documents"
644
+ ```
657
645
 
658
- # Create an event with details
659
- gsk calendar create \
660
- --summary "Q1 Planning" \
661
- --start_time "2026-03-15T09:00:00-08:00" \
662
- --end_time "2026-03-15T11:00:00-08:00" \
663
- --description "Quarterly planning session" \
664
- --location "Conference Room A" \
665
- --time_zone "America/Los_Angeles"
646
+ #### sharepoint
666
647
 
667
- # Create an event with attendees (sends invitations)
668
- gsk calendar create \
669
- --summary "Interview" \
670
- --start_time "2026-03-12T10:00:00-08:00" \
671
- --end_time "2026-03-12T11:00:00-08:00" \
672
- --attendees candidate@example.com interviewer@company.com
648
+ SharePoint operations: list, search, read_content, read_file.
673
649
 
674
- # Create on a specific calendar account
675
- gsk calendar create --summary "Personal Event" --start_time "..." --end_time "..." -a user@gmail.com
650
+ ```bash
651
+ gsk sharepoint search --query "company wiki"
652
+ gsk sharepoint list --site_id abc123
676
653
  ```
677
654
 
678
- | Option | Default | Description |
679
- |--------|---------|-------------|
680
- | `--summary <title>` | — | Event title (**required**) |
681
- | `--start_time <ISO8601>` | — | Start time with timezone offset (**required**) |
682
- | `--end_time <ISO8601>` | — | End time with timezone offset (**required**) |
683
- | `--description <text>` | — | Event description |
684
- | `--location <text>` | — | Event location |
685
- | `--attendees <emails...>` | — | Attendee email address(es) (sends invitations) |
686
- | `--time_zone <tz>` | `UTC` | Timezone name (e.g., `America/Los_Angeles`) |
687
- | `-a, --from_account <email>` | — | Calendar account email (for multi-account) |
655
+ #### outlook_contacts
656
+
657
+ Outlook Contacts operations: search.
658
+
659
+ ```bash
660
+ gsk outlook_contacts search --query "John"
661
+ ```
688
662
 
689
663
  ### AI Phone Calls
690
664
 
@@ -976,7 +950,7 @@ This separation allows programs to parse clean JSON from stdout while humans can
976
950
  | `mureka/song-generator` | Professional song generation with lyrics. Supports style prompts, reference tracks, vocal and melody inputs. Max: 180s |
977
951
  | `mureka/instrumental-generator` | Instrumental music generation without vocals. Supports style prompts and reference tracks. Max: 180s |
978
952
  | `fal-ai/lyria2` | Google Lyria 2 text-to-music. Good for sound effects and lyrics-free music. Max: 30 seconds |
979
- | `fal-ai/minimax-music/v2.5` | Song generation with lyrics using MiniMax Music 2.5. Supports markers (Verse), (Chorus), (Bridge), etc. Requires style prompt and lyrics |
953
+ | `fal-ai/minimax-music/v2.6` | Song generation with lyrics using MiniMax Music 2.6. Supports markers (Verse), (Chorus), (Bridge), etc. Requires style prompt and lyrics |
980
954
 
981
955
  **Voice Cloning & Transformation**
982
956
 
package/dist/config.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * 2. Environment variables (GSK_API_KEY, GSK_BASE_URL)
7
7
  * 3. Config file (~/.genspark-tool-cli/config.json)
8
8
  */
9
- import type { ToolSchema } from "./types.js";
9
+ import type { ToolSchema } from './types.js';
10
10
  export interface ConfigFile {
11
11
  api_key?: string;
12
12
  base_url?: string;
@@ -14,9 +14,23 @@ export interface ConfigFile {
14
14
  debug?: boolean;
15
15
  project_id?: string;
16
16
  auto_update?: boolean;
17
+ /**
18
+ * Virtual Developer project ID — gates the visibility of the `gsk vd`
19
+ * subcommand group. When set (either here or via GSK_VD_PROJECT_ID env
20
+ * var), the CLI exposes `gsk vd <subcmd>` and auto-injects this value as
21
+ * the default for every `--vd_project_id` flag. When unset, the whole
22
+ * `vd` subcommand group is hidden from the CLI.
23
+ */
24
+ vd_project_id?: string;
17
25
  }
18
26
  /**
19
- * Get the path to the config file
27
+ * Set (or clear) the custom config path. Call this before any other
28
+ * function in this module so that subsequent reads/writes target the
29
+ * override. Pass `undefined` to reset to the default location.
30
+ */
31
+ export declare function setConfigPathOverride(absPath: string | undefined): void;
32
+ /**
33
+ * Get the path to the config file — honours a `--config` override.
20
34
  */
21
35
  export declare function getConfigPath(): string;
22
36
  /**
@@ -25,7 +39,15 @@ export declare function getConfigPath(): string;
25
39
  */
26
40
  export declare function loadConfigFile(): ConfigFile;
27
41
  /**
28
- * Save configuration to the config file
42
+ * Save configuration to the config file — honours a `--config` override.
43
+ *
44
+ * Must resolve the filename via `getConfigPath()` (not
45
+ * `path.join(dir, CONFIG_FILE)`) so that when an override like
46
+ * `--config /tmp/my-profile.json` is active, the write lands on
47
+ * `/tmp/my-profile.json`, not `/tmp/config.json`. Using the raw
48
+ * `CONFIG_FILE` constant here would make `login`/`logout` silently write
49
+ * to the wrong file while reads still target the override — a
50
+ * split-brain state.
29
51
  */
30
52
  export declare function saveConfigFile(config: ConfigFile): void;
31
53
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAoBD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,CA6B3C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAUvD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CA+BnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAezE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAsBD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEvE;AAYD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,CAiC3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CASvD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CA+BnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAezE"}
package/dist/config.js CHANGED
@@ -6,23 +6,45 @@
6
6
  * 2. Environment variables (GSK_API_KEY, GSK_BASE_URL)
7
7
  * 3. Config file (~/.genspark-tool-cli/config.json)
8
8
  */
9
- import * as fs from "fs";
10
- import * as path from "path";
11
- import * as os from "os";
12
- const CONFIG_DIR = ".genspark-tool-cli";
13
- const CONFIG_FILE = "config.json";
14
- const TOOLS_CACHE_FILE = "tools-cache.json";
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import * as os from 'os';
12
+ const CONFIG_DIR = '.genspark-tool-cli';
13
+ const CONFIG_FILE = 'config.json';
14
+ const TOOLS_CACHE_FILE = 'tools-cache.json';
15
15
  const CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours
16
16
  /**
17
- * Get the config directory path
17
+ * Absolute path to an override config file. Set via `setConfigPathOverride`
18
+ * from a CLI flag (`--config`) or env var (`GSK_CONFIG`) at startup. When
19
+ * set, both the config file and the tools cache are read/written in the
20
+ * override's directory so a `--config` profile stays fully self-contained
21
+ * (useful for connecting to multiple servers / projects from one machine).
22
+ */
23
+ let _configPathOverride;
24
+ /**
25
+ * Set (or clear) the custom config path. Call this before any other
26
+ * function in this module so that subsequent reads/writes target the
27
+ * override. Pass `undefined` to reset to the default location.
28
+ */
29
+ export function setConfigPathOverride(absPath) {
30
+ _configPathOverride = absPath ? path.resolve(absPath) : undefined;
31
+ }
32
+ /**
33
+ * Get the config directory path — honours a `--config` override.
18
34
  */
19
35
  function getConfigDir() {
36
+ if (_configPathOverride) {
37
+ return path.dirname(_configPathOverride);
38
+ }
20
39
  return path.join(os.homedir(), CONFIG_DIR);
21
40
  }
22
41
  /**
23
- * Get the path to the config file
42
+ * Get the path to the config file — honours a `--config` override.
24
43
  */
25
44
  export function getConfigPath() {
45
+ if (_configPathOverride) {
46
+ return _configPathOverride;
47
+ }
26
48
  return path.join(getConfigDir(), CONFIG_FILE);
27
49
  }
28
50
  /**
@@ -35,18 +57,21 @@ export function loadConfigFile() {
35
57
  if (!fs.existsSync(configPath)) {
36
58
  return {};
37
59
  }
38
- const content = fs.readFileSync(configPath, "utf-8");
60
+ const content = fs.readFileSync(configPath, 'utf-8');
39
61
  const config = JSON.parse(content);
40
62
  // Validate and return only known fields
41
63
  return {
42
- api_key: typeof config.api_key === "string" ? config.api_key : undefined,
43
- base_url: typeof config.base_url === "string" ? config.base_url : undefined,
44
- timeout: typeof config.timeout === "number" ? config.timeout : undefined,
45
- debug: typeof config.debug === "boolean" ? config.debug : undefined,
46
- project_id: typeof config.project_id === "string" ? config.project_id : undefined,
47
- auto_update: typeof config.auto_update === "boolean"
64
+ api_key: typeof config.api_key === 'string' ? config.api_key : undefined,
65
+ base_url: typeof config.base_url === 'string' ? config.base_url : undefined,
66
+ timeout: typeof config.timeout === 'number' ? config.timeout : undefined,
67
+ debug: typeof config.debug === 'boolean' ? config.debug : undefined,
68
+ project_id: typeof config.project_id === 'string' ? config.project_id : undefined,
69
+ auto_update: typeof config.auto_update === 'boolean'
48
70
  ? config.auto_update
49
71
  : undefined,
72
+ vd_project_id: typeof config.vd_project_id === 'string'
73
+ ? config.vd_project_id
74
+ : undefined,
50
75
  };
51
76
  }
52
77
  catch {
@@ -55,16 +80,23 @@ export function loadConfigFile() {
55
80
  }
56
81
  }
57
82
  /**
58
- * Save configuration to the config file
83
+ * Save configuration to the config file — honours a `--config` override.
84
+ *
85
+ * Must resolve the filename via `getConfigPath()` (not
86
+ * `path.join(dir, CONFIG_FILE)`) so that when an override like
87
+ * `--config /tmp/my-profile.json` is active, the write lands on
88
+ * `/tmp/my-profile.json`, not `/tmp/config.json`. Using the raw
89
+ * `CONFIG_FILE` constant here would make `login`/`logout` silently write
90
+ * to the wrong file while reads still target the override — a
91
+ * split-brain state.
59
92
  */
60
93
  export function saveConfigFile(config) {
61
- const configDir = getConfigDir();
62
- const configPath = path.join(configDir, CONFIG_FILE);
63
- // Create config directory if it doesn't exist
94
+ const configPath = getConfigPath();
95
+ const configDir = path.dirname(configPath);
64
96
  if (!fs.existsSync(configDir)) {
65
97
  fs.mkdirSync(configDir, { recursive: true });
66
98
  }
67
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
99
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
68
100
  }
69
101
  /**
70
102
  * Load tools from the cache file.
@@ -76,7 +108,7 @@ export function loadToolsCache(baseUrl) {
76
108
  if (!fs.existsSync(cachePath)) {
77
109
  return null;
78
110
  }
79
- const content = fs.readFileSync(cachePath, "utf-8");
111
+ const content = fs.readFileSync(cachePath, 'utf-8');
80
112
  const cache = JSON.parse(content);
81
113
  // Validate base_url matches
82
114
  if (cache.base_url !== baseUrl) {
@@ -111,6 +143,6 @@ export function saveToolsCache(baseUrl, tools) {
111
143
  base_url: baseUrl,
112
144
  tools,
113
145
  };
114
- fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2), "utf-8");
146
+ fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2), 'utf-8');
115
147
  }
116
148
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}