martty 0.2.40 → 0.3.1-beta.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/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  ---
12
12
 
13
13
  Native binaries are packaged for macOS arm64, macOS x64, Linux x64, and Windows
14
- x64. Requires Node.js 18+.
14
+ x64. Requires Node.js 22.19+.
15
15
 
16
16
  > **Rename note:** the project and recommended npm package have moved from
17
17
  > DeepSeek Harness TUI / `martty` to **Martty** / `martty`.
@@ -272,16 +272,16 @@ credential, session, theme, and demo options.
272
272
 
273
273
  ## Supported platforms
274
274
 
275
- | Node platform key | Binary |
275
+ | Node platform key | npm package |
276
276
  |---|---|
277
- | `darwin-arm64` | `vendor/darwin-arm64/martty` |
278
- | `darwin-x64` | `vendor/darwin-x64/martty` |
279
- | `linux-x64` | `vendor/linux-x64/martty` |
280
- | `linux-arm64` | `vendor/linux-arm64/martty` |
281
- | `win32-x64` | `vendor/win32-x64/martty.exe` |
282
-
283
- If installation succeeds but launch reports `no native binary for ...`, confirm
284
- that you installed the latest version and that your platform appears above.
277
+ | `darwin-arm64` | `@openma/martty-darwin-arm64` |
278
+ | `darwin-x64` | `@openma/martty-darwin-x64` |
279
+ | `linux-x64` | `@openma/martty-linux-x64` |
280
+ | `linux-arm64` | `@openma/martty-linux-arm64` |
281
+ | `win32-x64` | `@openma/martty-win32-x64` |
282
+
283
+ If launch reports a missing native package, reinstall with optional dependencies
284
+ enabled (`npm install --include=optional martty`) and check the table above.
285
285
 
286
286
  ## Uninstall
287
287
 
package/bin/martty.js CHANGED
@@ -8,26 +8,10 @@ import { createInterface } from 'node:readline/promises'
8
8
  import { resolveDependencyStack } from '../lib/agent.js'
9
9
  import { bootClient, parseClientArgv, painterArgs, uiSettingsPath } from '../lib/boot.js'
10
10
  import { runHarnessCommandAsync } from '../lib/harnesses.js'
11
+ import { nativeBinary } from '../lib/spawn-tui.js'
11
12
 
12
13
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
13
- const platformKey = process.platform + '-' + process.arch
14
- const vendorDir = path.join(__dirname, '..', 'vendor')
15
- const binaryName = process.platform === 'win32' ? 'martty.exe' : 'martty'
16
- const packaged = path.join(vendorDir, platformKey, binaryName)
17
14
  const configuredBin = process.env.MARTTY_BIN || process.env.DSH_TUI_BIN
18
- let binaryPath = packaged
19
- if (typeof configuredBin === 'string' && configuredBin.length > 0) {
20
- if (fs.existsSync(configuredBin)) {
21
- binaryPath = configuredBin
22
- } else {
23
- // Never silently fall back: the user believes they are running their
24
- // own build (devlocalinstall.sh has caught this confusion before).
25
- console.error(
26
- `martty: ${configuredBin} (from ${process.env.MARTTY_BIN ? 'MARTTY_BIN' : 'DSH_TUI_BIN'})`
27
- + ' does not exist — falling back to the bundled binary',
28
- )
29
- }
30
- }
31
15
 
32
16
  const argv = process.argv.slice(2)
33
17
  const wantDemoSkin = argv.includes('--demo-skin')
@@ -109,23 +93,19 @@ if (!wantHelp && !wantVersion && !wantDemo && !wantDemoSkin) {
109
93
  }
110
94
  }
111
95
 
