@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Lex Christopherson
3
+ Copyright (c) 2025 Steven Becerra
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,7 +1,11 @@
1
1
  <div align="center">
2
2
 
3
3
  # Vector
4
- **A meta-prompting and context engineering development system for iOS**
4
+ **An open-source spec-driven system for building mobile apps with Claude**
5
+
6
+ [![npm](https://img.shields.io/npm/v/@mobiman/vector)](https://www.npmjs.com/package/@mobiman/vector)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
+ [![Discord](https://img.shields.io/discord/rkU8UTu7dY?label=Discord&logo=discord&logoColor=white)](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 GSD_CODEX_MARKER = '# Vector Agent Configuration \u2014 managed by core installer';
22
+ const VECTOR_CODEX_MARKER = '# Vector Agent Configuration \u2014 managed by core installer';
23
23
  // Copilot instructions marker constants
24
- const GSD_COPILOT_INSTRUCTIONS_MARKER = '<!-- Vector Configuration \u2014 managed by core installer -->';
25
- const GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER = '<!-- /Vector Configuration -->';
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
- ' A meta-prompting and context engineering development system for iOS\n';
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
- GSD_CODEX_MARKER,
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 stripGsdFromCodexConfig(content) {
820
- const markerIndex = content.indexOf(GSD_CODEX_MARKER);
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(GSD_CODEX_MARKER);
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 = GSD_COPILOT_INSTRUCTIONS_MARKER + '\n' +
888
+ const vectorBlock = VECTOR_COPILOT_INSTRUCTIONS_MARKER + '\n' +
889
889
  vectorContent.trim() + '\n' +
890
- GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER;
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(GSD_COPILOT_INSTRUCTIONS_MARKER);
898
- const closeIndex = existing.indexOf(GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER);
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 + GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER.length).trimStart();
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 stripGsdFromCopilotInstructions(content) {
924
- const openIndex = content.indexOf(GSD_COPILOT_INSTRUCTIONS_MARKER);
925
- const closeIndex = content.indexOf(GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER);
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 + GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER.length).trimStart();
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 codexGsdPath = `${path_1.default.resolve(targetDir, 'core').replace(/\\/g, '/')}/`;
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, codexGsdPath);
953
- content = content.replace(/\$HOME\/\.claude\/core\//g, codexGsdPath);
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 = stripGsdFromCodexConfig(content);
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 = stripGsdFromCopilotInstructions(content);
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 hasGsdHook = e.hooks.some((h) => h.command && (h.command.includes('vector-check-update') || h.command.includes('vector-statusline')));
1813
- return !hasGsdHook;
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 hasGsdHook = e.hooks.some((h) => h.command && h.command.includes('vector-context-monitor'));
1834
- return !hasGsdHook;
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 hasGsdUpdateHook = hooksMap.SessionStart.some((entry) => {
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 (!hasGsdUpdateHook) {
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/gsd
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
- stripGsdFromCodexConfig,
2830
+ stripVectorFromCodexConfig,
2831
2831
  mergeCodexConfig,
2832
2832
  installCodexConfig,
2833
2833
  convertClaudeCommandToCodexSkill,
2834
2834
  convertClaudeToOpencodeFrontmatter,
2835
- GSD_CODEX_MARKER,
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
- GSD_COPILOT_INSTRUCTIONS_MARKER,
2847
- GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER,
2846
+ VECTOR_COPILOT_INSTRUCTIONS_MARKER,
2847
+ VECTOR_COPILOT_INSTRUCTIONS_CLOSE_MARKER,
2848
2848
  mergeCopilotInstructions,
2849
- stripGsdFromCopilotInstructions,
2849
+ stripVectorFromCopilotInstructions,
2850
2850
  convertClaudeToAntigravityContent,
2851
2851
  convertClaudeCommandToAntigravitySkill,
2852
2852
  convertClaudeAgentToAntigravityAgent,