@meshxdata/fops 0.0.1 → 0.0.3
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 +62 -40
- package/package.json +4 -3
- package/src/agent/agent.js +26 -34
- package/src/agent/context.js +155 -98
- package/src/agent/llm.js +54 -11
- package/src/auth/coda.js +128 -0
- package/src/auth/index.js +1 -0
- package/src/commands/index.js +23 -9
- package/src/doctor.js +143 -15
- package/src/plugins/api.js +9 -0
- package/src/plugins/index.js +1 -0
- package/src/plugins/knowledge.js +124 -0
- package/src/plugins/registry.js +1 -0
- package/src/setup/setup.js +10 -5
- package/src/setup/wizard.js +15 -11
- package/src/shell.js +2 -2
- package/src/skills/foundation/SKILL.md +200 -66
- package/src/ui/input.js +31 -34
- package/src/ui/spinner.js +36 -10
- package/STRUCTURE.md +0 -43
- package/src/agent/agent.test.js +0 -233
- package/src/agent/context.test.js +0 -81
- package/src/agent/llm.test.js +0 -139
- package/src/auth/keychain.test.js +0 -185
- package/src/auth/login.test.js +0 -192
- package/src/auth/oauth.test.js +0 -118
- package/src/auth/resolve.test.js +0 -153
- package/src/config.test.js +0 -70
- package/src/doctor.test.js +0 -134
- package/src/plugins/api.test.js +0 -95
- package/src/plugins/discovery.test.js +0 -92
- package/src/plugins/hooks.test.js +0 -118
- package/src/plugins/manifest.test.js +0 -106
- package/src/plugins/registry.test.js +0 -43
- package/src/plugins/skills.test.js +0 -173
- package/src/project.test.js +0 -196
- package/src/setup/aws.test.js +0 -280
- package/src/shell.test.js +0 -72
- package/src/ui/banner.test.js +0 -97
- package/src/ui/spinner.test.js +0 -29
package/src/shell.test.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
vi.mock("execa", () => ({
|
|
4
|
-
execa: vi.fn(() => Promise.resolve({ stdout: "", exitCode: 0 })),
|
|
5
|
-
}));
|
|
6
|
-
|
|
7
|
-
const { execa } = await import("execa");
|
|
8
|
-
const { make, dockerCompose } = await import("./shell.js");
|
|
9
|
-
|
|
10
|
-
describe("shell", () => {
|
|
11
|
-
describe("make", () => {
|
|
12
|
-
it("calls execa with make, target, and cwd", async () => {
|
|
13
|
-
await make("/project", "up");
|
|
14
|
-
expect(execa).toHaveBeenCalledWith("make", ["up"], { cwd: "/project", stdio: "inherit" });
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it("passes extra args", async () => {
|
|
18
|
-
await make("/project", "logs", ["-f"]);
|
|
19
|
-
expect(execa).toHaveBeenCalledWith("make", ["logs", "-f"], { cwd: "/project", stdio: "inherit" });
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("uses empty args by default", async () => {
|
|
23
|
-
await make("/root", "build");
|
|
24
|
-
expect(execa).toHaveBeenCalledWith("make", ["build"], { cwd: "/root", stdio: "inherit" });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("propagates execa rejection", async () => {
|
|
28
|
-
execa.mockRejectedValueOnce(new Error("make failed"));
|
|
29
|
-
await expect(make("/project", "bad-target")).rejects.toThrow("make failed");
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("passes multiple args correctly", async () => {
|
|
33
|
-
await make("/project", "deploy", ["--env=prod", "--verbose", "--dry-run"]);
|
|
34
|
-
expect(execa).toHaveBeenCalledWith(
|
|
35
|
-
"make",
|
|
36
|
-
["deploy", "--env=prod", "--verbose", "--dry-run"],
|
|
37
|
-
{ cwd: "/project", stdio: "inherit" }
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("dockerCompose", () => {
|
|
43
|
-
it("calls execa with docker compose and args", async () => {
|
|
44
|
-
await dockerCompose("/project", ["ps", "--format", "json"]);
|
|
45
|
-
expect(execa).toHaveBeenCalledWith("docker", ["compose", "ps", "--format", "json"], {
|
|
46
|
-
cwd: "/project",
|
|
47
|
-
stdio: "inherit",
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("prefixes args with compose subcommand", async () => {
|
|
52
|
-
await dockerCompose("/project", ["up", "-d"]);
|
|
53
|
-
expect(execa).toHaveBeenCalledWith("docker", ["compose", "up", "-d"], {
|
|
54
|
-
cwd: "/project",
|
|
55
|
-
stdio: "inherit",
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("propagates execa rejection", async () => {
|
|
60
|
-
execa.mockRejectedValueOnce(new Error("docker failed"));
|
|
61
|
-
await expect(dockerCompose("/project", ["up"])).rejects.toThrow("docker failed");
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("handles empty args array", async () => {
|
|
65
|
-
await dockerCompose("/project", []);
|
|
66
|
-
expect(execa).toHaveBeenCalledWith("docker", ["compose"], {
|
|
67
|
-
cwd: "/project",
|
|
68
|
-
stdio: "inherit",
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
});
|
package/src/ui/banner.test.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { QUOTES, getRandomQuote, BANNER, renderBanner } from "./banner.js";
|
|
3
|
-
|
|
4
|
-
describe("ui/banner", () => {
|
|
5
|
-
describe("QUOTES", () => {
|
|
6
|
-
it("is a non-empty array of strings", () => {
|
|
7
|
-
expect(Array.isArray(QUOTES)).toBe(true);
|
|
8
|
-
expect(QUOTES.length).toBeGreaterThan(10);
|
|
9
|
-
for (const q of QUOTES) {
|
|
10
|
-
expect(typeof q).toBe("string");
|
|
11
|
-
expect(q.length).toBeGreaterThan(0);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("has no duplicate quotes", () => {
|
|
16
|
-
const unique = new Set(QUOTES);
|
|
17
|
-
expect(unique.size).toBe(QUOTES.length);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("includes Mr Robot themed quotes", () => {
|
|
21
|
-
const hasMrRobot = QUOTES.some((q) => q.includes("zero-day") || q.includes("daemon") || q.includes("root access"));
|
|
22
|
-
expect(hasMrRobot).toBe(true);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("includes ops humor quotes", () => {
|
|
26
|
-
const hasOps = QUOTES.some((q) => q.includes("container") || q.includes("production") || q.includes("Docker"));
|
|
27
|
-
expect(hasOps).toBe(true);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
describe("getRandomQuote", () => {
|
|
32
|
-
it("returns a string from QUOTES", () => {
|
|
33
|
-
const quote = getRandomQuote();
|
|
34
|
-
expect(typeof quote).toBe("string");
|
|
35
|
-
expect(QUOTES).toContain(quote);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("returns a value on every call", () => {
|
|
39
|
-
for (let i = 0; i < 20; i++) {
|
|
40
|
-
const quote = getRandomQuote();
|
|
41
|
-
expect(typeof quote).toBe("string");
|
|
42
|
-
expect(quote.length).toBeGreaterThan(0);
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe("BANNER", () => {
|
|
48
|
-
it("contains ASCII art block characters", () => {
|
|
49
|
-
expect(BANNER).toContain("█");
|
|
50
|
-
expect(BANNER).toContain("╗");
|
|
51
|
-
expect(BANNER).toContain("╚");
|
|
52
|
-
expect(BANNER).toContain("═");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("is multi-line", () => {
|
|
56
|
-
const lines = BANNER.split("\n").filter((l) => l.trim());
|
|
57
|
-
expect(lines.length).toBeGreaterThanOrEqual(5);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("has substantial length", () => {
|
|
61
|
-
expect(BANNER.length).toBeGreaterThan(100);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
describe("renderBanner", () => {
|
|
66
|
-
it("prints banner to stdout", () => {
|
|
67
|
-
const spy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
68
|
-
renderBanner();
|
|
69
|
-
expect(spy).toHaveBeenCalled();
|
|
70
|
-
const output = spy.mock.calls.map((c) => c[0]).join("\n");
|
|
71
|
-
expect(output).toContain("Foundation OPS CLI");
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("displays version", () => {
|
|
75
|
-
const spy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
76
|
-
renderBanner();
|
|
77
|
-
const output = spy.mock.calls.map((c) => c[0]).join("\n");
|
|
78
|
-
expect(output).toMatch(/v\d+\.\d+/);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("displays exit instructions", () => {
|
|
82
|
-
const spy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
83
|
-
renderBanner();
|
|
84
|
-
const output = spy.mock.calls.map((c) => c[0]).join("\n");
|
|
85
|
-
expect(output).toContain("/exit");
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("displays a quote", () => {
|
|
89
|
-
const spy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
90
|
-
renderBanner();
|
|
91
|
-
const output = spy.mock.calls.map((c) => c[0]).join("\n");
|
|
92
|
-
// At least one quote should be present
|
|
93
|
-
const hasQuote = QUOTES.some((q) => output.includes(q));
|
|
94
|
-
expect(hasQuote).toBe(true);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
});
|
package/src/ui/spinner.test.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { VERBS } from "./spinner.js";
|
|
3
|
-
|
|
4
|
-
describe("ui/spinner", () => {
|
|
5
|
-
describe("VERBS", () => {
|
|
6
|
-
it("is a non-empty array of strings", () => {
|
|
7
|
-
expect(Array.isArray(VERBS)).toBe(true);
|
|
8
|
-
expect(VERBS.length).toBeGreaterThan(5);
|
|
9
|
-
for (const v of VERBS) {
|
|
10
|
-
expect(typeof v).toBe("string");
|
|
11
|
-
expect(v.length).toBeGreaterThan(0);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("has no duplicates", () => {
|
|
16
|
-
const unique = new Set(VERBS);
|
|
17
|
-
expect(unique.size).toBe(VERBS.length);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("contains hacker-themed verbs", () => {
|
|
21
|
-
const hasHacker = VERBS.some((v) =>
|
|
22
|
-
v.toLowerCase().includes("hack") ||
|
|
23
|
-
v.toLowerCase().includes("decrypt") ||
|
|
24
|
-
v.toLowerCase().includes("crack")
|
|
25
|
-
);
|
|
26
|
-
expect(hasHacker).toBe(true);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
});
|