t44 0.4.0-rc.7 → 0.4.0-rc.8

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/caps/Home.ts CHANGED
@@ -14,11 +14,17 @@ export async function capsule({
14
14
  return encapsulate({
15
15
  '#@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0': {
16
16
  '#@stream44.studio/encapsulate/structs/Capsule': {},
17
+ '#t44/structs/HomeRegistryConfig': {
18
+ as: '$HomeRegistryConfig'
19
+ },
17
20
  '#': {
18
21
  homeDir: {
19
22
  type: CapsulePropertyTypes.GetterFunction,
20
23
  value: async function (this: any): Promise<string> {
21
- return process.env.T44_HOME_DIR || homedir()
24
+ if (process.env.T44_HOME_DIR) return process.env.T44_HOME_DIR
25
+ const config = await this.$HomeRegistryConfig.config
26
+ if (config?.homeDir) return config.homeDir
27
+ return homedir()
22
28
  }
23
29
  },
24
30
  sshDir: {
@@ -51,10 +51,11 @@ export async function capsule({
51
51
  type: CapsulePropertyTypes.Function,
52
52
  value: async function (this: any): Promise<string> {
53
53
  const { stat, mkdir } = await import('fs/promises')
54
+ const { join } = await import('path')
54
55
  const chalk = (await import('chalk')).default
55
56
 
56
57
  const config = await this.$HomeRegistryConfig.config
57
- const defaultDir = await this.Home.registryDir
58
+ const defaultHomeDir = await this.Home.homeDir
58
59
 
59
60
  let chosenDir: string
60
61
 
@@ -73,15 +74,15 @@ export async function capsule({
73
74
  }
74
75
  chosenDir = config.rootDir
75
76
  } else {
76
- // rootDir not set — prompt user
77
- console.log(chalk.cyan(`\nšŸ  Home Registry Setup\n`))
78
- console.log(chalk.gray(' The home registry is the place in your home directory that keeps'))
79
- console.log(chalk.gray(' details about your workspaces and projects.'))
77
+ // rootDir not set — prompt user for home directory
78
+ console.log(chalk.cyan(`\nšŸ  Home Directory Setup\n`))
79
+ console.log(chalk.gray(' The home directory is where your workspace keeps its registry,'))
80
+ console.log(chalk.gray(' SSH keys, and other workspace-related files.'))
80
81
  console.log('')
81
82
 
82
- chosenDir = await this.WorkspacePrompt.input({
83
- message: 'Enter the home registry directory:',
84
- defaultValue: defaultDir,
83
+ const chosenHomeDir = await this.WorkspacePrompt.input({
84
+ message: 'Enter the home directory:',
85
+ defaultValue: defaultHomeDir,
85
86
  validate: (input: string) => {
86
87
  if (!input || input.trim().length === 0) {
87
88
  return 'Directory path cannot be empty'
@@ -90,18 +91,18 @@ export async function capsule({
90
91
  }
91
92
  })
92
93
 
93
- // Check if directory exists
94
- let dirExists = false
94
+ // Check if home directory exists
95
+ let homeDirExists = false
95
96
  try {
96
- const s = await stat(chosenDir)
97
- dirExists = s.isDirectory()
97
+ const s = await stat(chosenHomeDir)
98
+ homeDirExists = s.isDirectory()
98
99
  } catch {
99
100
  // Does not exist
100
101
  }
101
102
 
102
- if (dirExists) {
103
+ if (homeDirExists) {
103
104
  const confirmed = await this.WorkspacePrompt.confirm({
104
- message: `Directory '${chosenDir}' already exists. Use this existing registry as the home registry for your workspace?`,
105
+ message: `Directory '${chosenHomeDir}' already exists. Use it as the home directory for your workspace?`,
105
106
  defaultValue: true
106
107
  })
107
108
 
@@ -110,11 +111,16 @@ export async function capsule({
110
111
  process.exit(0)
111
112
  }
112
113
  } else {
113
- // Create the directory
114
- await mkdir(chosenDir, { recursive: true })
115
- console.log(chalk.green(`\n āœ“ Created home registry directory: ${chosenDir}\n`))
114
+ // Create the home directory
115
+ await mkdir(chosenHomeDir, { recursive: true })
116
+ console.log(chalk.green(`\n āœ“ Created home directory: ${chosenHomeDir}\n`))
116
117
  }
117
118
 
119
+ // Derive registry dir from home dir
120
+ chosenDir = join(chosenHomeDir, '.o/workspace.foundation')
121
+ await mkdir(chosenDir, { recursive: true })
122
+
123
+ await this.$HomeRegistryConfig.setConfigValue(['homeDir'], chosenHomeDir)
118
124
  await this.$HomeRegistryConfig.setConfigValue(['rootDir'], chosenDir)
119
125
  }
120
126
 
package/caps/RootKey.ts CHANGED
@@ -65,7 +65,7 @@ export async function capsule({
65
65
  console.log(chalk.gray(` Root: ${workspaceConfig?.rootDir || 'unknown'}`))
66
66
  console.log(chalk.gray(''))
67
67
  console.log(chalk.gray(' The root key is an Ed25519 SSH key used to identify this workspace.'))
68
- console.log(chalk.gray(' You can select an existing key from ~/.ssh or create a new one.'))
68
+ console.log(chalk.gray(` You can select an existing key from ${sshDir} or create a new one.`))
69
69
  console.log(chalk.gray(''))
70
70
 
71
71
  // Discover existing Ed25519 keys in ~/.ssh
@@ -65,7 +65,7 @@ export async function capsule({
65
65
  console.log(chalk.gray(` Root: ${workspaceConfig?.rootDir || 'unknown'}`))
66
66
  console.log(chalk.gray(''))
67
67
  console.log(chalk.gray(' The signing key is an Ed25519 SSH key used for code and artifact signing.'))
68
- console.log(chalk.gray(' You can select an existing key from ~/.ssh or create a new one.'))
68
+ console.log(chalk.gray(` You can select an existing key from ${sshDir} or create a new one.`))
69
69
  console.log(chalk.gray(''))
70
70
 
71
71
  // Discover existing Ed25519 keys in ~/.ssh
@@ -93,7 +93,7 @@ export async function capsule({
93
93
  const config = await this.WorkspaceConfig.config as any
94
94
 
95
95
  const api: Record<string, any> = {}
96
- for (const propertyName in config.javascript.api) {
96
+ for (const propertyName in config?.javascript?.api) {
97
97
  api[propertyName] = config.javascript.api[propertyName]
98
98
  }
99
99
  return api
@@ -107,7 +107,7 @@ export async function capsule({
107
107
  const self = this
108
108
 
109
109
  const commands: Record<string, (commandArgs?: any) => Promise<void>> = {}
110
- for (const commandName in cliConfig.cli.commands) {
110
+ for (const commandName in cliConfig?.cli?.commands) {
111
111
  const commandConfig = cliConfig.cli.commands[commandName]
112
112
 
113
113
  commands[commandName] = async function (commandArgs?: any) {
@@ -355,7 +355,7 @@ export async function capsule({
355
355
  const cliConfig = await this.$config.config
356
356
  const cliCommands = await this.cliCommands as Record<string, (args?: any) => Promise<void>>
357
357
 
358
- for (const commandName in cliConfig.cli.commands) {
358
+ for (const commandName in cliConfig?.cli?.commands) {
359
359
  const commandConfig = cliConfig.cli.commands[commandName]
360
360
  const { description, arguments: commandArgs } = commandConfig
361
361
 
@@ -1,4 +1,4 @@
1
- $schema: ../../../../.~o/workspace.foundation/@t44.sh~t44~caps~JsonSchemas/@t44.sh~t44~structs~WorkspaceConfigFile.json
1
+ $schema: ../../../../../../../.~o/workspace.foundation/@t44.sh~t44~caps~JsonSchemas/@t44.sh~t44~structs~WorkspaceConfigFile.json
2
2
  extends:
3
3
  - ./WorkspaceShell.yaml
4
4
  '#t44/structs/WorkspaceCliConfig':
@@ -2,7 +2,6 @@
2
2
  import * as yaml from 'js-yaml'
3
3
  import { readFile, writeFile, access } from 'fs/promises';
4
4
  import { join, resolve, relative, dirname } from 'path'
5
- import { createRequire } from 'module'
6
5
  import chalk from 'chalk'
7
6
 
8
7
  export async function capsule({
@@ -220,7 +219,7 @@ export async function capsule({
220
219
  }
221
220
  capsule['#'] = 't44/caps/WorkspaceConfigFile'
222
221
 
223
- function resolveExtendPath(extendPath: string, configDir: string, workspaceRequire: NodeRequire): string {
222
+ function resolveExtendPath(extendPath: string, configDir: string): string {
224
223
  if (extendPath.startsWith('.')) {
225
224
  return resolve(configDir, extendPath)
226
225
  } else {
@@ -243,9 +242,21 @@ function resolveExtendPath(extendPath: string, configDir: string, workspaceRequi
243
242
  filePath = parts.slice(1).join('/')
244
243
  }
245
244
 
246
- // Resolve the package's package.json to get its directory
247
- const packageJsonPath = workspaceRequire.resolve(`${packageName}/package.json`)
248
- const packageDir = join(packageJsonPath, '..')
245
+ // Walk up from configDir looking for node_modules/<packageName>
246
+ const { existsSync } = require('fs')
247
+ let searchDir = configDir
248
+ let packageDir = ''
249
+ while (searchDir !== dirname(searchDir)) {
250
+ const candidate = join(searchDir, 'node_modules', packageName)
251
+ if (existsSync(join(candidate, 'package.json'))) {
252
+ packageDir = candidate
253
+ break
254
+ }
255
+ searchDir = dirname(searchDir)
256
+ }
257
+ if (!packageDir) {
258
+ throw new Error(`Cannot resolve package '${packageName}' from '${configDir}'. Ensure it is installed in node_modules.`)
259
+ }
249
260
 
250
261
  // Resolve the file path within the package
251
262
  return resolve(packageDir, filePath)
@@ -257,9 +268,6 @@ async function loadConfigWithExtends(configPath: string, workspaceRootDir: strin
257
268
  const mainConfigDir = join(resolve(configPath), '..')
258
269
  let configTree: any = null
259
270
 
260
- // Create a require function relative to workspace root for module resolution
261
- const workspaceRequire = createRequire(join(workspaceRootDir, 'package.json'))
262
-
263
271
  async function loadConfigRecursive(currentPath: string, referencedFrom?: string, chain: string[] = []): Promise<any> {
264
272
  const absolutePath = resolve(currentPath)
265
273
 
@@ -484,7 +492,7 @@ async function loadConfigWithExtends(configPath: string, workspaceRootDir: strin
484
492
  if (config.extends && Array.isArray(config.extends)) {
485
493
  for (const extendPath of config.extends) {
486
494
  // Always use configDir for resolution - it's the directory of the file containing the extends
487
- const resolvedExtendPath = resolveExtendPath(extendPath, configDir, workspaceRequire)
495
+ const resolvedExtendPath = resolveExtendPath(extendPath, configDir)
488
496
  const childNode = await loadConfigRecursive(resolvedExtendPath, absolutePath, currentChain)
489
497
  // Store the original extends value for display
490
498
  childNode.extendsValue = extendPath
@@ -1,4 +1,4 @@
1
- $schema: ../../../../.~o/workspace.foundation/@t44.sh~t44~caps~JsonSchemas/@t44.sh~t44~structs~WorkspaceConfigFile.json
1
+ $schema: ../../../../../../../.~o/workspace.foundation/@t44.sh~t44~caps~JsonSchemas/@t44.sh~t44~structs~WorkspaceConfigFile.json
2
2
  '#t44/structs/WorkspaceShellConfig':
3
3
  env:
4
4
  default: null
package/lib/key.ts CHANGED
@@ -272,6 +272,10 @@ export async function generateEd25519Key(
272
272
  comment: string
273
273
  ): Promise<{ publicKey: string; keyFingerprint: string } | null> {
274
274
  const chalk = (await import('chalk')).default
275
+ const { mkdir } = await import('fs/promises')
276
+ const { dirname } = await import('path')
277
+
278
+ await mkdir(dirname(privateKeyPath), { recursive: true })
275
279
 
276
280
  try {
277
281
  execSync(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "t44",
3
- "version": "0.4.0-rc.7",
3
+ "version": "0.4.0-rc.8",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -85,9 +85,9 @@
85
85
  "@ucanto/principal": "^9.0.3",
86
86
  "@ucanto/server": "^11.0.3",
87
87
  "json-schema-ref-resolver": "^3.0.0",
88
- "@stream44.studio/encapsulate": "^0.4.0-rc.8",
89
- "@stream44.studio/dco": "^0.3.0-rc.7",
90
- "@stream44.studio/t44-blockchaincommons.com": "^0.1.0-rc.9"
88
+ "@stream44.studio/encapsulate": "^0.4.0-rc.9",
89
+ "@stream44.studio/dco": "^0.3.0-rc.9",
90
+ "@stream44.studio/t44-blockchaincommons.com": "^0.1.0-rc.10"
91
91
  },
92
92
  "devDependencies": {
93
93
  "@types/bun": "^1.3.4",
@@ -13,6 +13,10 @@ export async function capsule({
13
13
  schema: {
14
14
  type: 'object',
15
15
  properties: {
16
+ homeDir: {
17
+ type: 'string',
18
+ description: 'Absolute path to the home directory (parent of registry, .ssh, etc).'
19
+ },
16
20
  rootDir: {
17
21
  type: 'string',
18
22
  description: 'Absolute path to the home registry root directory.'
package/workspace.yaml CHANGED
@@ -1,3 +1,3 @@
1
- $schema: ../../../.~o/workspace.foundation/@t44.sh~t44~caps~JsonSchemas/@t44.sh~t44~structs~WorkspaceConfigFile.json
1
+ $schema: ../../../../../../.~o/workspace.foundation/@t44.sh~t44~caps~JsonSchemas/@t44.sh~t44~structs~WorkspaceConfigFile.json
2
2
  extends:
3
3
  - ./caps/WorkspaceConfig.yaml