@meshxdata/fops 0.0.5 → 0.0.6

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.

Potentially problematic release.


This version of @meshxdata/fops might be problematic. Click here for more details.

Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/src/commands/index.js +115 -0
  3. package/src/doctor.js +7 -0
  4. package/src/plugins/bundled/coda/auth.js +79 -0
  5. package/src/plugins/bundled/coda/client.js +187 -0
  6. package/src/plugins/bundled/coda/fops.plugin.json +7 -0
  7. package/src/plugins/bundled/coda/index.js +284 -0
  8. package/src/plugins/bundled/coda/package.json +3 -0
  9. package/src/plugins/bundled/coda/skills/coda/SKILL.md +82 -0
  10. package/src/plugins/bundled/cursor/fops.plugin.json +7 -0
  11. package/src/plugins/bundled/cursor/index.js +432 -0
  12. package/src/plugins/bundled/cursor/package.json +1 -0
  13. package/src/plugins/bundled/cursor/skills/cursor/SKILL.md +48 -0
  14. package/src/plugins/bundled/fops-plugin-1password/fops.plugin.json +7 -0
  15. package/src/plugins/bundled/fops-plugin-1password/index.js +239 -0
  16. package/src/plugins/bundled/fops-plugin-1password/lib/env.js +100 -0
  17. package/src/plugins/bundled/fops-plugin-1password/lib/op.js +111 -0
  18. package/src/plugins/bundled/fops-plugin-1password/lib/setup.js +235 -0
  19. package/src/plugins/bundled/fops-plugin-1password/lib/sync.js +61 -0
  20. package/src/plugins/bundled/fops-plugin-1password/package.json +1 -0
  21. package/src/plugins/bundled/fops-plugin-1password/skills/1password/SKILL.md +79 -0
  22. package/src/plugins/bundled/fops-plugin-ecr/fops.plugin.json +7 -0
  23. package/src/plugins/bundled/fops-plugin-ecr/index.js +302 -0
  24. package/src/plugins/bundled/fops-plugin-ecr/lib/aws.js +147 -0
  25. package/src/plugins/bundled/fops-plugin-ecr/lib/images.js +73 -0
  26. package/src/plugins/bundled/fops-plugin-ecr/lib/setup.js +180 -0
  27. package/src/plugins/bundled/fops-plugin-ecr/lib/sync.js +74 -0
  28. package/src/plugins/bundled/fops-plugin-ecr/package.json +1 -0
  29. package/src/plugins/bundled/fops-plugin-ecr/skills/ecr/SKILL.md +105 -0
  30. package/src/plugins/bundled/fops-plugin-memory/fops.plugin.json +7 -0
  31. package/src/plugins/bundled/fops-plugin-memory/index.js +148 -0
  32. package/src/plugins/bundled/fops-plugin-memory/lib/relevance.js +72 -0
  33. package/src/plugins/bundled/fops-plugin-memory/lib/store.js +75 -0
  34. package/src/plugins/bundled/fops-plugin-memory/package.json +1 -0
  35. package/src/plugins/bundled/fops-plugin-memory/skills/memory/SKILL.md +58 -0
  36. package/src/plugins/loader.js +40 -0
  37. package/src/setup/setup.js +2 -0
  38. package/src/setup/wizard.js +12 -0
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: memory
3
+ description: Persistent memory across agent sessions
4
+ ---
5
+
6
+ ## Agent Memory
7
+
8
+ You have persistent memory across sessions. Relevant memories are automatically recalled into your context when they match the user's query. You can also save new memories during conversations.
9
+
10
+ ## When to Save Memories
11
+
12
+ Save a memory when you learn something that would be useful in **future sessions**:
13
+
14
+ - **Resolved issues**: "postgres init fails if vault isn't started first — start vault before running migrations"
15
+ - **User preferences**: "user prefers to rebuild images rather than pull from ECR"
16
+ - **Stack quirks**: "trino takes 30-45 seconds to become healthy after container starts"
17
+ - **Configuration discoveries**: "frontend needs NEXT_PUBLIC_API_URL set to http://localhost:9001 in .env"
18
+ - **Debugging insights**: "backend OOM usually means too many Kafka consumers — reduce KAFKA_MAX_POLL_RECORDS"
19
+ - **Workflow patterns**: "user runs fops down && fops up to reset state, not just restart"
20
+
21
+ ## How to Save
22
+
23
+ ```bash
24
+ fops memory save "description of what you learned"
25
+ fops memory save "postgres needs vault running first" --tag postgres --tag startup
26
+ ```
27
+
28
+ Tags help with recall but are optional. The text itself is searched.
29
+
30
+ ## When NOT to Save
31
+
32
+ - Transient state (container is currently down, an image was just pulled)
33
+ - Information already in the stack context (service ports, container health)
34
+ - Generic knowledge (Docker commands, AWS docs)
35
+ - Anything the user explicitly asks you not to remember
36
+
37
+ ## Commands
38
+
39
+ ```bash
40
+ fops memory save "text" [--tag tag1 --tag tag2] # Save a memory
41
+ fops memory list # List all memories
42
+ fops memory search "query" # Search by relevance
43
+ fops memory forget <id> # Remove a memory
44
+ fops memory clear # Clear all memories
45
+ fops mem ... # Shorthand alias
46
+ ```
47
+
48
+ ## Recall
49
+
50
+ Memories are automatically recalled via the knowledge system. When the user's message matches stored memories, they appear in your context under "Agent Memory". You don't need to explicitly search — relevant memories are injected per turn.
51
+
52
+ ## Housekeeping
53
+
54
+ If you notice a recalled memory is outdated or incorrect, suggest removing it:
55
+
56
+ ```bash
57
+ fops memory forget abc123
58
+ ```
@@ -10,6 +10,45 @@ import { loadBuiltinAgents } from "../agent/agents.js";
10
10
 
