hologit 0.47.5 → 0.48.1
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/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +11 -0
- package/README.md +14 -3
- package/commands/inspect.js +162 -0
- package/lib/Workspace.js +44 -9
- package/package.json +3 -3
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hologit",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Jarvus Innovations",
|
|
5
|
+
"email": "hello@jarv.us"
|
|
6
|
+
},
|
|
7
|
+
"metadata": {
|
|
8
|
+
"description": "Skills for working with hologit"
|
|
9
|
+
},
|
|
10
|
+
"plugins": [
|
|
11
|
+
{
|
|
12
|
+
"name": "hologit",
|
|
13
|
+
"source": "./",
|
|
14
|
+
"description": "Hologit configuration and CLI assistance",
|
|
15
|
+
"skills": ["./skills/hologit"]
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hologit",
|
|
3
|
+
"description": "Skills for configuring and using hologit",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Jarvus Innovations",
|
|
7
|
+
"email": "hello@jarv.us"
|
|
8
|
+
},
|
|
9
|
+
"repository": "https://github.com/JarvusInnovations/hologit",
|
|
10
|
+
"license": "MIT"
|
|
11
|
+
}
|
package/README.md
CHANGED
|
@@ -60,19 +60,19 @@ Lenses are configured in `.holo/lenses/` and can be chained together to form com
|
|
|
60
60
|
git holo init
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
1. Create a holobranch:
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
66
|
git holo branch create my-branch
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
1. Add a source:
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
72
|
git holo source create https://github.com/example/repo
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
1. Project your holobranch:
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
78
|
git holo project my-branch
|
|
@@ -97,6 +97,17 @@ See the [Installation Guide](docs/grand-tour/installation.md) and [Grand Tour](d
|
|
|
97
97
|
- **Deployment**: Prepare deployment artifacts with consistent transformations
|
|
98
98
|
- **Code Generation**: Automate code generation and transformation workflows
|
|
99
99
|
|
|
100
|
+
## Claude Code Plugin
|
|
101
|
+
|
|
102
|
+
Hologit includes a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin that gives Claude deep knowledge of hologit's configuration system, CLI, stock lenses, and workflows.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
/plugin marketplace add JarvusInnovations/hologit
|
|
106
|
+
/plugin install hologit@hologit
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Once installed, Claude can help you configure `.holo/` files, set up sources and mappings, choose and configure stock lenses, and debug projection issues.
|
|
110
|
+
|
|
100
111
|
## Documentation
|
|
101
112
|
|
|
102
113
|
- [Installation Guide](docs/grand-tour/installation.md)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
exports.command = 'inspect [holobranch]';
|
|
2
|
+
exports.desc = 'Display the fully resolved hologit configuration';
|
|
3
|
+
|
|
4
|
+
exports.builder = {
|
|
5
|
+
'holobranch': {
|
|
6
|
+
describe: 'Name of a specific holobranch to inspect'
|
|
7
|
+
},
|
|
8
|
+
'ref': {
|
|
9
|
+
describe: 'Commit ref to read configuration from',
|
|
10
|
+
default: 'HEAD'
|
|
11
|
+
},
|
|
12
|
+
'working': {
|
|
13
|
+
describe: 'Use the (possibly uncommitted) contents of the working tree',
|
|
14
|
+
type: 'boolean',
|
|
15
|
+
default: false
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
exports.handler = async function inspect ({
|
|
20
|
+
holobranch,
|
|
21
|
+
ref = 'HEAD',
|
|
22
|
+
working = false
|
|
23
|
+
}) {
|
|
24
|
+
const { Repo } = require('../lib');
|
|
25
|
+
|
|
26
|
+
const repo = await Repo.getFromEnvironment({ ref, working });
|
|
27
|
+
const workspace = await repo.getWorkspace();
|
|
28
|
+
const { name: workspaceName } = await workspace.getCachedConfig();
|
|
29
|
+
|
|
30
|
+
if (holobranch) {
|
|
31
|
+
const branch = workspace.getBranch(holobranch);
|
|
32
|
+
if (!await branch.isDefined()) {
|
|
33
|
+
throw new Error(`holobranch not defined: ${holobranch}`);
|
|
34
|
+
}
|
|
35
|
+
await printBranch(workspace, workspaceName, branch, '');
|
|
36
|
+
} else {
|
|
37
|
+
await printWorkspace(workspace, workspaceName);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
async function printWorkspace (workspace, workspaceName) {
|
|
43
|
+
console.log(`Workspace: ${workspaceName}`);
|
|
44
|
+
|
|
45
|
+
// sources
|
|
46
|
+
const sources = await workspace.getSources();
|
|
47
|
+
if (sources.size) {
|
|
48
|
+
console.log('\nSources:');
|
|
49
|
+
for (const [name, source] of sources) {
|
|
50
|
+
await printSource(source, ' ');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// branches
|
|
55
|
+
const branches = await workspace.getBranches();
|
|
56
|
+
if (branches.size) {
|
|
57
|
+
console.log('\nBranches:');
|
|
58
|
+
for (const [name, branch] of branches) {
|
|
59
|
+
if (await branch.isDefined()) {
|
|
60
|
+
console.log('');
|
|
61
|
+
await printBranch(workspace, workspaceName, branch, ' ');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async function printBranch (workspace, workspaceName, branch, indent) {
|
|
69
|
+
const config = await branch.getCachedConfig();
|
|
70
|
+
const label = config.extend
|
|
71
|
+
? `${branch.name} (extends: ${config.extend})`
|
|
72
|
+
: branch.name;
|
|
73
|
+
console.log(`${indent}${label}`);
|
|
74
|
+
|
|
75
|
+
// mappings
|
|
76
|
+
const mappings = await branch.getMappings();
|
|
77
|
+
if (mappings.size) {
|
|
78
|
+
console.log(`${indent} Mappings (${mappings.size}):`);
|
|
79
|
+
for (const [key, mapping] of mappings) {
|
|
80
|
+
await printMapping(workspace, workspaceName, mapping, `${indent} `);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// lenses
|
|
85
|
+
const lenses = await branch.getLenses();
|
|
86
|
+
if (lenses.size) {
|
|
87
|
+
console.log(`${indent} Lenses (${lenses.size}):`);
|
|
88
|
+
for (const [name, lens] of lenses) {
|
|
89
|
+
await printLens(lens, `${indent} `);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
async function printMapping (workspace, workspaceName, mapping, indent) {
|
|
96
|
+
const config = await mapping.getCachedConfig();
|
|
97
|
+
|
|
98
|
+
const isWorkspace = config.holosource === workspaceName;
|
|
99
|
+
const sourceLabel = isWorkspace
|
|
100
|
+
? `${config.holosource} (workspace)`
|
|
101
|
+
: config.holosource;
|
|
102
|
+
|
|
103
|
+
console.log(`${indent}${mapping.key}`);
|
|
104
|
+
console.log(`${indent} source: ${sourceLabel}`);
|
|
105
|
+
console.log(`${indent} files: ${config.files.join(', ')}`);
|
|
106
|
+
console.log(`${indent} root: ${config.root}`);
|
|
107
|
+
console.log(`${indent} output: ${config.output}`);
|
|
108
|
+
console.log(`${indent} layer: ${config.layer}`);
|
|
109
|
+
|
|
110
|
+
if (config.after) {
|
|
111
|
+
console.log(`${indent} after: ${config.after.join(', ')}`);
|
|
112
|
+
}
|
|
113
|
+
if (config.before) {
|
|
114
|
+
console.log(`${indent} before: ${config.before.join(', ')}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
async function printLens (lens, indent) {
|
|
120
|
+
const config = await lens.getCachedConfig();
|
|
121
|
+
|
|
122
|
+
console.log(`${indent}${lens.name}`);
|
|
123
|
+
|
|
124
|
+
if (config.container) {
|
|
125
|
+
console.log(`${indent} container: ${config.container}`);
|
|
126
|
+
} else if (config.package) {
|
|
127
|
+
console.log(`${indent} package: ${config.package}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const inputRoot = config.input.root === '.' ? '.' : config.input.root;
|
|
131
|
+
const inputFiles = config.input.files.join(', ');
|
|
132
|
+
console.log(`${indent} input: ${inputRoot}/{${inputFiles}}`);
|
|
133
|
+
|
|
134
|
+
const outputRoot = config.output.root === '.' ? '.' : config.output.root;
|
|
135
|
+
console.log(`${indent} output: ${outputRoot}/ (${config.output.merge})`);
|
|
136
|
+
|
|
137
|
+
if (config.after) {
|
|
138
|
+
console.log(`${indent} after: ${config.after.join(', ')}`);
|
|
139
|
+
}
|
|
140
|
+
if (config.before) {
|
|
141
|
+
console.log(`${indent} before: ${config.before.join(', ')}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
async function printSource (source, indent) {
|
|
147
|
+
const config = await source.getCachedConfig();
|
|
148
|
+
|
|
149
|
+
if (config.$workspace) {
|
|
150
|
+
console.log(`${indent}${source.name} (workspace)`);
|
|
151
|
+
} else {
|
|
152
|
+
const ref = config.ref || '';
|
|
153
|
+
const url = config.url || '';
|
|
154
|
+
console.log(`${indent}${source.name}`);
|
|
155
|
+
console.log(`${indent} url: ${url}`);
|
|
156
|
+
console.log(`${indent} ref: ${ref}`);
|
|
157
|
+
|
|
158
|
+
if (config.project && config.project.holobranch) {
|
|
159
|
+
console.log(`${indent} project: ${config.project.holobranch}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
package/lib/Workspace.js
CHANGED
|
@@ -107,24 +107,30 @@ class Workspace extends Configurable {
|
|
|
107
107
|
const children = tree ? await tree.getChildren() : {};
|
|
108
108
|
|
|
109
109
|
|
|
110
|
-
// build unsorted map
|
|
110
|
+
// build unsorted map via recursive discovery
|
|
111
111
|
const childNameRe = /^([^\/]+)\.toml$/;
|
|
112
112
|
const map = new Map();
|
|
113
|
-
for (const childName in children) {
|
|
114
|
-
let name;
|
|
115
113
|
|
|
116
|
-
|
|
114
|
+
for (const childName in children) {
|
|
117
115
|
if (children[childName].isTree) {
|
|
118
|
-
|
|
116
|
+
// skip .lenses directories (e.g. "docs-site.lenses")
|
|
117
|
+
if (childName.endsWith('.lenses')) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// peek inside: if directory contains .toml files it defines
|
|
122
|
+
// a branch's mappings; otherwise it's a namespace — recurse
|
|
123
|
+
await this._discoverBranches(
|
|
124
|
+
children[childName], childName, childNameRe, map
|
|
125
|
+
);
|
|
119
126
|
} else {
|
|
120
127
|
const nameMatches = childName.match(childNameRe);
|
|
121
128
|
if (!nameMatches) {
|
|
122
129
|
continue;
|
|
123
130
|
}
|
|
124
|
-
[,name] = nameMatches;
|
|
131
|
+
const [,name] = nameMatches;
|
|
132
|
+
map.set(name, this.getBranch(name));
|
|
125
133
|
}
|
|
126
|
-
|
|
127
|
-
map.set(name, this.getBranch(name));
|
|
128
134
|
}
|
|
129
135
|
|
|
130
136
|
|
|
@@ -133,6 +139,35 @@ class Workspace extends Configurable {
|
|
|
133
139
|
return map;
|
|
134
140
|
}
|
|
135
141
|
|
|
142
|
+
async _discoverBranches (tree, prefix, childNameRe, map) {
|
|
143
|
+
const treeChildren = await tree.getChildren();
|
|
144
|
+
|
|
145
|
+
// check if this directory contains any .toml files directly
|
|
146
|
+
let hasTomlFiles = false;
|
|
147
|
+
for (const name in treeChildren) {
|
|
148
|
+
if (!treeChildren[name].isTree && childNameRe.test(name)) {
|
|
149
|
+
hasTomlFiles = true;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (hasTomlFiles) {
|
|
155
|
+
// directory contains mappings — it defines a branch
|
|
156
|
+
map.set(prefix, this.getBranch(prefix));
|
|
157
|
+
} else {
|
|
158
|
+
// no .toml files — it's a namespace, recurse into subdirectories
|
|
159
|
+
for (const name in treeChildren) {
|
|
160
|
+
if (!treeChildren[name].isTree || name.endsWith('.lenses')) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await this._discoverBranches(
|
|
165
|
+
treeChildren[name], prefix + '/' + name, childNameRe, map
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
136
171
|
getSource (name) {
|
|
137
172
|
let cache = sourceCache.get(this);
|
|
138
173
|
const cachedSource = cache && cache.get(name);
|
|
@@ -173,7 +208,7 @@ class Workspace extends Configurable {
|
|
|
173
208
|
|
|
174
209
|
// read tree
|
|
175
210
|
const tree = await this.root.getSubtree(`.holo/sources`);
|
|
176
|
-
const children = await tree.getChildren();
|
|
211
|
+
const children = tree ? await tree.getChildren() : {};
|
|
177
212
|
|
|
178
213
|
|
|
179
214
|
// build unsorted map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hologit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.1",
|
|
4
4
|
"description": "Hologit automates the projection of layered composite file trees based on flat, declarative plans",
|
|
5
5
|
"repository": "https://github.com/JarvusInnovations/hologit",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@iarna/toml": "^2.2.5",
|
|
13
13
|
"async-exit-hook": "^2.0.1",
|
|
14
|
-
"axios": "^1.13.
|
|
14
|
+
"axios": "^1.13.5",
|
|
15
15
|
"chokidar": "^5.0.0",
|
|
16
16
|
"debounce": "^3.0.0",
|
|
17
17
|
"fb-watchman": "^2.0.2",
|
|
18
18
|
"git-client": "^1.9.4",
|
|
19
19
|
"hab-client": "^1.1.3",
|
|
20
20
|
"handlebars": "^4.7.8",
|
|
21
|
-
"minimatch": "^10.
|
|
21
|
+
"minimatch": "^10.2.2",
|
|
22
22
|
"mz": "^2.7.0",
|
|
23
23
|
"mz-modules": "^2.1.0",
|
|
24
24
|
"object-squish": "^1.1.0",
|