swipium 1.0.0
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 +21 -0
- package/README.md +295 -0
- package/dist/appMap/automationLink.js +74 -0
- package/dist/appMap/automationLink.js.map +1 -0
- package/dist/appMap/build.js +193 -0
- package/dist/appMap/build.js.map +1 -0
- package/dist/appMap/codeIndex.js +73 -0
- package/dist/appMap/codeIndex.js.map +1 -0
- package/dist/appMap/featureModel.js +83 -0
- package/dist/appMap/featureModel.js.map +1 -0
- package/dist/appMap/firstRunApply.js +131 -0
- package/dist/appMap/firstRunApply.js.map +1 -0
- package/dist/appMap/fsWalk.js +75 -0
- package/dist/appMap/fsWalk.js.map +1 -0
- package/dist/appMap/issues.js +227 -0
- package/dist/appMap/issues.js.map +1 -0
- package/dist/appMap/migrations.js +87 -0
- package/dist/appMap/migrations.js.map +1 -0
- package/dist/appMap/prelaunch.js +66 -0
- package/dist/appMap/prelaunch.js.map +1 -0
- package/dist/appMap/projectRegistry.js +70 -0
- package/dist/appMap/projectRegistry.js.map +1 -0
- package/dist/appMap/provenance.js +52 -0
- package/dist/appMap/provenance.js.map +1 -0
- package/dist/appMap/query.js +118 -0
- package/dist/appMap/query.js.map +1 -0
- package/dist/appMap/runtimeMerge.js +207 -0
- package/dist/appMap/runtimeMerge.js.map +1 -0
- package/dist/appMap/schema.js +65 -0
- package/dist/appMap/schema.js.map +1 -0
- package/dist/appMap/screenMatch.js +75 -0
- package/dist/appMap/screenMatch.js.map +1 -0
- package/dist/appMap/staticScan.js +614 -0
- package/dist/appMap/staticScan.js.map +1 -0
- package/dist/appMap/store.js +173 -0
- package/dist/appMap/store.js.map +1 -0
- package/dist/appMap/tsAstScan.js +184 -0
- package/dist/appMap/tsAstScan.js.map +1 -0
- package/dist/artifacts/bundletool.js +199 -0
- package/dist/artifacts/bundletool.js.map +1 -0
- package/dist/artifacts/resolve.js +388 -0
- package/dist/artifacts/resolve.js.map +1 -0
- package/dist/automationGen/appiumModel.js +129 -0
- package/dist/automationGen/appiumModel.js.map +1 -0
- package/dist/automationGen/ciEmitter.js +80 -0
- package/dist/automationGen/ciEmitter.js.map +1 -0
- package/dist/automationGen/jsEmitter.js +440 -0
- package/dist/automationGen/jsEmitter.js.map +1 -0
- package/dist/automationGen/packagePatch.js +56 -0
- package/dist/automationGen/packagePatch.js.map +1 -0
- package/dist/automationGen/projectProfile.js +317 -0
- package/dist/automationGen/projectProfile.js.map +1 -0
- package/dist/automationGen/pythonEmitter.js +386 -0
- package/dist/automationGen/pythonEmitter.js.map +1 -0
- package/dist/automationGen/readmeEmitter.js +66 -0
- package/dist/automationGen/readmeEmitter.js.map +1 -0
- package/dist/automationGen/suitePlan.js +94 -0
- package/dist/automationGen/suitePlan.js.map +1 -0
- package/dist/automationGen/validation.js +150 -0
- package/dist/automationGen/validation.js.map +1 -0
- package/dist/build/parseBuildLog.js +119 -0
- package/dist/build/parseBuildLog.js.map +1 -0
- package/dist/build/plan.js +150 -0
- package/dist/build/plan.js.map +1 -0
- package/dist/ci/preflight.js +85 -0
- package/dist/ci/preflight.js.map +1 -0
- package/dist/cli/init.js +105 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/scan.js +85 -0
- package/dist/cli/scan.js.map +1 -0
- package/dist/cli/suite.js +85 -0
- package/dist/cli/suite.js.map +1 -0
- package/dist/cli/verify.js +62 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/consent/consent.js +43 -0
- package/dist/consent/consent.js.map +1 -0
- package/dist/context/detect.js +156 -0
- package/dist/context/detect.js.map +1 -0
- package/dist/context/findApps.js +198 -0
- package/dist/context/findApps.js.map +1 -0
- package/dist/context/projectRoot.js +41 -0
- package/dist/context/projectRoot.js.map +1 -0
- package/dist/context/scan.js +167 -0
- package/dist/context/scan.js.map +1 -0
- package/dist/core/target.js +115 -0
- package/dist/core/target.js.map +1 -0
- package/dist/core/targetPlan.js +140 -0
- package/dist/core/targetPlan.js.map +1 -0
- package/dist/drivers/DirectDriver.js +228 -0
- package/dist/drivers/DirectDriver.js.map +1 -0
- package/dist/drivers/Driver.js +4 -0
- package/dist/drivers/Driver.js.map +1 -0
- package/dist/drivers/SimctlDriver.js +127 -0
- package/dist/drivers/SimctlDriver.js.map +1 -0
- package/dist/drivers/WdaDriver.js +250 -0
- package/dist/drivers/WdaDriver.js.map +1 -0
- package/dist/explore/candidates.js +93 -0
- package/dist/explore/candidates.js.map +1 -0
- package/dist/explore/graph.js +116 -0
- package/dist/explore/graph.js.map +1 -0
- package/dist/explore/memory.js +35 -0
- package/dist/explore/memory.js.map +1 -0
- package/dist/explore/planner.js +105 -0
- package/dist/explore/planner.js.map +1 -0
- package/dist/explore/policy.js +85 -0
- package/dist/explore/policy.js.map +1 -0
- package/dist/explore/runner.js +475 -0
- package/dist/explore/runner.js.map +1 -0
- package/dist/explore/signatures.js +35 -0
- package/dist/explore/signatures.js.map +1 -0
- package/dist/explore/suite.js +55 -0
- package/dist/explore/suite.js.map +1 -0
- package/dist/featureTesting/executionBootstrap.js +140 -0
- package/dist/featureTesting/executionBootstrap.js.map +1 -0
- package/dist/firstRun/authStateMachine.js +83 -0
- package/dist/firstRun/authStateMachine.js.map +1 -0
- package/dist/firstRun/classifyScreen.js +201 -0
- package/dist/firstRun/classifyScreen.js.map +1 -0
- package/dist/firstRun/firstRunPlanner.js +207 -0
- package/dist/firstRun/firstRunPlanner.js.map +1 -0
- package/dist/firstRun/firstRunRunner.js +331 -0
- package/dist/firstRun/firstRunRunner.js.map +1 -0
- package/dist/firstRun/generatedDataPolicy.js +215 -0
- package/dist/firstRun/generatedDataPolicy.js.map +1 -0
- package/dist/firstRun/inputPlanner.js +67 -0
- package/dist/firstRun/inputPlanner.js.map +1 -0
- package/dist/firstRun/onboardingStateMachine.js +46 -0
- package/dist/firstRun/onboardingStateMachine.js.map +1 -0
- package/dist/firstRun/paywallPolicy.js +54 -0
- package/dist/firstRun/paywallPolicy.js.map +1 -0
- package/dist/firstRun/types.js +7 -0
- package/dist/firstRun/types.js.map +1 -0
- package/dist/fixtures/catalog.js +131 -0
- package/dist/fixtures/catalog.js.map +1 -0
- package/dist/flows/discover.js +18 -0
- package/dist/flows/discover.js.map +1 -0
- package/dist/flows/generate.js +211 -0
- package/dist/flows/generate.js.map +1 -0
- package/dist/flows/lint.js +97 -0
- package/dist/flows/lint.js.map +1 -0
- package/dist/flows/pack.js +68 -0
- package/dist/flows/pack.js.map +1 -0
- package/dist/flows/run.js +738 -0
- package/dist/flows/run.js.map +1 -0
- package/dist/flows/schema.js +240 -0
- package/dist/flows/schema.js.map +1 -0
- package/dist/flows/seedExec.js +108 -0
- package/dist/flows/seedExec.js.map +1 -0
- package/dist/flows/templates.js +155 -0
- package/dist/flows/templates.js.map +1 -0
- package/dist/flows/waitGuards.js +12 -0
- package/dist/flows/waitGuards.js.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/ios/signing.js +182 -0
- package/dist/ios/signing.js.map +1 -0
- package/dist/issues/classify.js +186 -0
- package/dist/issues/classify.js.map +1 -0
- package/dist/issues/fingerprint.js +130 -0
- package/dist/issues/fingerprint.js.map +1 -0
- package/dist/issues/index.js +240 -0
- package/dist/issues/index.js.map +1 -0
- package/dist/issues/metrics.js +155 -0
- package/dist/issues/metrics.js.map +1 -0
- package/dist/issues/recurrence.js +193 -0
- package/dist/issues/recurrence.js.map +1 -0
- package/dist/issues/report.js +110 -0
- package/dist/issues/report.js.map +1 -0
- package/dist/issues/reportBridge.js +119 -0
- package/dist/issues/reportBridge.js.map +1 -0
- package/dist/issues/schema.js +90 -0
- package/dist/issues/schema.js.map +1 -0
- package/dist/issues/sourceRevision.js +108 -0
- package/dist/issues/sourceRevision.js.map +1 -0
- package/dist/issues/store.js +155 -0
- package/dist/issues/store.js.map +1 -0
- package/dist/lib/android.js +278 -0
- package/dist/lib/android.js.map +1 -0
- package/dist/lib/commandTemplate.js +55 -0
- package/dist/lib/commandTemplate.js.map +1 -0
- package/dist/lib/coordSpace.js +23 -0
- package/dist/lib/coordSpace.js.map +1 -0
- package/dist/lib/device.js +87 -0
- package/dist/lib/device.js.map +1 -0
- package/dist/lib/gitignore.js +22 -0
- package/dist/lib/gitignore.js.map +1 -0
- package/dist/lib/image.js +97 -0
- package/dist/lib/image.js.map +1 -0
- package/dist/lib/logger.js +8 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/metroState.js +45 -0
- package/dist/lib/metroState.js.map +1 -0
- package/dist/lib/needsInput.js +201 -0
- package/dist/lib/needsInput.js.map +1 -0
- package/dist/lib/png.js +103 -0
- package/dist/lib/png.js.map +1 -0
- package/dist/lib/redact.js +21 -0
- package/dist/lib/redact.js.map +1 -0
- package/dist/lib/result.js +87 -0
- package/dist/lib/result.js.map +1 -0
- package/dist/lib/schemaHash.js +65 -0
- package/dist/lib/schemaHash.js.map +1 -0
- package/dist/lib/sensitive.js +13 -0
- package/dist/lib/sensitive.js.map +1 -0
- package/dist/lib/simctl.js +149 -0
- package/dist/lib/simctl.js.map +1 -0
- package/dist/lib/spawn.js +144 -0
- package/dist/lib/spawn.js.map +1 -0
- package/dist/lib/wda.js +347 -0
- package/dist/lib/wda.js.map +1 -0
- package/dist/lib/wdaConfig.js +69 -0
- package/dist/lib/wdaConfig.js.map +1 -0
- package/dist/lib/wdaTune.js +58 -0
- package/dist/lib/wdaTune.js.map +1 -0
- package/dist/oracle/auth.js +22 -0
- package/dist/oracle/auth.js.map +1 -0
- package/dist/oracle/failures.js +193 -0
- package/dist/oracle/failures.js.map +1 -0
- package/dist/oracle/health.js +123 -0
- package/dist/oracle/health.js.map +1 -0
- package/dist/oracle/record.js +36 -0
- package/dist/oracle/record.js.map +1 -0
- package/dist/orchestration/envelope.js +52 -0
- package/dist/orchestration/envelope.js.map +1 -0
- package/dist/orchestration/goal.js +98 -0
- package/dist/orchestration/goal.js.map +1 -0
- package/dist/plan/plan.js +124 -0
- package/dist/plan/plan.js.map +1 -0
- package/dist/prompts/index.js +63 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/report/artifactManifest.js +44 -0
- package/dist/report/artifactManifest.js.map +1 -0
- package/dist/report/coverage.js +60 -0
- package/dist/report/coverage.js.map +1 -0
- package/dist/report/evidence.js +84 -0
- package/dist/report/evidence.js.map +1 -0
- package/dist/report/export.js +447 -0
- package/dist/report/export.js.map +1 -0
- package/dist/report/flake.js +61 -0
- package/dist/report/flake.js.map +1 -0
- package/dist/report/history.js +564 -0
- package/dist/report/history.js.map +1 -0
- package/dist/report/policy.js +98 -0
- package/dist/report/policy.js.map +1 -0
- package/dist/report/qaLevel.js +96 -0
- package/dist/report/qaLevel.js.map +1 -0
- package/dist/report/readiness.js +213 -0
- package/dist/report/readiness.js.map +1 -0
- package/dist/report/summary.js +42 -0
- package/dist/report/summary.js.map +1 -0
- package/dist/report/testCatalog.js +93 -0
- package/dist/report/testCatalog.js.map +1 -0
- package/dist/report/timing.js +37 -0
- package/dist/report/timing.js.map +1 -0
- package/dist/server.js +180 -0
- package/dist/server.js.map +1 -0
- package/dist/services/automationGenerate.js +60 -0
- package/dist/services/automationGenerate.js.map +1 -0
- package/dist/services/build.js +66 -0
- package/dist/services/build.js.map +1 -0
- package/dist/services/preflight.js +51 -0
- package/dist/services/preflight.js.map +1 -0
- package/dist/services/prepareAndroid.js +183 -0
- package/dist/services/prepareAndroid.js.map +1 -0
- package/dist/services/prepareIos.js +162 -0
- package/dist/services/prepareIos.js.map +1 -0
- package/dist/services/report.js +537 -0
- package/dist/services/report.js.map +1 -0
- package/dist/services/smoke.js +120 -0
- package/dist/services/smoke.js.map +1 -0
- package/dist/services/suiteGenerate.js +123 -0
- package/dist/services/suiteGenerate.js.map +1 -0
- package/dist/services/testSuiteKnowledge.js +150 -0
- package/dist/services/testSuiteKnowledge.js.map +1 -0
- package/dist/session/attach.js +47 -0
- package/dist/session/attach.js.map +1 -0
- package/dist/session/progress.js +56 -0
- package/dist/session/progress.js.map +1 -0
- package/dist/session/store.js +329 -0
- package/dist/session/store.js.map +1 -0
- package/dist/snapshot/overlays.js +132 -0
- package/dist/snapshot/overlays.js.map +1 -0
- package/dist/snapshot/parse.js +204 -0
- package/dist/snapshot/parse.js.map +1 -0
- package/dist/snapshot/present.js +12 -0
- package/dist/snapshot/present.js.map +1 -0
- package/dist/snapshot/settle.js +36 -0
- package/dist/snapshot/settle.js.map +1 -0
- package/dist/state/profile.js +318 -0
- package/dist/state/profile.js.map +1 -0
- package/dist/suite/compile.js +176 -0
- package/dist/suite/compile.js.map +1 -0
- package/dist/suite/lint.js +45 -0
- package/dist/suite/lint.js.map +1 -0
- package/dist/suite/pom.js +285 -0
- package/dist/suite/pom.js.map +1 -0
- package/dist/suite/testcase.js +87 -0
- package/dist/suite/testcase.js.map +1 -0
- package/dist/testSuite/generator.js +222 -0
- package/dist/testSuite/generator.js.map +1 -0
- package/dist/testSuite/history.js +44 -0
- package/dist/testSuite/history.js.map +1 -0
- package/dist/testSuite/issueLinks.js +96 -0
- package/dist/testSuite/issueLinks.js.map +1 -0
- package/dist/testSuite/merge.js +190 -0
- package/dist/testSuite/merge.js.map +1 -0
- package/dist/testSuite/schema.js +86 -0
- package/dist/testSuite/schema.js.map +1 -0
- package/dist/testSuite/store.js +116 -0
- package/dist/testSuite/store.js.map +1 -0
- package/dist/testSuite/traceability.js +55 -0
- package/dist/testSuite/traceability.js.map +1 -0
- package/dist/tools/act.js +457 -0
- package/dist/tools/act.js.map +1 -0
- package/dist/tools/agent.js +225 -0
- package/dist/tools/agent.js.map +1 -0
- package/dist/tools/appMap.js +317 -0
- package/dist/tools/appMap.js.map +1 -0
- package/dist/tools/assertVisual.js +74 -0
- package/dist/tools/assertVisual.js.map +1 -0
- package/dist/tools/automationGenerate.js +394 -0
- package/dist/tools/automationGenerate.js.map +1 -0
- package/dist/tools/capabilities.js +114 -0
- package/dist/tools/capabilities.js.map +1 -0
- package/dist/tools/clearOverlay.js +150 -0
- package/dist/tools/clearOverlay.js.map +1 -0
- package/dist/tools/detectContext.js +41 -0
- package/dist/tools/detectContext.js.map +1 -0
- package/dist/tools/doctor.js +116 -0
- package/dist/tools/doctor.js.map +1 -0
- package/dist/tools/explore.js +289 -0
- package/dist/tools/explore.js.map +1 -0
- package/dist/tools/firstRun.js +136 -0
- package/dist/tools/firstRun.js.map +1 -0
- package/dist/tools/flow.js +331 -0
- package/dist/tools/flow.js.map +1 -0
- package/dist/tools/flowGenerate.js +55 -0
- package/dist/tools/flowGenerate.js.map +1 -0
- package/dist/tools/getArtifact.js +39 -0
- package/dist/tools/getArtifact.js.map +1 -0
- package/dist/tools/health.js +41 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/ios.js +492 -0
- package/dist/tools/ios.js.map +1 -0
- package/dist/tools/jobs.js +20 -0
- package/dist/tools/jobs.js.map +1 -0
- package/dist/tools/network.js +50 -0
- package/dist/tools/network.js.map +1 -0
- package/dist/tools/note.js +69 -0
- package/dist/tools/note.js.map +1 -0
- package/dist/tools/plan.js +49 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/prepareIosTarget.js +99 -0
- package/dist/tools/prepareIosTarget.js.map +1 -0
- package/dist/tools/prepareTarget.js +257 -0
- package/dist/tools/prepareTarget.js.map +1 -0
- package/dist/tools/report.js +42 -0
- package/dist/tools/report.js.map +1 -0
- package/dist/tools/screenRecord.js +24 -0
- package/dist/tools/screenRecord.js.map +1 -0
- package/dist/tools/screenshot.js +63 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/smoke.js +39 -0
- package/dist/tools/smoke.js.map +1 -0
- package/dist/tools/snapshot.js +129 -0
- package/dist/tools/snapshot.js.map +1 -0
- package/dist/tools/startSession.js +169 -0
- package/dist/tools/startSession.js.map +1 -0
- package/dist/tools/state.js +87 -0
- package/dist/tools/state.js.map +1 -0
- package/dist/tools/suite.js +412 -0
- package/dist/tools/suite.js.map +1 -0
- package/dist/tools/testThis.js +774 -0
- package/dist/tools/testThis.js.map +1 -0
- package/dist/tools/wda.js +477 -0
- package/dist/tools/wda.js.map +1 -0
- package/dist/version.js +62 -0
- package/dist/version.js.map +1 -0
- package/dist/visual/ocr.js +72 -0
- package/dist/visual/ocr.js.map +1 -0
- package/dist/visual/provider.js +75 -0
- package/dist/visual/provider.js.map +1 -0
- package/docs/README.md +19 -0
- package/docs/assets/swipium-lockup-ink-on-light.png +0 -0
- package/docs/mcp-server.md +135 -0
- package/docs/tools.md +130 -0
- package/package.json +70 -0
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// `swipium init <client> [--apply] [--scope project|user|local]`
|
|
2
|
+
//
|
|
3
|
+
// Default = PREVIEW the exact registration (safe, no mutation). `--apply` executes it by
|
|
4
|
+
// DELEGATING to the client's own CLI where one exists (claude/gemini `mcp add`), or writing
|
|
5
|
+
// Codex's config.toml (it has no `mcp add` + a history of silent config-load bugs). After a
|
|
6
|
+
// successful apply it runs `verify` (the server starts + tools inject).
|
|
7
|
+
//
|
|
8
|
+
// NOTE: this is the CLI path, not the MCP server — writing to stdout is fine here.
|
|
9
|
+
import { spawnSync } from 'node:child_process';
|
|
10
|
+
import { existsSync, readFileSync, appendFileSync, mkdirSync } from 'node:fs';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
import { dirname, resolve, join } from 'node:path';
|
|
14
|
+
import { runVerify } from './verify.js';
|
|
15
|
+
import { initFlowTemplates } from '../flows/templates.js';
|
|
16
|
+
const SELF = resolve(dirname(fileURLToPath(import.meta.url)), '..', 'index.js'); // dist/index.js
|
|
17
|
+
/** A delegated CLI registration succeeded only if it both ran and exited 0. */
|
|
18
|
+
export function applyOk(r) {
|
|
19
|
+
return !r.error && r.status === 0;
|
|
20
|
+
}
|
|
21
|
+
function geminiBlock(node) {
|
|
22
|
+
return ` "swipium": { "command": ${JSON.stringify(node)}, "args": [${JSON.stringify(SELF)}], "cwd": "<your repo>", "timeout": 600000 }`;
|
|
23
|
+
}
|
|
24
|
+
function codexBlock(node) {
|
|
25
|
+
return `[mcp_servers.swipium]\ncommand = ${JSON.stringify(node)}\nargs = [${JSON.stringify(SELF)}]\ncwd = "<your repo>"`;
|
|
26
|
+
}
|
|
27
|
+
export async function runInit(args) {
|
|
28
|
+
const client = (args[0] ?? '').toLowerCase();
|
|
29
|
+
const apply = args.includes('--apply');
|
|
30
|
+
const scopeIdx = args.indexOf('--scope');
|
|
31
|
+
const scope = scopeIdx >= 0 ? args[scopeIdx + 1] : 'local';
|
|
32
|
+
const node = process.execPath;
|
|
33
|
+
if (client === 'flows') {
|
|
34
|
+
const rootIdx = args.indexOf('--root');
|
|
35
|
+
const root = rootIdx >= 0 ? resolve(args[rootIdx + 1]) : process.cwd();
|
|
36
|
+
const force = args.includes('--force');
|
|
37
|
+
const result = initFlowTemplates(root, { force });
|
|
38
|
+
process.stdout.write(`Initialized Swipium flow templates under ${root}\n`);
|
|
39
|
+
for (const f of result.files) {
|
|
40
|
+
process.stdout.write(` ${f.written ? 'wrote' : 'kept'} ${f.path}${f.skipped ? ' (--force to overwrite)' : ''}\n`);
|
|
41
|
+
}
|
|
42
|
+
process.stdout.write('\nNext: edit selectors/variables, then validate with qa_flow_check and run with qa_flow_run from an MCP session.\n');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!['claude', 'gemini', 'codex'].includes(client)) {
|
|
46
|
+
process.stdout.write('Usage: swipium init <claude|gemini|codex> [--apply] [--scope project|user|local]\n swipium init flows [--root <dir>] [--force]\n');
|
|
47
|
+
process.exitCode = 2;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (client === 'claude') {
|
|
51
|
+
const cmd = ['mcp', 'add', 'swipium', ...(scope !== 'local' ? ['--scope', scope] : []), '--', node, SELF];
|
|
52
|
+
if (apply) {
|
|
53
|
+
const r = spawnSync('claude', cmd, { stdio: 'inherit' });
|
|
54
|
+
if (!applyOk(r)) {
|
|
55
|
+
process.stdout.write(`claude registration failed (status ${r.status ?? 'n/a'}). Run manually:\n claude ${cmd.join(' ')}\n`);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
process.stdout.write('\nRegistered. Verifying the server starts + tools inject…\n');
|
|
59
|
+
await runVerify();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
process.stdout.write(`Preview (run with --apply to execute):\n claude ${cmd.join(' ')}\n`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (client === 'gemini') {
|
|
67
|
+
const cmd = ['mcp', 'add', 'swipium', node, SELF];
|
|
68
|
+
if (apply) {
|
|
69
|
+
const r = spawnSync('gemini', cmd, { stdio: 'inherit' });
|
|
70
|
+
if (!applyOk(r)) {
|
|
71
|
+
process.stdout.write(`gemini \`mcp add\` unavailable. Add to ~/.gemini/settings.json under "mcpServers":\n${geminiBlock(node)}\n`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
process.stdout.write('\nRegistered. Verifying…\n');
|
|
75
|
+
await runVerify();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
process.stdout.write(`Preview (run with --apply):\n gemini ${cmd.join(' ')}\nor add to ~/.gemini/settings.json:\n${geminiBlock(node)}\n`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// codex — no `mcp add`; write config.toml (append if absent), then self-verify.
|
|
84
|
+
const cfg = join(homedir(), '.codex', 'config.toml');
|
|
85
|
+
const block = codexBlock(node);
|
|
86
|
+
if (apply) {
|
|
87
|
+
mkdirSync(dirname(cfg), { recursive: true });
|
|
88
|
+
const cur = existsSync(cfg) ? readFileSync(cfg, 'utf8') : '';
|
|
89
|
+
if (cur.includes('[mcp_servers.swipium]')) {
|
|
90
|
+
process.stdout.write(`Already present in ${cfg}\n`);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
appendFileSync(cfg, `\n${block}\n`);
|
|
94
|
+
process.stdout.write(`Appended to ${cfg}\n`);
|
|
95
|
+
}
|
|
96
|
+
process.stdout.write('⚠ Codex has an open tool-injection regression (#19425) on builds after ~0.120.0 — confirm tools actually appear in Codex. Server-side self-check:\n');
|
|
97
|
+
await runVerify();
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
process.stdout.write(`Add to ${cfg}:\n${block}\n⚠ Codex has an open tool-injection regression — verify tools appear after adding.\n`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
process.stdout.write('\nSelf-check anytime: swipium verify\n');
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,yFAAyF;AACzF,4FAA4F;AAC5F,4FAA4F;AAC5F,wEAAwE;AACxE,EAAE;AACF,mFAAmF;AAEnF,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,gBAAgB;AAEjG,+EAA+E;AAC/E,MAAM,UAAU,OAAO,CAAC,CAA6C;IACnE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,6BAA6B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8CAA8C,CAAC;AAC3I,CAAC;AACD,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,oCAAoC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC3H,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc;IAC1C,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC;IAE9B,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,IAAI,IAAI,CAAC,CAAC;QAC3E,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrH,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oHAAoH,CAAC,CAAC;QAC3I,OAAO;IACT,CAAC;IAED,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wIAAwI,CAAC,CAAC;QAC/J,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1G,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC,MAAM,IAAI,KAAK,8BAA8B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/H,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;gBACpF,MAAM,SAAS,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uFAAuF,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrI,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBACnD,MAAM,SAAS,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,yCAAyC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7I,CAAC;IACH,CAAC;SAAM,CAAC;QACN,gFAAgF;QAChF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,KAAK,EAAE,CAAC;YACV,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,cAAc,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC;gBACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qJAAqJ,CAAC,CAAC;YAC5K,MAAM,SAAS,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,KAAK,uFAAuF,CAAC,CAAC;QACxI,CAAC;IACH,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;AACjE,CAAC"}
|
package/dist/cli/scan.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// `swipium scan [path]` (PHASE3-PLAN §3.1) — inspect a project and scaffold its .swipium/.
|
|
2
|
+
// Writes .swipium/config.json (generated, overwritten), and scaffolds .swipium/fixtures.json
|
|
3
|
+
// (only if absent — never clobbers user fixtures) and .swipium/flows/. Ends with a clear
|
|
4
|
+
// ready | partial | blocked summary and the exact missing items.
|
|
5
|
+
// Pass --check / --dry-run / --no-write to inspect without writing project files.
|
|
6
|
+
//
|
|
7
|
+
// CLI path, not the MCP server — writing to stdout is fine here, and defaulting to cwd is
|
|
8
|
+
// fine (the no-cwd rule is for the stdio server, which has no meaningful working directory).
|
|
9
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { join, resolve } from 'node:path';
|
|
11
|
+
import { scanProject } from '../context/scan.js';
|
|
12
|
+
const FIXTURES_TEMPLATE = {
|
|
13
|
+
_doc: 'Declared preconditions for QA runs. An unmet requiredState reads as "blocked + setup", not a failure. A fixture with a testAccount (or a login/auth name) marks credentials available for login_smoke.',
|
|
14
|
+
fixtures: [],
|
|
15
|
+
};
|
|
16
|
+
const FLOWS_README = `# Swipium flows
|
|
17
|
+
|
|
18
|
+
Put repeatable tests here as \`*.yaml\`. Each flow is picked up by \`swipium plan\` and
|
|
19
|
+
\`qa_plan\` as a candidate workflow.
|
|
20
|
+
`;
|
|
21
|
+
export async function runScan(args) {
|
|
22
|
+
const write = !args.some((arg) => arg === '--check' || arg === '--dry-run' || arg === '--no-write');
|
|
23
|
+
const rootArg = args.find((arg) => arg.trim() && !arg.startsWith('--'));
|
|
24
|
+
const root = resolve(rootArg?.trim() || process.cwd());
|
|
25
|
+
if (!existsSync(root)) {
|
|
26
|
+
process.stdout.write(`Path not found: ${root}\n`);
|
|
27
|
+
process.exitCode = 2;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
process.stdout.write(`Scanning ${root} …\n`);
|
|
31
|
+
const scan = await scanProject(root);
|
|
32
|
+
const swipiumDir = join(root, '.swipium');
|
|
33
|
+
const configPath = join(swipiumDir, 'config.json');
|
|
34
|
+
const fixturesPath = join(swipiumDir, 'fixtures.json');
|
|
35
|
+
const flowsDir = join(swipiumDir, 'flows');
|
|
36
|
+
let fixturesNote = existsSync(fixturesPath) ? 'kept existing' : 'created (empty template)';
|
|
37
|
+
if (write) {
|
|
38
|
+
mkdirSync(swipiumDir, { recursive: true });
|
|
39
|
+
// config.json — generated artifact, always refreshed.
|
|
40
|
+
writeFileSync(configPath, JSON.stringify(scan, null, 2));
|
|
41
|
+
// fixtures.json — scaffold only if absent (don't clobber the user's declared preconditions).
|
|
42
|
+
if (!existsSync(fixturesPath)) {
|
|
43
|
+
writeFileSync(fixturesPath, JSON.stringify(FIXTURES_TEMPLATE, null, 2));
|
|
44
|
+
}
|
|
45
|
+
// flows/ — scaffold the directory + a README if empty.
|
|
46
|
+
mkdirSync(flowsDir, { recursive: true });
|
|
47
|
+
mkdirSync(join(swipiumDir, 'packs'), { recursive: true }); // flow packs (release suites)
|
|
48
|
+
const flowsReadme = join(flowsDir, 'README.md');
|
|
49
|
+
if (!existsSync(flowsReadme))
|
|
50
|
+
writeFileSync(flowsReadme, FLOWS_README);
|
|
51
|
+
}
|
|
52
|
+
const icon = scan.readiness === 'ready' ? '✅' : scan.readiness === 'partial' ? '⚠️' : '⛔';
|
|
53
|
+
const lines = [
|
|
54
|
+
'',
|
|
55
|
+
`${icon} ${scan.readiness.toUpperCase()}`,
|
|
56
|
+
`framework: ${scan.framework}${scan.monorepo ? ' (monorepo — pick a target)' : ''}`,
|
|
57
|
+
`appId: ${scan.appId ?? 'unknown'}${scan.appIdSource ? ` (via ${scan.appIdSource})` : ''}`,
|
|
58
|
+
`artifacts: ${scan.apks.length} apk, ${scan.ipas.length} ipa, ${scan.appBundles.length} .app${scan.installed === true ? ' · app installed' : scan.installed === false ? ' · app NOT installed' : ''}`,
|
|
59
|
+
`devices: online=[${scan.devices.androidOnline.join(', ')}] avds=[${scan.devices.avds.join(', ')}]`,
|
|
60
|
+
`metro needed: ${scan.metroNeed} · fresh_start safe: ${scan.freshStartSafe} · likely auth: ${scan.likelyAuth}${scan.authSignals.length ? ` (${scan.authSignals.join(', ')})` : ''}`,
|
|
61
|
+
`recommended profile: ${scan.recommendedProfile}`,
|
|
62
|
+
];
|
|
63
|
+
if (scan.missing.length) {
|
|
64
|
+
lines.push('', 'to fix:');
|
|
65
|
+
for (const m of scan.missing)
|
|
66
|
+
lines.push(` - ${m}`);
|
|
67
|
+
}
|
|
68
|
+
lines.push('', write ? `wrote: ${configPath}` : `check mode: no files written`, write ? ` ${fixturesPath} (${fixturesNote})` : `would write: ${configPath}`, write ? ` ${flowsDir}/` : ` ${fixturesPath} (${fixturesNote})`, ...(write ? [] : [` ${flowsDir}/`]), `git scope: not touched (Swipium never edits .gitignore or runs Git)`, '', write
|
|
69
|
+
? 'Next: run `swipium plan` for READY/BLOCKED/UNSAFE workflows, or in an agent call qa_start_session then qa_plan.'
|
|
70
|
+
: 'Next: rerun without --check when you are ready to create Swipium project files, or use qa_detect_context for read-only MCP inspection.', '');
|
|
71
|
+
process.stdout.write(lines.join('\n'));
|
|
72
|
+
}
|
|
73
|
+
/** Read a previously generated .swipium/config.json, if present. Used by qa_start_session. */
|
|
74
|
+
export function loadProjectConfig(root) {
|
|
75
|
+
const p = join(root, '.swipium', 'config.json');
|
|
76
|
+
if (!existsSync(p))
|
|
77
|
+
return null;
|
|
78
|
+
try {
|
|
79
|
+
return JSON.parse(readFileSync(p, 'utf8'));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/cli/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// `swipium suite <lint|compile|init>`. `lint` audits generated page objects for
|
|
2
|
+
// brittle locators; `init` prints how to bootstrap a suite (generation needs a recorded run,
|
|
3
|
+
// which is a live MCP session — the CLI points the user at it rather than guessing).
|
|
4
|
+
import { isAbsolute, join } from 'node:path';
|
|
5
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { lintSuitePages } from '../suite/lint.js';
|
|
7
|
+
import { compileSuite } from '../suite/compile.js';
|
|
8
|
+
import { parseFlow } from '../flows/schema.js';
|
|
9
|
+
function resolveRoot(arg) {
|
|
10
|
+
if (!arg)
|
|
11
|
+
return process.cwd();
|
|
12
|
+
return isAbsolute(arg) ? arg : join(process.cwd(), arg);
|
|
13
|
+
}
|
|
14
|
+
/** Compile a suite into runnable Flow V2 files under .swipium/flows + .swipium/compiled. */
|
|
15
|
+
function compileToFlows(root, suiteRel) {
|
|
16
|
+
const result = compileSuite(root, suiteRel ?? 'suites/smoke.yaml');
|
|
17
|
+
const lines = [];
|
|
18
|
+
if (result.errors.length && result.flows.length === 0) {
|
|
19
|
+
return { ok: false, slugs: [], lines: [`No suite to compile: ${result.errors.join('; ')}`] };
|
|
20
|
+
}
|
|
21
|
+
const flowsDir = join(root, '.swipium', 'flows');
|
|
22
|
+
const compiledDir = join(root, '.swipium', 'compiled');
|
|
23
|
+
mkdirSync(flowsDir, { recursive: true });
|
|
24
|
+
mkdirSync(compiledDir, { recursive: true });
|
|
25
|
+
const slugs = [];
|
|
26
|
+
let allOk = true;
|
|
27
|
+
for (const f of result.flows) {
|
|
28
|
+
const slug = f.name.replace(/[^\w.-]+/g, '-');
|
|
29
|
+
const parse = f.yaml ? parseFlow(f.yaml) : { errors: ['empty'] };
|
|
30
|
+
const ok = !!f.yaml && parse.errors.length === 0 && f.errors.length === 0;
|
|
31
|
+
if (ok) {
|
|
32
|
+
writeFileSync(join(flowsDir, `${slug}.yaml`), f.yaml);
|
|
33
|
+
writeFileSync(join(compiledDir, `${slug}.flow.yaml`), f.yaml);
|
|
34
|
+
slugs.push(slug);
|
|
35
|
+
lines.push(`✓ ${f.name} → .swipium/flows/${slug}.yaml`);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
allOk = false;
|
|
39
|
+
lines.push(`✗ ${f.name}: ${[...f.errors, ...parse.errors].join('; ')}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return { ok: allOk, slugs, lines };
|
|
43
|
+
}
|
|
44
|
+
export async function runSuite(args) {
|
|
45
|
+
const sub = args[0];
|
|
46
|
+
const root = resolveRoot(args.find((a, i) => i > 0 && !a.startsWith('--')));
|
|
47
|
+
if (sub === 'lint') {
|
|
48
|
+
const res = lintSuitePages(root);
|
|
49
|
+
if (!res.exists) {
|
|
50
|
+
process.stdout.write(`No .swipium/pages under ${root}. Generate a suite first (qa_suite_generate via the MCP server).\n`);
|
|
51
|
+
process.exitCode = 2;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
process.stdout.write(`Suite lint: ${res.pageCount} page object(s), ${res.items.length} finding(s)\n`);
|
|
55
|
+
for (const i of res.items) {
|
|
56
|
+
process.stdout.write(`${i.severity.toUpperCase()} ${i.page}.${i.element}: ${i.message}\n`);
|
|
57
|
+
}
|
|
58
|
+
process.exitCode = res.items.some((i) => i.severity === 'error') ? 1 : 0;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (sub === 'compile') {
|
|
62
|
+
const suiteRel = args.includes('--suite') ? args[args.indexOf('--suite') + 1] : undefined;
|
|
63
|
+
const r = compileToFlows(root, suiteRel);
|
|
64
|
+
r.lines.forEach((l) => process.stdout.write(l + '\n'));
|
|
65
|
+
process.exitCode = r.ok && r.slugs.length ? 0 : 2;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (sub === 'init') {
|
|
69
|
+
process.stdout.write([
|
|
70
|
+
'Swipium suites are generated from a recorded run (durable selectors > guesswork):',
|
|
71
|
+
' 1. Start the MCP server and a session (qa_start_session).',
|
|
72
|
+
' 2. Drive the app with qa_act (or qa_smoke) — every action is recorded.',
|
|
73
|
+
' 3. qa_suite_generate → writes .swipium/{pages,tests,suites,testcases,locators}.',
|
|
74
|
+
' 4. swipium suite lint — audit locator durability before committing.',
|
|
75
|
+
' 5. swipium suite compile — POM → runnable Flow V2 under .swipium/flows.',
|
|
76
|
+
' 6. Execute compiled flows through qa_flow_run from an MCP session.',
|
|
77
|
+
'',
|
|
78
|
+
].join('\n'));
|
|
79
|
+
process.exitCode = 0;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
process.stdout.write('Usage: swipium suite <lint|compile|init> [--suite suites/smoke.yaml] [projectRoot]\n');
|
|
83
|
+
process.exitCode = 2;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suite.js","sourceRoot":"","sources":["../../src/cli/suite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// `swipium verify` — programmatic proxy for "does the server start and do its tools
|
|
2
|
+
// inject?". Spawns dist/index.js as a stdio MCP server via the SDK client, lists tools,
|
|
3
|
+
// asserts the full Phase-0 surface is present, and calls qa_doctor. This is the same
|
|
4
|
+
// JSON-RPC path the real clients use — the closest automatable check to the in-client test.
|
|
5
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
6
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { dirname, resolve } from 'node:path';
|
|
9
|
+
import { TOOL_NAMES, PROMPT_NAMES } from '../version.js';
|
|
10
|
+
const SELF = resolve(dirname(fileURLToPath(import.meta.url)), '..', 'index.js');
|
|
11
|
+
const EXPECTED = [...TOOL_NAMES];
|
|
12
|
+
export async function runVerify() {
|
|
13
|
+
const transport = new StdioClientTransport({ command: process.execPath, args: [SELF] });
|
|
14
|
+
const client = new Client({ name: 'swipium-verify', version: '0.0.0' });
|
|
15
|
+
try {
|
|
16
|
+
await client.connect(transport);
|
|
17
|
+
const { tools } = await client.listTools();
|
|
18
|
+
const names = tools.map((t) => t.name);
|
|
19
|
+
const missing = EXPECTED.filter((t) => !names.includes(t));
|
|
20
|
+
// Prompts are the third MCP capability — confirm they inject too (best-effort: a client
|
|
21
|
+
// that doesn't support prompts will throw, which we tolerate).
|
|
22
|
+
let promptNames = [];
|
|
23
|
+
try {
|
|
24
|
+
const { prompts } = await client.listPrompts();
|
|
25
|
+
promptNames = prompts.map((p) => p.name);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
/* prompts unsupported by this transport/client — not fatal */
|
|
29
|
+
}
|
|
30
|
+
const missingPrompts = [...PROMPT_NAMES].filter((p) => !promptNames.includes(p));
|
|
31
|
+
let doctorRan = false;
|
|
32
|
+
let schemaHash = 'unknown';
|
|
33
|
+
try {
|
|
34
|
+
const d = await client.callTool({ name: 'qa_doctor', arguments: {} });
|
|
35
|
+
doctorRan = !d.isError;
|
|
36
|
+
const sc = d.structuredContent;
|
|
37
|
+
if (sc?.schemaHash)
|
|
38
|
+
schemaHash = sc.schemaHash;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
/* doctor failure is reported below */
|
|
42
|
+
}
|
|
43
|
+
await client.close();
|
|
44
|
+
if (missing.length) {
|
|
45
|
+
console.log(`❌ verify FAILED — missing tools: ${missing.join(', ')}`);
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log(`✅ verify OK — server starts, ${names.length} tools inject (all ${EXPECTED.length} expected present), schema ${schemaHash}, qa_doctor ${doctorRan ? 'ran' : 'ERRORED'}.`);
|
|
50
|
+
console.log(`tools: ${names.join(', ')}`);
|
|
51
|
+
console.log(missingPrompts.length
|
|
52
|
+
? `⚠ prompts: ${promptNames.length}/${PROMPT_NAMES.length} present (missing: ${missingPrompts.join(', ')})`
|
|
53
|
+
: `prompts: all ${PROMPT_NAMES.length} present (${promptNames.join(', ')})`);
|
|
54
|
+
if (!doctorRan)
|
|
55
|
+
process.exitCode = 1;
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
console.log(`❌ verify FAILED — could not start/inspect the server: ${String(e)}`);
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/cli/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Portable consent state machine (DESIGN §10.2). Works WITHOUT client elicitation:
|
|
2
|
+
// a privileged action returns { requiresConsent, consentId, ... }; the agent surfaces
|
|
3
|
+
// it, the user approves, and the same tool is re-called with { consentId, approve:true }.
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
const pending = new Map();
|
|
6
|
+
/** Build the tool result that asks for consent. */
|
|
7
|
+
export function requireConsent(req) {
|
|
8
|
+
const consentId = randomUUID().slice(0, 8);
|
|
9
|
+
pending.set(consentId, req);
|
|
10
|
+
const payload = { requiresConsent: true, consentId, ...req };
|
|
11
|
+
const text = `🔐 Consent required (${req.risk}): ${req.explain}\n` +
|
|
12
|
+
(req.exactCommand ? `Will run: ${req.exactCommand}\n` : '') +
|
|
13
|
+
`To approve, re-call this tool with consentId="${consentId}" and approve=true.\n\n` +
|
|
14
|
+
'```json\n' +
|
|
15
|
+
JSON.stringify(payload, null, 2) +
|
|
16
|
+
'\n```';
|
|
17
|
+
return { content: [{ type: 'text', text }], structuredContent: payload };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validate a resume call. Consent is single-use AND bound to the exact action:
|
|
21
|
+
* `expected.action`/`expected.affects` must match what was originally requested, so an
|
|
22
|
+
* approval issued for one action can't be replayed against a different one.
|
|
23
|
+
*/
|
|
24
|
+
export function consumeConsent(consentId, approve, expected) {
|
|
25
|
+
if (!consentId)
|
|
26
|
+
return { approved: false, reason: 'no consentId supplied' };
|
|
27
|
+
const req = pending.get(consentId);
|
|
28
|
+
if (!req)
|
|
29
|
+
return { approved: false, reason: 'unknown or already-used consentId' };
|
|
30
|
+
// Bind to the exact action/affects BEFORE consuming, so a mismatched id stays valid
|
|
31
|
+
// for its real use rather than being silently burned.
|
|
32
|
+
if (expected?.action && req.action !== expected.action) {
|
|
33
|
+
return { approved: false, req, reason: `consent is for "${req.action}", not "${expected.action}"` };
|
|
34
|
+
}
|
|
35
|
+
if (expected?.affects && JSON.stringify(req.affects ?? {}) !== JSON.stringify(expected.affects)) {
|
|
36
|
+
return { approved: false, req, reason: 'consent does not match the affected target' };
|
|
37
|
+
}
|
|
38
|
+
pending.delete(consentId);
|
|
39
|
+
if (!approve)
|
|
40
|
+
return { approved: false, req, reason: 'user did not approve' };
|
|
41
|
+
return { approved: true, req };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=consent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consent.js","sourceRoot":"","sources":["../../src/consent/consent.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,sFAAsF;AACtF,0FAA0F;AAE1F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAazC,MAAM,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;AAElD,mDAAmD;AACnD,MAAM,UAAU,cAAc,CAAC,GAAmB;IAChD,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,EAAE,CAAC;IAC7D,MAAM,IAAI,GACR,wBAAwB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,OAAO,IAAI;QACrD,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,iDAAiD,SAAS,yBAAyB;QACnF,WAAW;QACX,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAChC,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;AAC3E,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAkB,EAClB,OAAiB,EACjB,QAAiE;IAEjE,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAC5E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAC;IAClF,oFAAoF;IACpF,sDAAsD;IACtD,IAAI,QAAQ,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QACvD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,mBAAmB,GAAG,CAAC,MAAM,WAAW,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC;IACtG,CAAC;IACD,IAAI,QAAQ,EAAE,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAChG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,4CAA4C,EAAE,CAAC;IACxF,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1B,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAC9E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Detect the mobile project context under a resolved projectRoot (DESIGN §7).
|
|
2
|
+
// Best-effort, file-marker based; never trusts cwd.
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { which, firstLine, adbDevices, listAvds, findAapt2 } from '../lib/android.js';
|
|
6
|
+
import { resolveArtifact } from '../artifacts/resolve.js';
|
|
7
|
+
function readJson(p) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(readFileSync(p, 'utf8'));
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function hasAny(dir, names) {
|
|
16
|
+
return names.some((n) => existsSync(join(dir, n)));
|
|
17
|
+
}
|
|
18
|
+
function listApks(dir) {
|
|
19
|
+
if (!existsSync(dir))
|
|
20
|
+
return [];
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const f of readdirSync(dir)) {
|
|
23
|
+
if (f.toLowerCase().endsWith('.apk')) {
|
|
24
|
+
const p = join(dir, f);
|
|
25
|
+
try {
|
|
26
|
+
if (statSync(p).size >= 1024 * 1024)
|
|
27
|
+
out.push(p);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
/* skip */
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function listBy(dir, ext) {
|
|
37
|
+
if (!existsSync(dir))
|
|
38
|
+
return [];
|
|
39
|
+
return readdirSync(dir)
|
|
40
|
+
.filter((f) => f.toLowerCase().endsWith(ext))
|
|
41
|
+
.map((f) => join(dir, f));
|
|
42
|
+
}
|
|
43
|
+
function unique(values) {
|
|
44
|
+
return [...new Set(values)];
|
|
45
|
+
}
|
|
46
|
+
export function detectFramework(root) {
|
|
47
|
+
const pkg = readJson(join(root, 'package.json'));
|
|
48
|
+
const deps = pkg ? { ...pkg.dependencies, ...pkg.devDependencies } : {};
|
|
49
|
+
const hasRN = 'react-native' in deps;
|
|
50
|
+
const hasExpo = 'expo' in deps;
|
|
51
|
+
if (existsSync(join(root, 'pubspec.yaml')))
|
|
52
|
+
return 'flutter';
|
|
53
|
+
if (hasExpo)
|
|
54
|
+
return 'expo';
|
|
55
|
+
if (hasRN)
|
|
56
|
+
return 'bare-react-native';
|
|
57
|
+
if (hasAny(root, ['settings.gradle', 'settings.gradle.kts', 'build.gradle', 'build.gradle.kts']))
|
|
58
|
+
return 'native-android';
|
|
59
|
+
if (existsSync(join(root, 'Package.swift')) ||
|
|
60
|
+
readdirSync(root).some((f) => f.endsWith('.xcworkspace') || f.endsWith('.xcodeproj')))
|
|
61
|
+
return 'native-ios';
|
|
62
|
+
return 'unknown';
|
|
63
|
+
}
|
|
64
|
+
function detectMonorepo(root) {
|
|
65
|
+
const pkg = readJson(join(root, 'package.json'));
|
|
66
|
+
if (pkg && 'workspaces' in pkg)
|
|
67
|
+
return true;
|
|
68
|
+
if (existsSync(join(root, 'pnpm-workspace.yaml')) || existsSync(join(root, 'lerna.json')))
|
|
69
|
+
return true;
|
|
70
|
+
// multiple package.json in immediate subdirs
|
|
71
|
+
try {
|
|
72
|
+
let count = 0;
|
|
73
|
+
for (const e of readdirSync(root, { withFileTypes: true })) {
|
|
74
|
+
if (e.isDirectory() && e.name !== 'node_modules' && existsSync(join(root, e.name, 'package.json')))
|
|
75
|
+
count++;
|
|
76
|
+
}
|
|
77
|
+
return count >= 2;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export async function detectContext(projectRoot) {
|
|
84
|
+
let location = 'unknown';
|
|
85
|
+
try {
|
|
86
|
+
const entries = readdirSync(projectRoot).filter((f) => !f.startsWith('.'));
|
|
87
|
+
if (entries.length === 0)
|
|
88
|
+
location = 'empty';
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
/* leave unknown */
|
|
92
|
+
}
|
|
93
|
+
const framework = detectFramework(projectRoot);
|
|
94
|
+
if (framework !== 'unknown')
|
|
95
|
+
location = 'project';
|
|
96
|
+
const monorepo = detectMonorepo(projectRoot);
|
|
97
|
+
const artifacts = {
|
|
98
|
+
apks: [...listApks(projectRoot), ...listApks(join(projectRoot, 'apps', 'android'))],
|
|
99
|
+
ipas: listBy(join(projectRoot, 'apps', 'ios'), '.ipa'),
|
|
100
|
+
appBundles: listBy(join(projectRoot, 'apps', 'ios'), '.app'),
|
|
101
|
+
};
|
|
102
|
+
const resolvedArtifacts = await resolveArtifact({ projectRoot, platform: 'any', allowOutsideRoot: false }, false).catch(() => null);
|
|
103
|
+
if (resolvedArtifacts) {
|
|
104
|
+
artifacts.apks = unique([...artifacts.apks, ...resolvedArtifacts.candidates.filter((c) => c.type === 'apk').map((c) => c.path)]);
|
|
105
|
+
artifacts.ipas = unique([...artifacts.ipas, ...resolvedArtifacts.candidates.filter((c) => c.type === 'ipa').map((c) => c.path)]);
|
|
106
|
+
artifacts.appBundles = unique([...artifacts.appBundles, ...resolvedArtifacts.candidates.filter((c) => c.type === 'app').map((c) => c.path)]);
|
|
107
|
+
}
|
|
108
|
+
const [adb, emulator, javaLine, xcodebuild] = await Promise.all([
|
|
109
|
+
which('adb'),
|
|
110
|
+
which('emulator'),
|
|
111
|
+
firstLine('java', ['-version']),
|
|
112
|
+
which('xcodebuild'),
|
|
113
|
+
]);
|
|
114
|
+
const toolchain = {
|
|
115
|
+
node: process.version,
|
|
116
|
+
adb,
|
|
117
|
+
emulator,
|
|
118
|
+
java: javaLine !== null,
|
|
119
|
+
aapt2: findAapt2() !== null,
|
|
120
|
+
xcodebuild,
|
|
121
|
+
};
|
|
122
|
+
const devices = {
|
|
123
|
+
androidOnline: adb ? await adbDevices() : [],
|
|
124
|
+
avds: emulator ? await listAvds() : [],
|
|
125
|
+
};
|
|
126
|
+
const blockers = [];
|
|
127
|
+
if (framework === 'unknown')
|
|
128
|
+
blockers.push('Could not identify a mobile project here — pass an explicit projectRoot, or this is not a supported framework.');
|
|
129
|
+
if (monorepo)
|
|
130
|
+
blockers.push('Monorepo detected — specify which app target to use (avoids guessing).');
|
|
131
|
+
if (!toolchain.adb)
|
|
132
|
+
blockers.push('adb not found — install Android platform-tools.');
|
|
133
|
+
if (framework === 'native-android' && artifacts.apks.length === 0) {
|
|
134
|
+
blockers.push('No prebuilt Android APK found — drop an APK under apps/android, build Gradle output, or pass apk=.');
|
|
135
|
+
}
|
|
136
|
+
else if (framework === 'native-ios' && artifacts.ipas.length === 0 && artifacts.appBundles.length === 0) {
|
|
137
|
+
blockers.push('No prebuilt iOS app artifact found — build a simulator .app or provide an .ipa for a real device lane.');
|
|
138
|
+
}
|
|
139
|
+
else if (framework !== 'native-android' && framework !== 'native-ios' && artifacts.apks.length === 0 && artifacts.ipas.length === 0 && artifacts.appBundles.length === 0) {
|
|
140
|
+
blockers.push('No prebuilt app artifact found — build an APK for Android or a simulator .app for iOS, then run swipium scan again.');
|
|
141
|
+
}
|
|
142
|
+
if (toolchain.adb && devices.androidOnline.length === 0 && devices.avds.length === 0)
|
|
143
|
+
blockers.push('No online device and no AVD — create an AVD (see qa_doctor).');
|
|
144
|
+
return {
|
|
145
|
+
projectRoot,
|
|
146
|
+
location,
|
|
147
|
+
framework,
|
|
148
|
+
monorepo,
|
|
149
|
+
artifacts,
|
|
150
|
+
devices,
|
|
151
|
+
toolchain,
|
|
152
|
+
buildable: framework !== 'unknown',
|
|
153
|
+
blockers,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/context/detect.ts"],"names":[],"mappings":"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"}
|