11
11
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
12
 
13
+ /**
14
+ * Sync bundled plugins from src/plugins/bundled/ to ~/.fops/plugins/.
15
+ * Installs missing plugins and updates existing ones when the bundled version is newer.
16
+ */
17
+ function syncBundledPlugins() {
18
+ const bundledDir = path.join(__dirname, "bundled");
19
+ if (!fs.existsSync(bundledDir)) return;
20
+
21
+ const globalDir = path.join(os.homedir(), ".fops", "plugins");
22
+ fs.mkdirSync(globalDir, { recursive: true });
23
+
24
+ const entries = fs.readdirSync(bundledDir, { withFileTypes: true });
25
+ for (const entry of entries) {
26
+ if (!entry.isDirectory()) continue;
27
+ const srcDir = path.join(bundledDir, entry.name);
28
+ const manifestPath = path.join(srcDir, "fops.plugin.json");
29
+ if (!fs.existsSync(manifestPath)) continue;
30
+
31
+ let manifest;
32
+ try { manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")); } catch { continue; }
33
+
34
+ const destDir = path.join(globalDir, entry.name);
35
+ const destManifest = path.join(destDir, "fops.plugin.json");
36
+
37
+ // Skip if installed version is same or newer
38
+ if (fs.existsSync(destManifest)) {
39
+ try {
40
+ const existing = JSON.parse(fs.readFileSync(destManifest, "utf8"));
41
+ if (existing.version >= manifest.version) continue;
42
+ } catch {
43
+ // corrupt manifest — overwrite
44
+ }
45
+ }
46
+
47
+ // Copy plugin to ~/.fops/plugins/<name>/
48
+ fs.cpSync(srcDir, destDir, { recursive: true });
49
+ }
50
+ }
51
+
13
52
  /**
14
53
  * Ensure ~/.fops/plugins/node_modules symlinks to the CLI's node_modules.
15
54
  * This lets global plugins resolve bare imports (chalk, execa, inquirer, etc.)
@@ -106,6 +145,7 @@ async function loadBuiltinPlugins(registry) {
106
145
  * Returns a populated PluginRegistry.
107
146
  */
108
147
  export async function loadPlugins() {
148
+ syncBundledPlugins();
109
149
  ensurePluginNodeModules();
110
150
  const registry = createRegistry();
111
151
  loadBuiltinAgents(registry);
@@ -109,6 +109,7 @@ export function runSetup(dir, opts = {}) {
109
109
  } catch {
110
110
  console.log(chalk.yellow("\n⚠ Some images failed to download."));
111
111
  }
112
+ console.log("");
112
113
  console.log(chalk.green("Setup complete. Run: fops up"));
113
114
  return;
114
115
  }
@@ -162,6 +163,7 @@ export function runSetup(dir, opts = {}) {
162
163
  console.log(chalk.dim(" Then re-run: fops init --download\n"));
163
164
  }
164
165
  }
166
+ console.log("");
165
167
  console.log(chalk.green("Setup complete. Run: fops up"));
166
168
  })();
167
169
  }
@@ -130,6 +130,18 @@ export async function runInitWizard() {
130
130
  hasAws = await installTool("AWS CLI", { brew: "awscli", winget: "Amazon.AWSCLI" });
131
131
  }
132
132
 
133
+ // 1Password desktop app (optional — needed for CLI integration)
134
+ const has1PwdApp = process.platform === "darwin"
135
+ ? fs.existsSync("/Applications/1Password.app")
136
+ : process.platform === "win32"
137
+ ? fs.existsSync(path.join(process.env.LOCALAPPDATA || "", "1Password", "app", "8", "1Password.exe"))
138
+ : false;
139
+ if (has1PwdApp) console.log(chalk.green(" ✓ 1Password"));
140
+ else {
141
+ console.log(chalk.yellow(" ⚠ 1Password") + chalk.dim(" — desktop app needed for CLI integration"));
142
+ await installTool("1Password", { brewCask: "1password", winget: "AgileBits.1Password" });
143
+ }
144
+
133
145
  // 1Password CLI (optional)
134
146
  if (hasOp) console.log(chalk.green(" ✓ 1Password CLI"));
135
147
  else {