112
- if (!fs.existsSync(binaryPath)) {
113
- let available = []
114
- try {
115
- available = fs
116
- .readdirSync(vendorDir, { withFileTypes: true })
117
- .filter((e) => e.isDirectory())
118
- .map((e) => e.name)
119
- } catch {
120
- // vendor dir missing entirely
121
- }
122
- console.error('martty: no bundled binary for this platform (' + platformKey + ').')
123
- if (available.length > 0) {
124
- console.error('Bundled platforms: ' + available.join(', '))
125
- } else {
126
- console.error('No platform binaries are bundled in this install.')
127
- }
128
- console.error('Hint: run scripts/build-npm.sh on this machine to build and package a native binary.')
96
+ if (configuredBin && !fs.existsSync(configuredBin)) {
97
+ // Never silently fall back: the user believes they are running their
98
+ // own build (devlocalinstall.sh has caught this confusion before).
99
+ console.error(
100
+ `martty: ${configuredBin} (from ${process.env.MARTTY_BIN ? 'MARTTY_BIN' : 'DSH_TUI_BIN'})`
101
+ + ' does not exist — falling back to the installed native binary',
102
+ )
103
+ }
104
+ let binaryPath
105
+ try {
106
+ binaryPath = nativeBinary({ envBin: configuredBin && fs.existsSync(configuredBin) ? configuredBin : null })
107
+ } catch (error) {
108
+ console.error(`martty: ${error instanceof Error ? error.message : String(error)}`)
129
109
  process.exit(1)
130
110
  }
131
111
 
@@ -19,6 +19,19 @@ import { downloadFile } from './download.js'
19
19
 
20
20
  export const ACP_REGISTRY_URL = 'https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json'
21
21
 
22
+ const OPENMA_PI_ACP = '@openma/pi-acp@0.1.3'
23
+
24
+ function preferMarttyPiAcp(records) {
25
+ return records.map((record) => record.id === 'pi-acp' ? {
26
+ ...record,
27
+ label: 'Pi (OpenMA)',
28
+ version: '0.1.3',
29
+ distributions: [{
30
+ type: 'npx', command: 'npx', args: [OPENMA_PI_ACP], env: {},
31
+ }],
32
+ } : record)
33
+ }
34
+
22
35
  function registryCachePath(options) {
23
36
  return typeof options.settingsPath === 'string'
24
37
  ? path.join(path.dirname(options.settingsPath), 'cache', 'acp-registry.json') : undefined
@@ -32,11 +45,11 @@ export function readAcpRegistrySnapshot(options = {}) {
32
45
  if (statSync(cachePath).size > 16 * 1024 * 1024) throw new Error('oversized cache')
33
46
  const cached = JSON.parse(readFileSync(cachePath, 'utf8'))
34
47
  if (cached.source === (options.registryUrl ?? ACP_REGISTRY_URL) && Array.isArray(cached.catalog?.agents)) {
35
- return normalizeAcpRegistry(cached.catalog, options)
48
+ return preferMarttyPiAcp(normalizeAcpRegistry(cached.catalog, options))
36
49
  }
37
50
  } catch { /* Missing/corrupt cache cannot block the bundled catalog. */ }
38
51
  }
39
- return normalizeAcpRegistry(JSON.parse(readFileSync(new URL('./acp-registry.snapshot.json', import.meta.url), 'utf8')), options)
52
+ return preferMarttyPiAcp(normalizeAcpRegistry(JSON.parse(readFileSync(new URL('./acp-registry.snapshot.json', import.meta.url), 'utf8')), options))
40
53
  }
41
54
 
