@xmemo/client 0.4.156 → 0.4.158

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.
Files changed (46) hide show
  1. package/README.md +37 -7
  2. package/package.json +2 -1
  3. package/plugins/kiro/.kiro-plugin/power.json +35 -0
  4. package/plugins/kiro/CHANGELOG.md +9 -0
  5. package/plugins/kiro/LICENSE +7 -0
  6. package/plugins/kiro/POWER.md +147 -0
  7. package/plugins/kiro/README.md +31 -0
  8. package/plugins/kiro/SETUP.md +234 -0
  9. package/plugins/kiro/assets/logo.svg +27 -0
  10. package/plugins/kiro/mcp.json +7 -0
  11. package/plugins/kiro/steering/AGENTS.md +32 -0
  12. package/src/cli.js +5 -5
  13. package/src/commands/auth.js +9 -8
  14. package/src/commands/diagnostics.js +10 -9
  15. package/src/commands/mcp.js +12 -11
  16. package/src/commands/profile.js +7 -6
  17. package/src/commands/setup.js +13 -12
  18. package/src/commands/update.js +6 -5
  19. package/src/{env.js → config/env.js} +7 -6
  20. package/src/{path-config.js → config/paths.js} +2 -1
  21. package/src/{profile.js → config/profile.js} +37 -42
  22. package/src/{constants.js → core/constants.js} +5 -5
  23. package/src/core/version.js +9 -0
  24. package/src/mcp/{detect.js → clients/detect.js} +3 -2
  25. package/src/mcp/{registry.js → clients/registry.js} +2 -1
  26. package/src/mcp/clients.js +6 -5
  27. package/src/mcp/{names.js → core/names.js} +2 -1
  28. package/src/mcp/{templates.js → core/templates.js} +4 -3
  29. package/src/mcp/{json-clients.js → formats/json.js} +11 -6
  30. package/src/mcp/{codex.js → formats/toml.js} +5 -4
  31. package/src/mcp/{hermes.js → formats/yaml.js} +5 -4
  32. package/src/mcp/{identity.js → identity/device.js} +28 -12
  33. package/src/mcp/{paths.js → identity/paths.js} +1 -0
  34. package/src/mcp/{copilot-proxy.js → proxy/copilot.js} +6 -5
  35. package/src/mcp/{proxy.js → proxy/server.js} +8 -7
  36. package/src/{auth.js → network/auth.js} +5 -4
  37. package/src/{base-url.js → network/base-url.js} +3 -2
  38. package/src/{discovery.js → network/discovery.js} +5 -4
  39. package/src/{http.js → network/http.js} +3 -2
  40. package/src/{help.js → ui/help.js} +3 -2
  41. package/src/{setup.js → ui/setup.js} +9 -8
  42. package/src/version.js +0 -1
  43. /package/src/{args.js → core/args.js} +0 -0
  44. /package/src/{errors.js → core/errors.js} +0 -0
  45. /package/src/{io.js → core/io.js} +0 -0
  46. /package/src/{runtime.js → core/runtime.js} +0 -0
@@ -7,16 +7,16 @@ import {
7
7
  AGENT_INSTANCE_HEADER,
8
8
  MCP_SERVER_NAME,
9
9
  TOKEN_ENV_VAR
10
- } from '../constants.js';
11
- import { UsageError } from '../errors.js';
10
+ } from '../../core/constants.js';
11
+ import { UsageError } from '../../core/errors.js';
12
12
  import {
13
13
  bestEffortChmod,
14
14
  isPlainObject,
15
15
  parseJsonConfig,
16
16
  readTextIfExists
17
- } from '../runtime.js';
18
- import { envReferenceIdentity } from './identity.js';
19
- import { existingJsonMcpServerName } from './names.js';
17
+ } from '../../core/runtime.js';
18
+ import { envReferenceIdentity } from '../identity/device.js';
19
+ import { existingJsonMcpServerName } from '../core/names.js';
20
20
 
