Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions packages/extension/scripts/amicode_fixture_seed.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,37 @@ export function seedAmicodeSandbox(dir) {
views: { home: "grid" },
});

// --- connections (credentials + status cache + custom registry) -------------
// company-compute + slack CONNECTED. validated_at is seeded one minute
// before seed-NOW: the 24h staleness clock MUST read fresh, or the fork's
// GET kicks a background network revalidation (probe → cache write) whose
// landing races the later reads — observed as the CI offline-flag flake.
// Credential mtimes pinned to the SAME instant so the 5s edit-slack also
// reads fresh. Tokens are inert seed values — no probe runs, no probe is
// kicked. The wall-clock validated_at is normalized to <NOW> at replay.
const ccValidatedAt = new Date(Date.now() - 60_000);
const ccValidatedIso = ccValidatedAt.toISOString();
writeJson(join(amico, "cloud.json"), { base_url: "https://solve.example.internal", token: "tok-cc-seed" });
writeJson(join(amico, "slack.json"), { token: "xoxb-seed-token" });
utimesSync(join(amico, "cloud.json"), ccValidatedAt, ccValidatedAt);
utimesSync(join(amico, "slack.json"), ccValidatedAt, ccValidatedAt);
writeJson(join(amico, "connections.json"), {
"company-compute": {
state: "connected",
identity: "aaron",
entitlements: ["hpc"],
validated_at: ccValidatedIso,
},
slack: { state: "connected", identity: "aaron@example", validated_at: ccValidatedIso },
});
// one custom connection (the remove-fixture target)
writeJson(join(dir, "custom-connections.json"), [
{ id: "custom-seed1", name: "Lab QPU", token: "tok-qpu", url: "https://qpu.example" },
]);

// --- projects (defaultParentDir is HOME-based — HOME rides the env overlay) --
mkdirSync(join(dir, "AmicodeProjects", "prior-project"), { recursive: true });

// --- stub PATH: `amico` exists (fixed output → deterministic approve fixture),
// `amico-vault` does NOT (forces the CLI-less scanMounts path on both
// sides, so fixtures never depend on a real CLI being installed). ----------
Expand Down Expand Up @@ -346,6 +377,16 @@ export function seedAmicodeSandbox(dir) {
AMICODE_LIBRARY_DIR: libraryDir,
AMICODE_WIDGETS_DIR: widgetsDir,
AMICODE_DASHBOARD_FILE: join(amico, "dashboard.json"),
AMICODE_CONNECTIONS_FILE: join(amico, "connections.json"),
AMICO_CUSTOM_CONNECTIONS_FILE: join(dir, "custom-connections.json"),
AMICO_CLOUD_FILE: join(amico, "cloud.json"),
AMICO_SLACK_FILE: join(amico, "slack.json"),
AMICO_PASQAL_FILE: join(amico, "pasqal.json"),
AMICO_GITHUB_FILE: join(amico, "github.json"),
AMICO_LINEAR_FILE: join(amico, "linear.json"),
AMICO_GOOGLE_FILE: join(amico, "google.json"),
AMICO_GOOGLE_DRIVE_FILE: join(amico, "google-drive.json"),
HOME: dir, // the projects default parent + CLI candidate paths are HOME-based
PATH: stubbin,
},
};
Expand Down
91 changes: 91 additions & 0 deletions packages/extension/scripts/record_amicode_fixtures.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,97 @@ const REQUESTS = [
body: { widget: "not-a-list" },
name: "dashboard save — bad_body refusal",
},
// ── connections + projects (slice 6) — network-free shapes only: status
// reads, fs-only mutations, and pre-probe refusals. Live-provider probes
// (real Slack/GitHub/Google/Linear endpoints) are deliberately NOT
// golden-tested — they're covered by the fork's unit suites with
// injectable fetch, ported with the module.
{ method: "GET", path: "/amicode/connections", name: "connections — seeded connected + needs-key states" },
{ method: "GET", path: "/amicode/connections/catalog", name: "connections catalog — configured filtered out" },
{ method: "POST", path: "/amicode/connections/credential", body: {}, name: "credential submit — empty body refusal" },
{
method: "POST",
path: "/amicode/connections/credential",
body: { id: "bogus-connector", token: "x" },
name: "credential submit — unknown_connection",
},
{
method: "POST",
path: "/amicode/connections/credential",
body: { id: "company-compute", base_url: "ftp://not-http", token: "t" },
name: "credential submit — non-http base_url refusal",
},
{
method: "POST",
path: "/amicode/connections/credential",
body: { id: "slack", token: " " },
name: "credential submit — empty token refusal",
},
{
method: "POST",
path: "/amicode/connections/disconnect",
body: { id: "slack" },
name: "disconnect — clears seeded slack credential",
},
{
method: "POST",
path: "/amicode/connections/disconnect",
body: { id: "no-such-connector" },
name: "disconnect — unknown id refusal",
},
{
method: "POST",
path: "/amicode/connections/revalidate",
body: { id: "github" },
name: "revalidate — no credential → needs-key (pre-probe)",
},
{
method: "POST",
path: "/amicode/connections/revalidate",
body: { id: "githubx" },
name: "revalidate — unknown id refusal",
},
{
method: "POST",
path: "/amicode/connections/choose-project",
body: { id: "pasqal-cloud", project_id: "p1" },
name: "choose-project — no pending selection",
},
// NOTE — POST /amicode/connections/auth is deliberately NOT golden-tested:
// the route exists in the fork's current source but post-dates the vendored
// pin (v1.18.10-amicode.11 serves the SPA catch-all for it). The port
// implements it from source; its refusal shapes are unit-tested in
// amicode_service_connections.test.ts, and it joins the golden arc at the
// next pin bump.
{
method: "POST",
path: "/amicode/connections/add-custom",
body: { name: "half-filled" },
name: "add-custom — missing token refusal",
},
{
method: "POST",
path: "/amicode/connections/remove",
body: { id: "custom-seed1" },
name: "remove — custom connection removed",
},
{
method: "POST",
path: "/amicode/connections/remove",
body: { id: "custom-gone" },
name: "remove — unknown custom id refusal",
},
{ method: "GET", path: "/amicode/connections", name: "connections — post-disconnect state" },
{ method: "POST", path: "/amicode/project", body: { name: "My New Project" }, name: "project create — mkdir (git absent, best-effort)" },
{ method: "POST", path: "/amicode/project", body: { name: "My New Project" }, name: "project create — collision" },
{ method: "POST", path: "/amicode/project", body: { name: " " }, name: "project create — empty-name refusal" },
{
method: "POST",
path: "/amicode/project",
body: { name: "Ok", parentDir: "relative/path" },
name: "project create — non-absolute parent refusal",
},
{ method: "GET", path: "/amicode/projects", name: "projects list — prior + created" },
];

async function main() {
Expand Down
Loading
Loading