@1medium/cli 1.3.0 → 1.3.1

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": "@1medium/cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "CLI and MCP server for 1Medium AI task management",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/api.js CHANGED
@@ -1,20 +1,20 @@
1
1
  "use strict";
2
2
 
3
3
  const fetch = require("node-fetch");
4
- const config = require("./config");
4
+ const sessionState = require("./session-state");
5
5
 
6
6
  /**
7
7
  * Get API base URL
8
8
  */
9
9
  function getApiUrl() {
10
- return config.get("apiUrl") || "https://1medium.ai/api";
10
+ return sessionState.get("apiUrl") || "https://1medium.ai/api";
11
11
  }
12
12
 
13
13
  /**
14
14
  * Get auth token
15
15
  */
16
16
  function getToken() {
17
- const token = config.get("token");
17
+ const token = sessionState.get("token");
18
18
  if (!token) {
19
19
  throw new Error(
20
20
  "No token configured. Run '1m login' to set your API token."
@@ -27,7 +27,7 @@ function getToken() {
27
27
  * Get configured org ID (if any)
28
28
  */
29
29
  function getOrgId() {
30
- return config.get("orgId") || null;
30
+ return sessionState.get("orgId") || null;
31
31
  }
32
32
 
33
33
  /**
package/src/mcp-server.js CHANGED
@@ -8,7 +8,7 @@ const {
8
8
  ListToolsRequestSchema,
9
9
  } = require("@modelcontextprotocol/sdk/types.js");
10
10
  const api = require("./api");
11
- const config = require("./config");
11
+ const sessionState = require("./session-state");
12
12
 
13
13
  const server = new Server(
14
14
  {
@@ -368,6 +368,22 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
368
368
  required: ["id"],
369
369
  },
370
370
  },
371
+ {
372
+ name: "config_persist",
373
+ description: "Persist current session settings (org/space/project) to the config file. Use this when you want changes to apply to all Claude Code tabs and persist across restarts.",
374
+ inputSchema: {
375
+ type: "object",
376
+ properties: {},
377
+ },
378
+ },
379
+ {
380
+ name: "config_reset",
381
+ description: "Reset session to values from the config file. Use this to discard any org/space/project changes made in this session and reload from persistent config.",
382
+ inputSchema: {
383
+ type: "object",
384
+ properties: {},
385
+ },
386
+ },
371
387
  ],
372
388
  };
373
389
  });
@@ -377,7 +393,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
377
393
  const { name, arguments: args } = request.params;
378
394
 
379
395
  // Check if configured
380
- const token = config.get("token");
396
+ const token = sessionState.get("token");
381
397
  if (!token) {
382
398
  return {
383
399
  content: [
@@ -397,7 +413,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
397
413
  case "org_list": {
398
414
  result = await api.listOrgs();
399
415
  const orgs = result.orgs || [];
400
- const currentOrgId = config.get("orgId");
416
+ const currentOrgId = sessionState.get("orgId");
401
417
 
402
418
  if (orgs.length === 0) {
403
419
  return {
@@ -424,9 +440,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
424
440
  }
425
441
 
426
442
  case "org_set": {
427
- config.set("orgId", args.id);
443
+ sessionState.set("orgId", args.id);
428
444
  if (args.name) {
429
- config.set("orgName", args.name);
445
+ sessionState.set("orgName", args.name);
430
446
  }
431
447
  return {
432
448
  content: [
@@ -439,8 +455,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
439
455
  }
440
456
 
441
457
  case "org_get": {
442
- const orgId = config.get("orgId");
443
- const orgName = config.get("orgName");
458
+ const orgId = sessionState.get("orgId");
459
+ const orgName = sessionState.get("orgName");
444
460
 
445
461
  if (!orgId) {
446
462
  return {
@@ -460,7 +476,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
460
476
 
461
477
  case "task_create": {
462
478
  // Use provided project_id or fall back to configured default
463
- const projectId = args.project_id || config.get("projectId") || null;
479
+ const projectId = args.project_id || sessionState.get("projectId") || null;
464
480
  const payload = {
465
481
  title: args.title,
466
482
  body_md: args.body,
@@ -586,7 +602,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
586
602
  case "space_list": {
587
603
  result = await api.listSpaces();
588
604
  const spaces = result.spaces || [];
589
- const currentSpaceId = config.get("spaceId");
605
+ const currentSpaceId = sessionState.get("spaceId");
590
606
 
591
607
  if (spaces.length === 0) {
592
608
  return {
@@ -612,9 +628,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
612
628
  }
613
629
 
614
630
  case "space_set": {
615
- config.set("spaceId", args.id);
631
+ sessionState.set("spaceId", args.id);
616
632
  if (args.name) {
617
- config.set("spaceName", args.name);
633
+ sessionState.set("spaceName", args.name);
618
634
  }
619
635
  return {
620
636
  content: [
@@ -627,8 +643,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
627
643
  }
628
644
 
629
645
  case "space_get": {
630
- const spaceId = config.get("spaceId");
631
- const spaceName = config.get("spaceName");
646
+ const spaceId = sessionState.get("spaceId");
647
+ const spaceName = sessionState.get("spaceName");
632
648
 
633
649
  if (!spaceId) {
634
650
  return {
@@ -652,7 +668,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
652
668
 
653
669
  result = await api.listProjects(params);
654
670
  const projects = result.projects || [];
655
- const currentProjectId = config.get("projectId");
671
+ const currentProjectId = sessionState.get("projectId");
656
672
 
657
673
  if (projects.length === 0) {
658
674
  return {
@@ -682,9 +698,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
682
698
  }
683
699
 
684
700
  case "project_set": {
685
- config.set("projectId", args.id);
701
+ sessionState.set("projectId", args.id);
686
702
  if (args.name) {
687
- config.set("projectName", args.name);
703
+ sessionState.set("projectName", args.name);
688
704
  }
689
705
  return {
690
706
  content: [
@@ -697,8 +713,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
697
713
  }
698
714
 
699
715
  case "project_get": {
700
- const projectId = config.get("projectId");
701
- const projectName = config.get("projectName");
716
+ const projectId = sessionState.get("projectId");
717
+ const projectName = sessionState.get("projectName");
702
718
 
703
719
  if (!projectId) {
704
720
  return {
@@ -803,6 +819,52 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
803
819
  };
804
820
  }
805
821
 
822
+ case "config_persist": {
823
+ sessionState.persistSession();
824
+ const state = sessionState.getSessionState();
825
+ let text = "Session settings persisted to config file.";
826
+ if (state.orgName || state.orgId) {
827
+ text += `\n Org: ${state.orgName || state.orgId || "(none)"}`;
828
+ }
829
+ if (state.spaceName || state.spaceId) {
830
+ text += `\n Space: ${state.spaceName || state.spaceId || "(none)"}`;
831
+ }
832
+ if (state.projectName || state.projectId) {
833
+ text += `\n Project: ${state.projectName || state.projectId || "(none)"}`;
834
+ }
835
+ return {
836
+ content: [
837
+ {
838
+ type: "text",
839
+ text,
840
+ },
841
+ ],
842
+ };
843
+ }
844
+
845
+ case "config_reset": {
846
+ sessionState.resetSession();
847
+ const state = sessionState.getSessionState();
848
+ let text = "Session reset from config file.";
849
+ if (state.orgName || state.orgId) {
850
+ text += `\n Org: ${state.orgName || state.orgId || "(none)"}`;
851
+ }
852
+ if (state.spaceName || state.spaceId) {
853
+ text += `\n Space: ${state.spaceName || state.spaceId || "(none)"}`;
854
+ }
855
+ if (state.projectName || state.projectId) {
856
+ text += `\n Project: ${state.projectName || state.projectId || "(none)"}`;
857
+ }
858
+ return {
859
+ content: [
860
+ {
861
+ type: "text",
862
+ text,
863
+ },
864
+ ],
865
+ };
866
+ }
867
+
806
868
  default:
807
869
  return {
808
870
  content: [{ type: "text", text: `Unknown tool: ${name}` }],
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Session-scoped state for MCP server
5
+ *
6
+ * This module wraps the persistent config with an in-memory layer for session-scoped keys.
7
+ * Multiple Claude Code tabs can run separate MCP server processes without affecting each other's
8
+ * org/space/project selections.
9
+ *
10
+ * Session-scoped keys (in-memory only):
11
+ * - orgId, orgName, spaceId, spaceName, projectId, projectName
12
+ *
13
+ * Persistent keys (always read/write from config file):
14
+ * - token, apiUrl
15
+ */
16
+
17
+ const config = require("./config");
18
+
19
+ // Keys that are session-scoped (stored in memory, not persisted by default)
20
+ const SESSION_KEYS = [
21
+ "orgId",
22
+ "orgName",
23
+ "spaceId",
24
+ "spaceName",
25
+ "projectId",
26
+ "projectName",
27
+ ];
28
+
29
+ // In-memory session state, initialized from config
30
+ const sessionState = {};
31
+
32
+ // Initialize session state from config on module load
33
+ for (const key of SESSION_KEYS) {
34
+ sessionState[key] = config.get(key);
35
+ }
36
+
37
+ /**
38
+ * Get a config value
39
+ * Session-scoped keys return from memory; others fall through to persistent config
40
+ */
41
+ function get(key) {
42
+ if (SESSION_KEYS.includes(key)) {
43
+ return sessionState[key];
44
+ }
45
+ return config.get(key);
46
+ }
47
+
48
+ /**
49
+ * Set a config value
50
+ * Session-scoped keys are stored in memory only; others persist to config file
51
+ */
52
+ function set(key, value) {
53
+ if (SESSION_KEYS.includes(key)) {
54
+ sessionState[key] = value;
55
+ } else {
56
+ config.set(key, value);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Persist current session state to the config file
62
+ * Call this to make session changes permanent across all Claude Code tabs
63
+ */
64
+ function persistSession() {
65
+ for (const key of SESSION_KEYS) {
66
+ config.set(key, sessionState[key]);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Reset session state from the config file
72
+ * Call this to discard session changes and reload from persistent config
73
+ */
74
+ function resetSession() {
75
+ for (const key of SESSION_KEYS) {
76
+ sessionState[key] = config.get(key);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Get the list of session-scoped keys
82
+ */
83
+ function getSessionKeys() {
84
+ return [...SESSION_KEYS];
85
+ }
86
+
87
+ /**
88
+ * Get all current session values (for debugging/display)
89
+ */
90
+ function getSessionState() {
91
+ const state = {};
92
+ for (const key of SESSION_KEYS) {
93
+ state[key] = sessionState[key];
94
+ }
95
+ return state;
96
+ }
97
+
98
+ module.exports = {
99
+ get,
100
+ set,
101
+ persistSession,
102
+ resetSession,
103
+ getSessionKeys,
104
+ getSessionState,
105
+ };