21
21
  export const JSON_MCP_CLIENT_DEFINITIONS = Object.freeze([
22
22
  httpClientDefinition('cursor', 'Cursor', 'defaultCursorConfigPath', { urlKey: 'url', authentication: 'env-bearer' }),
@@ -30,7 +30,7 @@ export const JSON_MCP_CLIENT_DEFINITIONS = Object.freeze([
30
30
  nestedTransportClientDefinition('continue', 'Continue', 'defaultContinueConfigPath'),
31
31
  commandClientDefinition('claude-desktop', 'Claude Desktop', 'defaultClaudeConfigPath'),
32
32
  httpClientDefinition('openclaw', 'OpenClaw', 'defaultOpenclawConfigPath', { urlKey: 'url', authentication: 'env-bearer' }),
33
- httpClientDefinition('kiro', 'Kiro', 'defaultKiroConfigPath', { urlKey: 'url', authentication: 'env-bearer' }),
33
+ httpClientDefinition('kiro', 'Kiro', 'defaultKiroConfigPath', { urlKey: 'url', section: 'powers.mcpServers', authentication: 'oauth' }),
34
34
  commandClientDefinition('zed', 'Zed', 'defaultZedConfigPath', { section: 'context_servers' }),
35
35
  nestedTransportClientDefinition('jetbrains', 'JetBrains', 'defaultJetbrainsConfigPath'),
36
36
  remoteClientDefinition('opencode', 'OpenCode', 'defaultOpencodeConfigPath'),
@@ -182,6 +182,10 @@ function headersForDefinition(definition, identity) {
182
182
 
183
183
  if (definition.authentication === 'env-bearer') {
184
184
  headers.Authorization = authorizationHeader(definition.bearerSyntax);
185
+ } else if (definition.id === 'kiro') {
186
+ if (process.env[TOKEN_ENV_VAR]) {
187
+ headers.Authorization = authorizationHeader(definition.bearerSyntax ?? 'env-colon');
188
+ }
185
189
  }
186
190
 
187
191
  return orderedHeaders(headers);
@@ -352,3 +356,4 @@ export const claudecodeJsonConfig = (mcpUrl, identity = envReferenceIdentity('cl
352
356
  export const claudecodeJsonSnippet = (mcpUrl, identity = envReferenceIdentity('claude-code')) => jsonClientSnippet('claude-code', mcpUrl, identity);
353
357
  export const claudecodeJsonServerConfig = (mcpUrl, identity = envReferenceIdentity('claude-code')) => jsonClientServerConfig('claude-code', mcpUrl, identity);
354
358
  export const mergeClaudecodeMcpConfig = (configPath, mcpUrl, identity) => mergeJsonClientMcpConfig('claude-code', configPath, mcpUrl, identity);
359
+
@@ -6,8 +6,8 @@ import {
6
6
  LEGACY_MCP_SERVER_NAMES,
7
7
  MCP_SERVER_NAME,
8
8
  TOKEN_ENV_VAR
9
- } from '../constants.js';
10
- import { UsageError } from '../errors.js';
9
+ } from '../../core/constants.js';
10
+ import { UsageError } from '../../core/errors.js';
11
11
  import {
12
12
  bestEffortChmod,
13
13
  escapeRegExp,
@@ -15,8 +15,8 @@ import {
15
15
  fileExists,
16
16
  readTextIfExists,
17
17
  unescapeTomlString
18
- } from '../runtime.js';
19
- import { agentInstanceIdentityPath } from './identity.js';
18
+ } from '../../core/runtime.js';
19
+ import { agentInstanceIdentityPath } from '../identity/device.js';
20
20
 
21
21
  export function codexTomlSnippet(mcpUrl) {
22
22
  return `[mcp_servers.${MCP_SERVER_NAME}]
@@ -145,3 +145,4 @@ function tomlStringValue(block, key) {
145
145
  const match = block.match(pattern);
146
146
  return match ? unescapeTomlString(match[1]) : null;
147
147
  }
148
+
@@ -5,13 +5,13 @@ import {
5
5
  AGENT_INSTANCE_ENV_VAR,
6
6
  MCP_SERVER_NAME,
7
7
  TOKEN_ENV_VAR
8
- } from '../constants.js';
9
- import { UsageError } from '../errors.js';
8
+ } from '../../core/constants.js';
9
+ import { UsageError } from '../../core/errors.js';
10
10
  import {
11
11
  bestEffortChmod,
12
12
  readTextIfExists
13
- } from '../runtime.js';
14
- import { envReferenceIdentity } from './identity.js';
13
+ } from '../../core/runtime.js';
14
+ import { envReferenceIdentity } from '../identity/device.js';
15
15
 
16
16
  export function hermesYamlSnippet(mcpUrl, identity = envReferenceIdentity('hermes')) {
17
17
  return `mcp_servers:
@@ -69,3 +69,4 @@ export async function mergeHermesMcpConfig(configPath, mcpUrl, identity) {
69
69
  }
70
70
  await bestEffortChmod(configPath, 0o600);
71
71
  }
72
+
@@ -1,10 +1,10 @@
1
1
  import fs from 'node:fs/promises';
2
+ import os from 'node:os';
2
3
  import path from 'node:path';
3
- import { randomUUID } from 'node:crypto';
4
4
 
5
- import { AGENT_INSTANCE_ENV_VAR } from '../constants.js';
6
- import { bestEffortChmod, parseJsonConfig, readTextIfExists } from '../runtime.js';
7
- import { stringValue } from '../args.js';
5
+ import { AGENT_INSTANCE_ENV_VAR } from '../../core/constants.js';
6
+ import { bestEffortChmod, parseJsonConfig, readTextIfExists } from '../../core/runtime.js';
7
+ import { stringValue } from '../../core/args.js';
8
8
  import { configRoot } from './paths.js';
9
9
 
10
10
  function identityClientId(clientId) {
@@ -24,32 +24,47 @@ export async function agentIdentity(clientId, env) {
24
24
  };
25
25
  }
26
26
 
27
- const identityPath = agentInstanceIdentityPath(env, targetClientId);
28
- const existing = await readAgentInstanceIdentity(identityPath);
27
+ const identityPath = deviceInstanceIdentityPath(env);
28
+ const existing = await readDeviceInstanceIdentity(identityPath);
29
29
  if (existing) {
30
30
  return { agentId: targetClientId, agentInstanceId: existing, path: identityPath };
31
31
  }
32
32
 
33
- const generated = `xmemo-${targetClientId}-${randomUUID()}`;
33
+ const hostname = os.hostname().toLowerCase().replace(/[^a-z0-9-]/g, '-').substring(0, 32);
34
+ const generated = `xmemo-${hostname}`;
35
+
34
36
  await fs.mkdir(path.dirname(identityPath), { recursive: true, mode: 0o700 });
35
37
  await bestEffortChmod(path.dirname(identityPath), 0o700);
36
- await fs.writeFile(identityPath, `${JSON.stringify({ version: 1, agentId: targetClientId, agentInstanceId: generated }, null, 2)}\n`, { mode: 0o600 });
38
+ await fs.writeFile(identityPath, `${JSON.stringify({
39
+ version: 1,
40
+ deviceInstanceId: generated,
41
+ hostname: os.hostname(),
42
+ createdAt: new Date().toISOString()
43
+ }, null, 2)}\n`, { mode: 0o600 });
37
44
  await bestEffortChmod(identityPath, 0o600);
38
45
  return { agentId: targetClientId, agentInstanceId: generated, path: identityPath };
39
46
  }
40
47
 
41
- export async function readAgentInstanceIdentity(identityPath) {
48
+ export async function readDeviceInstanceIdentity(identityPath) {
42
49
  const existing = await readTextIfExists(identityPath);
43
50
  if (!existing.trim()) {
44
51
  return null;
45
52
  }
46
53
  const parsed = parseJsonConfig(existing, identityPath);
47
- const value = stringValue(parsed, ['agentInstanceId']);
54
+ const value = stringValue(parsed, ['deviceInstanceId']) || stringValue(parsed, ['agentInstanceId']);
48
55
  return value || null;
49
56
  }
50
57
 
51
- export function agentInstanceIdentityPath(env, clientId) {
52
- return path.join(configRoot(env), 'agent-instances', `${clientId}.json`);
58
+ export function deviceInstanceIdentityPath(env) {
59
+ return path.join(configRoot(env), 'device-instance.json');
60
+ }
61
+
62
+ export async function readAgentInstanceIdentity(identityPath) {
63
+ return readDeviceInstanceIdentity(identityPath);
64
+ }
65
+
66
+ export function agentInstanceIdentityPath(env) {
67
+ return deviceInstanceIdentityPath(env);
53
68
  }
54
69
 
55
70
  export function envReferenceIdentity(clientId) {
@@ -60,3 +75,4 @@ export function envReferenceIdentity(clientId) {
60
75
  path: `${AGENT_INSTANCE_ENV_VAR} environment variable`
61
76
  };
62
77
  }
78
+
@@ -152,3 +152,4 @@ export function defaultClaudecodeConfigPath(env) {
152
152
  const home = env.USERPROFILE || env.HOME || os.homedir();
153
153
  return path.join(home, '.claude.json');
154
154
  }
155
+
@@ -1,16 +1,16 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
 
4
- import { MCP_SERVER_NAME } from '../constants.js';
5
- import { UsageError } from '../errors.js';
4
+ import { MCP_SERVER_NAME } from '../../core/constants.js';
5
+ import { UsageError } from '../../core/errors.js';
6
6
  import {
7
7
  bestEffortChmod,
8
8
  isPlainObject,
9
9
  parseJsonConfig,
10
10
  readTextIfExists
11
- } from '../runtime.js';
12
- import { existingJsonMcpServerName } from './names.js';
13
- export { mcpProxyCommand } from './proxy.js';
11
+ } from '../../core/runtime.js';
12
+ import { existingJsonMcpServerName } from '../core/names.js';
13
+ export { mcpProxyCommand } from './server.js';
14
14
 
15
15
  export async function mergeCopilotMcpConfig(configPath, proxyUrl) {
16
16
  const existing = await readTextIfExists(configPath);
@@ -41,3 +41,4 @@ export function copilotLocalProxyServerConfig(proxyUrl) {
41
41
  url: proxyUrl
42
42
  };
43
43
  }
44
+
@@ -1,6 +1,6 @@
1
1
  import http from 'node:http';
2
2
 
3
- import { optionValue, parsePositiveInteger } from '../args.js';
3
+ import { optionValue, parsePositiveInteger } from '../../core/args.js';
4
4
  import {
5
5
  AGENT_ID_HEADER,
6
6
  AGENT_INSTANCE_HEADER,
@@ -11,12 +11,12 @@ import {
11
11
  DEFAULT_PROXY_PORT,
12
12
  PRODUCT_NAME,
13
13
  TOKEN_ENV_VAR
14
- } from '../constants.js';
15
- import { credentialsPath, resolveCredentialToken, validateToken } from '../auth.js';
16
- import { endpointUrl, normalizeBaseUrl } from '../http.js';
17
- import { UsageError } from '../errors.js';
18
- import { writeLine } from '../io.js';
19
- import { closeServer, readAll, waitForShutdown } from '../runtime.js';
14
+ } from '../../core/constants.js';
15
+ import { credentialsPath, resolveCredentialToken, validateToken } from '../../network/auth.js';
16
+ import { endpointUrl, normalizeBaseUrl } from '../../network/http.js';
17
+ import { UsageError } from '../../core/errors.js';
18
+ import { writeLine } from '../../core/io.js';
19
+ import { closeServer, readAll, waitForShutdown } from '../../core/runtime.js';
20
20
 
21
21
  export async function mcpProxyCommand(args, io, { agentIdentity }) {
22
22
  const baseUrl = normalizeBaseUrl(baseUrlOption(args, io.env));
@@ -109,3 +109,4 @@ function baseUrlOption(args, env) {
109
109
  ?? env.MEMORY_OS_BASE_URL
110
110
  ?? DEFAULT_SERVICE_URL;
111
111
  }
112
+
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
2
2
  import os from 'node:os';
3
3
  import path from 'node:path';
4
4
 
5
- import { stringValue } from './args.js';
5
+ import { stringValue } from '../core/args.js';
6
6
  import {
7
7
  CLI_VERSION,
8
8
  DEVICE_LOGIN_START_PATH,
@@ -10,16 +10,16 @@ import {
10
10
  LEGACY_TOKEN_ENV_VAR,
11
11
  PACKAGE_NAME,
12
12
  TOKEN_ENV_VAR
13
- } from './constants.js';
13
+ } from '../core/constants.js';
14
14
  import { endpointUrl, postJson } from './http.js';
15
- import { UsageError } from './errors.js';
15
+ import { UsageError } from '../core/errors.js';
16
16
  import {
17
17
  bestEffortChmod,
18
18
  parseJsonConfig,
19
19
  readAll,
20
20
  readTextIfExists,
21
21
  sleep
22
- } from './runtime.js';
22
+ } from '../core/runtime.js';
23
23
 
24
24
  export async function startDeviceLogin(baseUrl, timeoutMs, io) {
25
25
  const payload = await postJson(endpointUrl(baseUrl, DEVICE_LOGIN_START_PATH), {
@@ -197,3 +197,4 @@ export function validateToken(token) {
197
197
  throw new UsageError('Token is too short to be a production credential.');
198
198
  }
199
199
  }
200
+
@@ -1,5 +1,5 @@
1
- import { optionValue } from './args.js';
2
- import { DEFAULT_SERVICE_URL } from './constants.js';
1
+ import { optionValue } from '../core/args.js';
2
+ import { DEFAULT_SERVICE_URL } from '../core/constants.js';
3
3
 
4
4
  export function baseUrlOption(args, env) {
5
5
  return optionValue(args, '--base-url')
@@ -10,3 +10,4 @@ export function baseUrlOption(args, env) {
10
10
  ?? env.MEMORY_OS_URL
11
11
  ?? DEFAULT_SERVICE_URL;
12
12
  }
13
+
@@ -1,8 +1,8 @@
1
- import { arrayValue, booleanValue, stringValue } from './args.js';
2
- import { TOKEN_ENV_VAR } from './constants.js';
3
- import { UsageError } from './errors.js';
1
+ import { arrayValue, booleanValue, stringValue } from '../core/args.js';
2
+ import { TOKEN_ENV_VAR } from '../core/constants.js';
3
+ import { UsageError } from '../core/errors.js';
4
4
  import { endpointUrl, fetchJson } from './http.js';
5
- import { isPlainObject } from './runtime.js';
5
+ import { isPlainObject } from '../core/runtime.js';
6
6
 
7
7
  export function ensureDiscoveryService(discovery, discoveryUrl) {
8
8
  const service = stringValue(discovery, ['service']);
@@ -100,3 +100,4 @@ export function discoveryMcpClients(discovery) {
100
100
  }));
101
101
  }
102
102
 
103
+
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  CLI_VERSION,
3
3
  COMMAND_NAME
4
- } from './constants.js';
5
- import { UsageError } from './errors.js';
4
+ } from '../core/constants.js';
5
+ import { UsageError } from '../core/errors.js';
6
6
 
7
7
  export async function verifyTokenWithMcp(baseUrl, token, timeoutMs, io) {
8
8
  const url = endpointUrl(baseUrl, '/mcp');
@@ -158,3 +158,4 @@ export function endpointUrl(baseUrl, pathname) {
158
158
  url.search = '';
159
159
  return url.toString();
160
160
  }
161
+
@@ -4,8 +4,8 @@ import {
4
4
  LEGACY_COMMAND_NAME,
5
5
  PACKAGE_NAME,
6
6
  PRODUCT_NAME
7
- } from './constants.js';
8
- import { writeLine } from './io.js';
7
+ } from '../core/constants.js';
8
+ import { writeLine } from '../core/io.js';
9
9
 
10
10
  export function writeHelp(io) {
11
11
  writeLine(io.stdout, `======================================================================`);
@@ -56,3 +56,4 @@ export function writeHelp(io) {
56
56
  writeLine(io.stdout, ' - AST Merge Safety: Config writes only touch and append the XMemo keys, preserving all other servers.');
57
57
  writeLine(io.stdout, '======================================================================');
58
58
  }
59
+
@@ -1,17 +1,17 @@
1
- import { optionValue } from './args.js';
1
+ import { optionValue } from '../core/args.js';
2
2
  import {
3
3
  COMMAND_NAME,
4
4
  DEFAULT_PROXY_HOST,
5
5
  MCP_SERVER_NAME,
6
6
  PRODUCT_NAME,
7
7
  TOKEN_ENV_VAR
8
- } from './constants.js';
9
- import { UsageError } from './errors.js';
10
- import { writeLine } from './io.js';
11
- import { supportedMcpClientIds, usesClientOAuth } from './mcp/registry.js';
12
- import { mcpLocalProxyTemplate } from './mcp/templates.js';
13
- import { defaultCopilotConfigPath } from './path-config.js';
14
- import { profileClientConfig } from './profile.js';
8
+ } from '../core/constants.js';
9
+ import { UsageError } from '../core/errors.js';
10
+ import { writeLine } from '../core/io.js';
11
+ import { supportedMcpClientIds, usesClientOAuth } from '../mcp/clients/registry.js';
12
+ import { mcpLocalProxyTemplate } from '../mcp/core/templates.js';
13
+ import { defaultCopilotConfigPath } from '../mcp/identity/paths.js';
14
+ import { profileClientConfig } from '../config/profile.js';
15
15
 
16
16
  const SETUP_CLIENT_ALIASES = new Map([
17
17
  ['codex', 'codex'],
@@ -241,3 +241,4 @@ export function writeSetupSummary(plan, io) {
241
241
  writeLine(io.stdout, ` 2. Configure a client, for example: ${COMMAND_NAME} setup codex --url ${plan.baseUrl}`);
242
242
  writeLine(io.stdout, ` 3. Run ${COMMAND_NAME} status to smoke-test the service without sending the token.`);
243
243
  }
244
+
package/src/version.js DELETED
@@ -1 +0,0 @@
1
- export const CLI_VERSION = '0.4.156';
File without changes
File without changes
File without changes
File without changes