42
55
  function cacheRegistry(value, options) {
@@ -240,7 +253,7 @@ export async function fetchAcpRegistry(options = {}) {
240
253
  throw new Error('ACP Registry has no distributions for this platform')
241
254
  }
242
255
  cacheRegistry(value, options)
243
- return records
256
+ return preferMarttyPiAcp(records)
244
257
  } catch (error) {
245
258
  if (timeout.signal.aborted) throw timeout.signal.reason
246
259
  if (error instanceof Error && error.message.startsWith('ACP Registry')) throw error
package/lib/spawn-tui.js CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  import { spawn } from 'node:child_process'
9
9
  import { randomBytes, timingSafeEqual } from 'node:crypto'
10
+ import { createRequire } from 'node:module'
10
11
  import fs from 'node:fs'
11
12
  import { createServer } from 'node:net'
12
13
  import path from 'node:path'
@@ -15,8 +16,8 @@ import { fileURLToPath } from 'node:url'
15
16
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
16
17
 
17
18
  /** Select the first existing native painter in development-to-release order. */
18
- export function selectNativeBinary({ envBin, devBin, packagedBin }) {
19
- for (const candidate of [envBin, devBin, packagedBin]) {
19
+ export function selectNativeBinary({ envBin, devBin, optionalBin, packagedBin }) {
20
+ for (const candidate of [envBin, devBin, optionalBin, packagedBin]) {
20
21
  if (typeof candidate === 'string' && candidate.length > 0 && fs.existsSync(candidate)) {
21
22
  return candidate
22
23
  }
@@ -25,28 +26,34 @@ export function selectNativeBinary({ envBin, devBin, packagedBin }) {
25
26
  }
26
27
 
27
28
  /**
28
- * Packaged native binary for this platform, or throw if it was not staged.
29
+ * Installed optional platform binary, or the local development binary.
29
30
  * Honors `MARTTY_BIN`, with `DSH_TUI_BIN` as a compatibility fallback.
31
+ * @param {{ packageRoot?: string, platform?: string, arch?: string, envBin?: string | null, devBin?: string | null }} [options]
30
32
  * @returns {string}
31
33
  */
32
- export function nativeBinary() {
33
- const envBin = process.env.MARTTY_BIN || process.env.DSH_TUI_BIN
34
- const key = `${process.platform}-${process.arch}`
35
- const exe = process.platform === 'win32' ? 'martty.exe' : 'martty'
36
- const bin = path.join(__dirname, '..', 'vendor', key, exe)
37
- const devBin = path.join(__dirname, '..', '..', 'target', 'debug', exe)
38
- const selected = selectNativeBinary({ envBin, devBin, packagedBin: bin })
34
+ export function nativeBinary(options = {}) {
35
+ const packageRoot = options.packageRoot ?? path.join(__dirname, '..')
36
+ const platform = options.platform ?? process.platform
37
+ const arch = options.arch ?? process.arch
38
+ const key = `${platform}-${arch}`
39
+ const exe = platform === 'win32' ? 'martty.exe' : 'martty'
40
+ const packageName = `@openma/martty-${key}`
41
+ const req = createRequire(path.join(packageRoot, 'package.json'))
42
+ let optionalBin
43
+ try { optionalBin = req.resolve(`${packageName}/bin/${exe}`) }
44
+ catch (error) {
45
+ if (error?.code !== 'MODULE_NOT_FOUND' && error?.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') throw error
46
+ }
47
+ const envBin = options.envBin === undefined
48
+ ? process.env.MARTTY_BIN || process.env.DSH_TUI_BIN : options.envBin
49
+ const devBin = options.devBin === undefined
50
+ ? path.join(packageRoot, '..', 'target', 'debug', exe) : options.devBin
51
+ const packagedBin = path.join(packageRoot, 'vendor', key, exe)
52
+ const selected = selectNativeBinary({ envBin, devBin, optionalBin, packagedBin })
39
53
  if (selected === undefined) {
40
- let have = []
41
- try {
42
- have = fs.readdirSync(path.join(__dirname, '..', 'vendor'))
43
- } catch {
44
- // vendor dir missing entirely
45
- }
46
54
  throw new Error(
47
- `martty: no native binary for ${key}` +
48
- ` (packaged: ${have.join(', ') || 'none'});` +
49
- ' rebuild the package on this machine with scripts/build-npm.sh',
55
+ `Martty native package ${packageName} is missing for ${key}; reinstall Martty with optional dependencies`
56
+ + ' (npm install --include=optional). From source, build with scripts/build-npm.sh.',
50
57
  )
51
58
  }
52
59
  return selected
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "martty",
3
- "version": "0.2.40",
3
+ "version": "0.3.1-beta.0",
4
4
  "description": "Terminal-native ACP client UI; Cordis client tree, any ACP agent",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -64,7 +64,6 @@
64
64
  "lib",
65
65
  "creator",
66
66
  "skills/tui-plugin-development/SKILL.md",
67
- "vendor",
68
67
  "cordis.patch.yml",
69
68
  "README.md",
70
69
  "LICENSE"
@@ -86,7 +85,7 @@
86
85
  "@deepseek-ai/dsh": "0.1.7-rc.2"
87
86
  },
88
87
  "engines": {
89
- "node": ">=18"
88
+ "node": ">=22.19.0"
90
89
  },
91
90
  "keywords": [
92
91
  "deepseek",
@@ -95,5 +94,12 @@
95
94
  "agent",
96
95
  "acp",
97
96
  "agent-client-protocol"
98
- ]
97
+ ],
98
+ "optionalDependencies": {
99
+ "@openma/martty-darwin-arm64": "0.3.1-beta.0",
100
+ "@openma/martty-darwin-x64": "0.3.1-beta.0",
101
+ "@openma/martty-linux-x64": "0.3.1-beta.0",
102
+ "@openma/martty-linux-arm64": "0.3.1-beta.0",
103
+ "@openma/martty-win32-x64": "0.3.1-beta.0"
104
+ }
99
105
  }
Binary file
Binary file
Binary file
Binary file
Binary file