@mobiman/vector 1.1.4 → 1.1.5
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/LICENSE +1 -1
- package/README.md +17 -1
- package/bin/install.cjs +34 -34
- package/bin/install.cjs.map +1 -1
- package/bin/install.cts +34 -34
- package/commands/vector/join-discord.md +1 -1
- package/core/bin/lib/init.cjs +4 -2
- package/core/bin/lib/init.cjs.map +1 -1
- package/core/bin/lib/init.cts +4 -2
- package/core/bin/lib/init.d.cts.map +1 -1
- package/core/references/checkpoints.md +12 -0
- package/core/references/git-integration.md +5 -5
- package/core/references/git-planning-commit.md +4 -4
- package/core/templates/milestone.md +1 -1
- package/core/templates/project.md +1 -1
- package/core/workflows/new-project.md +14 -4
- package/core/workflows/stats.md +1 -1
- package/package.json +18 -10
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
3
|
# Vector
|
|
4
|
-
**
|
|
4
|
+
**An open-source spec-driven system for building mobile apps with Claude**
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/@mobiman/vector)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://discord.gg/rkU8UTu7dY)
|
|
5
9
|
|
|
6
10
|
---
|
|
7
11
|
|
|
@@ -113,3 +117,15 @@ The orchestrator never does heavy lifting. It spawns agents, waits, integrates r
|
|
|
113
117
|
| `/vector:health [--repair]` | Validate `.planning/` directory integrity, auto-repair with `--repair` |
|
|
114
118
|
| `/vector:stats` | Display project statistics — phases, plans, requirements, git metrics |
|
|
115
119
|
|
|
120
|
+
## Community
|
|
121
|
+
|
|
122
|
+
- [Discord](https://discord.gg/rkU8UTu7dY) — get help, share what you're building, give feedback
|
|
123
|
+
- [Issues](https://github.com/mobiman1/vector/issues) — bug reports and feature requests
|
|
124
|
+
|
|
125
|
+
## Contributing
|
|
126
|
+
|
|
127
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on submitting bug reports, feature requests, and pull requests.
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT — see [LICENSE](LICENSE) for details.
|
package/bin/install.cjs
CHANGED
|
@@ -19,10 +19,10 @@ const reset = '\x1b[0m';
|
|
|
19
19
|
const bold = '\x1b[1m';
|
|
20
20
|
const purple = '\x1b[38;5;135m';
|
|
21
21
|
// Codex config.toml constants
|
|
22
|
-
const
|
|
22
|
+
const VECTOR_CODEX_MARKER = '# Vector Agent Configuration \u2014 managed by core installer';
|
|
23
23
|
// Copilot instructions marker constants
|
|
24
|
-
const
|
|
25
|
-
const
|
|
24
|
+
const VECTOR_COPILOT_INSTRUCTIONS_MARKER = '<!-- Vector Configuration \u2014 managed by core installer -->';
|
|
25
|
+
const VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER = '<!-- /Vector Configuration -->';
|
|
26
26
|
const CODEX_AGENT_SANDBOX = {
|
|
27
27
|
'vector-executor': 'workspace-write',
|
|
28
28
|
'vector-planner': 'workspace-write',
|
|
@@ -253,7 +253,7 @@ const banner = '\n' +
|
|
|
253
253
|
bold + purple + ' VECTOR' + reset + dim + ' by Mobiman' + reset + '\n' +
|
|
254
254
|
'\n' +
|
|
255
255
|
dim + ' v' + package_json_1.default.version + reset + '\n' +
|
|
256
|
-
'
|
|
256
|
+
' An open-source spec-driven system for building mobile apps with Claude\n';
|
|
257
257
|
// Parse --config-dir argument
|
|
258
258
|
function parseConfigDirArg() {
|
|
259
259
|
const configDirIndex = args.findIndex(arg => arg === '--config-dir' || arg === '-c');
|
|
@@ -801,7 +801,7 @@ function generateCodexAgentToml(agentName, agentContent) {
|
|
|
801
801
|
*/
|
|
802
802
|
function generateCodexConfigBlock(agents) {
|
|
803
803
|
const lines = [
|
|
804
|
-
|
|
804
|
+
VECTOR_CODEX_MARKER,
|
|
805
805
|
'',
|
|
806
806
|
];
|
|
807
807
|
for (const { name, description } of agents) {
|
|
@@ -816,8 +816,8 @@ function generateCodexConfigBlock(agents) {
|
|
|
816
816
|
* Strip Vector sections from Codex config.toml content.
|
|
817
817
|
* Returns cleaned content, or null if file would be empty.
|
|
818
818
|
*/
|
|
819
|
-
function
|
|
820
|
-
const markerIndex = content.indexOf(
|
|
819
|
+
function stripVectorFromCodexConfig(content) {
|
|
820
|
+
const markerIndex = content.indexOf(VECTOR_CODEX_MARKER);
|
|
821
821
|
if (markerIndex !== -1) {
|
|
822
822
|
// Has Vector marker — remove everything from marker to EOF
|
|
823
823
|
let before = content.substring(0, markerIndex).trimEnd();
|
|
@@ -857,7 +857,7 @@ function mergeCodexConfig(configPath, vectorBlock) {
|
|
|
857
857
|
return;
|
|
858
858
|
}
|
|
859
859
|
const existing = fs_1.default.readFileSync(configPath, 'utf8');
|
|
860
|
-
const markerIndex = existing.indexOf(
|
|
860
|
+
const markerIndex = existing.indexOf(VECTOR_CODEX_MARKER);
|
|
861
861
|
// Case 2: Has Vector marker — truncate and re-append
|
|
862
862
|
if (markerIndex !== -1) {
|
|
863
863
|
let before = existing.substring(0, markerIndex).trimEnd();
|
|
@@ -885,21 +885,21 @@ function mergeCodexConfig(configPath, vectorBlock) {
|
|
|
885
885
|
* @param {string} vectorContent - Template content (without markers)
|
|
886
886
|
*/
|
|
887
887
|
function mergeCopilotInstructions(filePath, vectorContent) {
|
|
888
|
-
const vectorBlock =
|
|
888
|
+
const vectorBlock = VECTOR_COPILOT_INSTRUCTIONS_MARKER + '\n' +
|
|
889
889
|
vectorContent.trim() + '\n' +
|
|
890
|
-
|
|
890
|
+
VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER;
|
|
891
891
|
// Case 1: No file — create fresh
|
|
892
892
|
if (!fs_1.default.existsSync(filePath)) {
|
|
893
893
|
fs_1.default.writeFileSync(filePath, vectorBlock + '\n');
|
|
894
894
|
return;
|
|
895
895
|
}
|
|
896
896
|
const existing = fs_1.default.readFileSync(filePath, 'utf8');
|
|
897
|
-
const openIndex = existing.indexOf(
|
|
898
|
-
const closeIndex = existing.indexOf(
|
|
897
|
+
const openIndex = existing.indexOf(VECTOR_COPILOT_INSTRUCTIONS_MARKER);
|
|
898
|
+
const closeIndex = existing.indexOf(VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER);
|
|
899
899
|
// Case 2: Has Vector markers — replace between markers
|
|
900
900
|
if (openIndex !== -1 && closeIndex !== -1) {
|
|
901
901
|
const before = existing.substring(0, openIndex).trimEnd();
|
|
902
|
-
const after = existing.substring(closeIndex +
|
|
902
|
+
const after = existing.substring(closeIndex + VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER.length).trimStart();
|
|
903
903
|
let newContent = '';
|
|
904
904
|
if (before)
|
|
905
905
|
newContent += before + '\n\n';
|
|
@@ -920,12 +920,12 @@ function mergeCopilotInstructions(filePath, vectorContent) {
|
|
|
920
920
|
* @param {string} content - File content
|
|
921
921
|
* @returns {string|null} - Cleaned content or null if empty
|
|
922
922
|
*/
|
|
923
|
-
function
|
|
924
|
-
const openIndex = content.indexOf(
|
|
925
|
-
const closeIndex = content.indexOf(
|
|
923
|
+
function stripVectorFromCopilotInstructions(content) {
|
|
924
|
+
const openIndex = content.indexOf(VECTOR_COPILOT_INSTRUCTIONS_MARKER);
|
|
925
|
+
const closeIndex = content.indexOf(VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER);
|
|
926
926
|
if (openIndex !== -1 && closeIndex !== -1) {
|
|
927
927
|
const before = content.substring(0, openIndex).trimEnd();
|
|
928
|
-
const after = content.substring(closeIndex +
|
|
928
|
+
const after = content.substring(closeIndex + VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER.length).trimStart();
|
|
929
929
|
const cleaned = (before + (before && after ? '\n\n' : '') + after).trim();
|
|
930
930
|
if (!cleaned)
|
|
931
931
|
return null;
|
|
@@ -945,12 +945,12 @@ function installCodexConfig(targetDir, agentsSrc) {
|
|
|
945
945
|
const agentEntries = fs_1.default.readdirSync(agentsSrc).filter(f => f.startsWith('vector-') && f.endsWith('.md'));
|
|
946
946
|
const agents = [];
|
|
947
947
|
// Compute the Codex Vector install path (absolute, so subagents with empty $HOME work — #820)
|
|
948
|
-
const
|
|
948
|
+
const codexVectorPath = `${path_1.default.resolve(targetDir, 'core').replace(/\\/g, '/')}/`;
|
|
949
949
|
for (const file of agentEntries) {
|
|
950
950
|
let content = fs_1.default.readFileSync(path_1.default.join(agentsSrc, file), 'utf8');
|
|
951
951
|
// Replace full .claude/core prefix so path resolves to codex Vector install
|
|
952
|
-
content = content.replace(/~\/\.claude\/core\//g,
|
|
953
|
-
content = content.replace(/\$HOME\/\.claude\/core\//g,
|
|
952
|
+
content = content.replace(/~\/\.claude\/core\//g, codexVectorPath);
|
|
953
|
+
content = content.replace(/\$HOME\/\.claude\/core\//g, codexVectorPath);
|
|
954
954
|
const { frontmatter } = extractFrontmatterAndBody(content);
|
|
955
955
|
const name = (frontmatter ? extractFrontmatterField(frontmatter, 'name') : null) || file.replace('.md', '');
|
|
956
956
|
const description = (frontmatter ? extractFrontmatterField(frontmatter, 'description') : null) || '';
|
|
@@ -1658,7 +1658,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1658
1658
|
const configPath = path_1.default.join(targetDir, 'config.toml');
|
|
1659
1659
|
if (fs_1.default.existsSync(configPath)) {
|
|
1660
1660
|
const content = fs_1.default.readFileSync(configPath, 'utf8');
|
|
1661
|
-
const cleaned =
|
|
1661
|
+
const cleaned = stripVectorFromCodexConfig(content);
|
|
1662
1662
|
if (cleaned === null) {
|
|
1663
1663
|
// File is empty after stripping — delete it
|
|
1664
1664
|
fs_1.default.unlinkSync(configPath);
|
|
@@ -1693,7 +1693,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1693
1693
|
const instructionsPath = path_1.default.join(targetDir, 'copilot-instructions.md');
|
|
1694
1694
|
if (fs_1.default.existsSync(instructionsPath)) {
|
|
1695
1695
|
const content = fs_1.default.readFileSync(instructionsPath, 'utf8');
|
|
1696
|
-
const cleaned =
|
|
1696
|
+
const cleaned = stripVectorFromCopilotInstructions(content);
|
|
1697
1697
|
if (cleaned === null) {
|
|
1698
1698
|
fs_1.default.unlinkSync(instructionsPath);
|
|
1699
1699
|
removedCount++;
|
|
@@ -1809,8 +1809,8 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1809
1809
|
const e = entry;
|
|
1810
1810
|
if (e.hooks && Array.isArray(e.hooks)) {
|
|
1811
1811
|
// Filter out Vector hooks
|
|
1812
|
-
const
|
|
1813
|
-
return !
|
|
1812
|
+
const hasVectorHook = e.hooks.some((h) => h.command && (h.command.includes('vector-check-update') || h.command.includes('vector-statusline')));
|
|
1813
|
+
return !hasVectorHook;
|
|
1814
1814
|
}
|
|
1815
1815
|
return true;
|
|
1816
1816
|
});
|
|
@@ -1830,8 +1830,8 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1830
1830
|
settingsHooks[eventName] = settingsHooks[eventName].filter(entry => {
|
|
1831
1831
|
const e = entry;
|
|
1832
1832
|
if (e.hooks && Array.isArray(e.hooks)) {
|
|
1833
|
-
const
|
|
1834
|
-
return !
|
|
1833
|
+
const hasVectorHook = e.hooks.some((h) => h.command && h.command.includes('vector-context-monitor'));
|
|
1834
|
+
return !hasVectorHook;
|
|
1835
1835
|
}
|
|
1836
1836
|
return true;
|
|
1837
1837
|
});
|
|
@@ -2578,11 +2578,11 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
2578
2578
|
if (!hooksMap.SessionStart) {
|
|
2579
2579
|
hooksMap.SessionStart = [];
|
|
2580
2580
|
}
|
|
2581
|
-
const
|
|
2581
|
+
const hasVectorUpdateHook = hooksMap.SessionStart.some((entry) => {
|
|
2582
2582
|
const e = entry;
|
|
2583
2583
|
return e.hooks && Array.isArray(e.hooks) && e.hooks.some((h) => h.command && h.command.includes('vector-check-update'));
|
|
2584
2584
|
});
|
|
2585
|
-
if (!
|
|
2585
|
+
if (!hasVectorUpdateHook) {
|
|
2586
2586
|
hooksMap.SessionStart.push({
|
|
2587
2587
|
hooks: [
|
|
2588
2588
|
{
|
|
@@ -2660,7 +2660,7 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS
|
|
|
2660
2660
|
console.log(`
|
|
2661
2661
|
${green}Done!${reset} Open a blank directory in ${program} and run ${cyan}${command}${reset}.
|
|
2662
2662
|
|
|
2663
|
-
${cyan}Join the community:${reset} https://discord.gg/
|
|
2663
|
+
${cyan}Join the community:${reset} https://discord.gg/rkU8UTu7dY
|
|
2664
2664
|
`);
|
|
2665
2665
|
}
|
|
2666
2666
|
/**
|
|
@@ -2827,12 +2827,12 @@ if (process.env.VECTOR_TEST_MODE) {
|
|
|
2827
2827
|
convertClaudeAgentToCodexAgent,
|
|
2828
2828
|
generateCodexAgentToml,
|
|
2829
2829
|
generateCodexConfigBlock,
|
|
2830
|
-
|
|
2830
|
+
stripVectorFromCodexConfig,
|
|
2831
2831
|
mergeCodexConfig,
|
|
2832
2832
|
installCodexConfig,
|
|
2833
2833
|
convertClaudeCommandToCodexSkill,
|
|
2834
2834
|
convertClaudeToOpencodeFrontmatter,
|
|
2835
|
-
|
|
2835
|
+
VECTOR_CODEX_MARKER,
|
|
2836
2836
|
CODEX_AGENT_SANDBOX,
|
|
2837
2837
|
getDirName,
|
|
2838
2838
|
getGlobalDir,
|
|
@@ -2843,10 +2843,10 @@ if (process.env.VECTOR_TEST_MODE) {
|
|
|
2843
2843
|
convertClaudeCommandToCopilotSkill,
|
|
2844
2844
|
convertClaudeAgentToCopilotAgent,
|
|
2845
2845
|
copyCommandsAsCopilotSkills,
|
|
2846
|
-
|
|
2847
|
-
|
|
2846
|
+
VECTOR_COPILOT_INSTRUCTIONS_MARKER,
|
|
2847
|
+
VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER,
|
|
2848
2848
|
mergeCopilotInstructions,
|
|
2849
|
-
|
|
2849
|
+
stripVectorFromCopilotInstructions,
|
|
2850
2850
|
convertClaudeToAntigravityContent,
|
|
2851
2851
|
convertClaudeCommandToAntigravitySkill,
|
|
2852
2852
|
convertClaudeAgentToAntigravityAgent,
|