anymorph 0.11.0 → 0.13.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/README.md +3 -3
- package/dist/index.js +283 -54
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -189,9 +189,9 @@ anymorph validate 20260517T074200Z
|
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
Validation does not update the backend. Backend sync happens from the tenant
|
|
192
|
-
repo GitHub webhook after `agent/runs/{runId}/actions.json` is pushed
|
|
193
|
-
`main`. Any generated `content/*.mdx` files are materialized as CMS pages
|
|
194
|
-
the same webhook path.
|
|
192
|
+
repo GitHub webhook after `agent/runs/{runId}/{channel}/actions.json` is pushed
|
|
193
|
+
to `main`. Any generated `content/*.mdx` files are materialized as CMS pages
|
|
194
|
+
from the same webhook path.
|
|
195
195
|
|
|
196
196
|
## How It Works
|
|
197
197
|
|
package/dist/index.js
CHANGED
|
@@ -11962,8 +11962,7 @@ var require_cms_frontmatter = __commonJS({
|
|
|
11962
11962
|
slug: z.string().optional(),
|
|
11963
11963
|
path: z.string().optional(),
|
|
11964
11964
|
lang: z.string().optional(),
|
|
11965
|
-
heroImage: z.string().optional()
|
|
11966
|
-
thumbnailImage: z.string().optional()
|
|
11965
|
+
heroImage: z.string().optional()
|
|
11967
11966
|
}).passthrough();
|
|
11968
11967
|
var CmsPageTypeSchema2 = z.enum([
|
|
11969
11968
|
"product",
|
|
@@ -11985,7 +11984,6 @@ var require_cms_frontmatter = __commonJS({
|
|
|
11985
11984
|
slug: z.string().min(1),
|
|
11986
11985
|
lang: z.string().min(1),
|
|
11987
11986
|
heroImage: z.string().min(1),
|
|
11988
|
-
thumbnailImage: z.string().min(1).optional(),
|
|
11989
11987
|
pageType: CmsPageTypeSchema2,
|
|
11990
11988
|
pageRole: z.enum(["HUB", "SPOKE", "UNKNOWN"]),
|
|
11991
11989
|
intentId: z.string().min(1).optional(),
|
|
@@ -12412,6 +12410,15 @@ var require_src = __commonJS({
|
|
|
12412
12410
|
mode: CliGeoRunModeSchema2,
|
|
12413
12411
|
signals: z.unknown(),
|
|
12414
12412
|
systemContext: z.unknown(),
|
|
12413
|
+
brandAssets: z.object({
|
|
12414
|
+
hash: z.string().min(1),
|
|
12415
|
+
files: z.array(
|
|
12416
|
+
z.object({
|
|
12417
|
+
path: z.string().min(1),
|
|
12418
|
+
content: z.string()
|
|
12419
|
+
}).strict()
|
|
12420
|
+
).default([])
|
|
12421
|
+
}).strict().optional(),
|
|
12415
12422
|
schemaCatalog: z.string(),
|
|
12416
12423
|
manifest: CliGeoRunManifestSchema2
|
|
12417
12424
|
}).strict();
|
|
@@ -12534,6 +12541,26 @@ var require_src = __commonJS({
|
|
|
12534
12541
|
policy: GeoStrategyPolicyVersionSchema2,
|
|
12535
12542
|
actions: z.array(GeoStrategyActionSchema2).max(20)
|
|
12536
12543
|
}).strict();
|
|
12544
|
+
var GeoStrategyActionChannelSchema2 = z.enum(["brand_owned", "geo_pages", "third_party"]);
|
|
12545
|
+
var GEO_STRATEGY_CHANNEL_ASSET_TYPE2 = Object.freeze({
|
|
12546
|
+
brand_owned: "brand_owned",
|
|
12547
|
+
geo_pages: "geo_page",
|
|
12548
|
+
third_party: "third_party"
|
|
12549
|
+
});
|
|
12550
|
+
var GeoStrategyChannelActionsArtifactSchema2 = GeoStrategyActionsArtifactSchema2.extend({
|
|
12551
|
+
channel: GeoStrategyActionChannelSchema2
|
|
12552
|
+
}).strict().superRefine((artifact, ctx) => {
|
|
12553
|
+
const expectedAssetType = GEO_STRATEGY_CHANNEL_ASSET_TYPE2[artifact.channel];
|
|
12554
|
+
artifact.actions.forEach((action, index2) => {
|
|
12555
|
+
if (action.assetType !== expectedAssetType) {
|
|
12556
|
+
ctx.addIssue({
|
|
12557
|
+
code: z.ZodIssueCode.custom,
|
|
12558
|
+
path: ["actions", index2, "assetType"],
|
|
12559
|
+
message: `assetType must be ${expectedAssetType} for ${artifact.channel} channel artifacts`
|
|
12560
|
+
});
|
|
12561
|
+
}
|
|
12562
|
+
});
|
|
12563
|
+
});
|
|
12537
12564
|
var GeoStrategyActionsArtifactJsonSchema2 = {
|
|
12538
12565
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
12539
12566
|
title: "GeoStrategyActions",
|
|
@@ -12658,6 +12685,71 @@ var require_src = __commonJS({
|
|
|
12658
12685
|
}
|
|
12659
12686
|
}
|
|
12660
12687
|
};
|
|
12688
|
+
function geoStrategyChannelActionsArtifactJsonSchema(channel) {
|
|
12689
|
+
const assetType = GEO_STRATEGY_CHANNEL_ASSET_TYPE2[channel];
|
|
12690
|
+
return {
|
|
12691
|
+
...GeoStrategyActionsArtifactJsonSchema2,
|
|
12692
|
+
title: `GeoStrategy${channel}Actions`,
|
|
12693
|
+
required: ["schemaVersion", "runId", "channel", "policy", "actions"],
|
|
12694
|
+
properties: {
|
|
12695
|
+
...GeoStrategyActionsArtifactJsonSchema2.properties,
|
|
12696
|
+
channel: { const: channel },
|
|
12697
|
+
actions: {
|
|
12698
|
+
...GeoStrategyActionsArtifactJsonSchema2.properties.actions,
|
|
12699
|
+
items: {
|
|
12700
|
+
...GeoStrategyActionsArtifactJsonSchema2.properties.actions.items,
|
|
12701
|
+
properties: {
|
|
12702
|
+
...GeoStrategyActionsArtifactJsonSchema2.properties.actions.items.properties,
|
|
12703
|
+
assetType: { const: assetType }
|
|
12704
|
+
}
|
|
12705
|
+
}
|
|
12706
|
+
}
|
|
12707
|
+
}
|
|
12708
|
+
};
|
|
12709
|
+
}
|
|
12710
|
+
var GeoStrategyChannelActionsArtifactJsonSchemas2 = Object.freeze({
|
|
12711
|
+
brand_owned: geoStrategyChannelActionsArtifactJsonSchema("brand_owned"),
|
|
12712
|
+
geo_pages: geoStrategyChannelActionsArtifactJsonSchema("geo_pages"),
|
|
12713
|
+
third_party: geoStrategyChannelActionsArtifactJsonSchema("third_party")
|
|
12714
|
+
});
|
|
12715
|
+
var GeoStrategyMemoryItemJsonSchema2 = {
|
|
12716
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
12717
|
+
title: "GeoStrategyMemoryItem",
|
|
12718
|
+
type: "object",
|
|
12719
|
+
required: ["id", "runId", "type", "title", "content", "createdAt"],
|
|
12720
|
+
additionalProperties: false,
|
|
12721
|
+
properties: {
|
|
12722
|
+
id: { type: "string", pattern: "^[0-9a-z]{5}-[a-z0-9][a-z0-9-]*$" },
|
|
12723
|
+
runId: { type: "string", minLength: 1 },
|
|
12724
|
+
type: {
|
|
12725
|
+
type: "string",
|
|
12726
|
+
enum: ["observation", "evidence", "competitor", "query", "hypothesis"]
|
|
12727
|
+
},
|
|
12728
|
+
title: { type: "string", minLength: 1 },
|
|
12729
|
+
content: { type: "string", minLength: 1 },
|
|
12730
|
+
sources: { type: "array", items: { type: "string" }, default: [] },
|
|
12731
|
+
tags: { type: "array", items: { type: "string" }, default: [] },
|
|
12732
|
+
createdAt: { type: "string", format: "date-time" }
|
|
12733
|
+
}
|
|
12734
|
+
};
|
|
12735
|
+
var GeoStrategyRunContextJsonSchema2 = {
|
|
12736
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
12737
|
+
title: "GeoStrategyRunContext",
|
|
12738
|
+
type: "object",
|
|
12739
|
+
required: ["runId", "mode", "workspaceDomain", "workspaceId", "signals"],
|
|
12740
|
+
additionalProperties: true,
|
|
12741
|
+
properties: {
|
|
12742
|
+
runId: { type: "string", minLength: 1 },
|
|
12743
|
+
mode: { type: "string", enum: ["bootstrap", "normal"] },
|
|
12744
|
+
workspaceDomain: { type: "string", minLength: 1 },
|
|
12745
|
+
workspaceId: { type: "string", minLength: 1 },
|
|
12746
|
+
tenantRepo: { type: "object" },
|
|
12747
|
+
branch: { type: "string" },
|
|
12748
|
+
signals: { type: "object" },
|
|
12749
|
+
systemContext: { type: "object" },
|
|
12750
|
+
intentsPath: { type: "string" }
|
|
12751
|
+
}
|
|
12752
|
+
};
|
|
12661
12753
|
var LegacyGeoStrategyActionsArtifactSchema = z.union([
|
|
12662
12754
|
z.array(GeoStrategyActionSchema2),
|
|
12663
12755
|
z.object({
|
|
@@ -13067,6 +13159,14 @@ var require_src = __commonJS({
|
|
|
13067
13159
|
policy: null
|
|
13068
13160
|
};
|
|
13069
13161
|
}
|
|
13162
|
+
function parseGeoStrategyChannelActionsArtifactWithMetadata2(raw) {
|
|
13163
|
+
const parsed = GeoStrategyChannelActionsArtifactSchema2.parse(raw);
|
|
13164
|
+
return {
|
|
13165
|
+
channel: parsed.channel,
|
|
13166
|
+
actions: parsed.actions,
|
|
13167
|
+
policy: parsed.policy
|
|
13168
|
+
};
|
|
13169
|
+
}
|
|
13070
13170
|
function allowedGeoStrategyArtifactPaths2(runId) {
|
|
13071
13171
|
return [
|
|
13072
13172
|
`agent/runs/${runId}/context.json`,
|
|
@@ -13074,12 +13174,13 @@ var require_src = __commonJS({
|
|
|
13074
13174
|
`agent/runs/${runId}/policy.json`,
|
|
13075
13175
|
`agent/runs/${runId}/intents.json`,
|
|
13076
13176
|
`agent/runs/${runId}/crawl_logs.json`,
|
|
13077
|
-
`agent/runs/${runId}/
|
|
13078
|
-
`agent/runs/${runId}/
|
|
13079
|
-
`agent/runs/${runId}/
|
|
13080
|
-
`agent/runs/${runId}/
|
|
13081
|
-
`agent/runs/${runId}/
|
|
13082
|
-
`agent/runs/${runId}/
|
|
13177
|
+
`agent/runs/${runId}/brand_owned/actions.json`,
|
|
13178
|
+
`agent/runs/${runId}/brand_owned/rationale.md`,
|
|
13179
|
+
`agent/runs/${runId}/geo_pages/actions.json`,
|
|
13180
|
+
`agent/runs/${runId}/geo_pages/rationale.md`,
|
|
13181
|
+
`agent/runs/${runId}/third_party/actions.json`,
|
|
13182
|
+
`agent/runs/${runId}/third_party/actions_enriched.json`,
|
|
13183
|
+
`agent/runs/${runId}/third_party/rationale.md`,
|
|
13083
13184
|
`agent/runs/${runId}/actions.json`,
|
|
13084
13185
|
`agent/runs/${runId}/rationale.md`,
|
|
13085
13186
|
`agent/runs/${runId}/status.json`,
|
|
@@ -13417,6 +13518,12 @@ var require_src = __commonJS({
|
|
|
13417
13518
|
GeoStrategyPolicyVersionSchema: GeoStrategyPolicyVersionSchema2,
|
|
13418
13519
|
GeoStrategyActionsArtifactSchema: GeoStrategyActionsArtifactSchema2,
|
|
13419
13520
|
GeoStrategyActionsArtifactJsonSchema: GeoStrategyActionsArtifactJsonSchema2,
|
|
13521
|
+
GeoStrategyActionChannelSchema: GeoStrategyActionChannelSchema2,
|
|
13522
|
+
GEO_STRATEGY_CHANNEL_ASSET_TYPE: GEO_STRATEGY_CHANNEL_ASSET_TYPE2,
|
|
13523
|
+
GeoStrategyChannelActionsArtifactSchema: GeoStrategyChannelActionsArtifactSchema2,
|
|
13524
|
+
GeoStrategyChannelActionsArtifactJsonSchemas: GeoStrategyChannelActionsArtifactJsonSchemas2,
|
|
13525
|
+
GeoStrategyMemoryItemJsonSchema: GeoStrategyMemoryItemJsonSchema2,
|
|
13526
|
+
GeoStrategyRunContextJsonSchema: GeoStrategyRunContextJsonSchema2,
|
|
13420
13527
|
GeoStrategyAgentOutputSchema: GeoStrategyAgentOutputSchema2,
|
|
13421
13528
|
GeoStrategySubagentArtifactSchema: GeoStrategySubagentArtifactSchema2,
|
|
13422
13529
|
GeoStrategyActionsArtifactSubmitSchema: GeoStrategyActionsArtifactSubmitSchema2,
|
|
@@ -13443,6 +13550,7 @@ var require_src = __commonJS({
|
|
|
13443
13550
|
StrategyMapEvidenceSchema: StrategyMapEvidenceSchema2,
|
|
13444
13551
|
parseGeoStrategyActionsArtifact: parseGeoStrategyActionsArtifact2,
|
|
13445
13552
|
parseGeoStrategyActionsArtifactWithMetadata: parseGeoStrategyActionsArtifactWithMetadata2,
|
|
13553
|
+
parseGeoStrategyChannelActionsArtifactWithMetadata: parseGeoStrategyChannelActionsArtifactWithMetadata2,
|
|
13446
13554
|
allowedGeoStrategyArtifactPaths: allowedGeoStrategyArtifactPaths2,
|
|
13447
13555
|
allowedStrategyMapArtifactPaths: allowedStrategyMapArtifactPaths2,
|
|
13448
13556
|
formatGeoStrategyActionsArtifactContract: formatGeoStrategyActionsArtifactContract2,
|
|
@@ -22430,6 +22538,12 @@ var GeoStrategyActionSchema = import_index2.default.GeoStrategyActionSchema;
|
|
|
22430
22538
|
var GeoStrategyPolicyVersionSchema = import_index2.default.GeoStrategyPolicyVersionSchema;
|
|
22431
22539
|
var GeoStrategyActionsArtifactSchema = import_index2.default.GeoStrategyActionsArtifactSchema;
|
|
22432
22540
|
var GeoStrategyActionsArtifactJsonSchema = import_index2.default.GeoStrategyActionsArtifactJsonSchema;
|
|
22541
|
+
var GeoStrategyActionChannelSchema = import_index2.default.GeoStrategyActionChannelSchema;
|
|
22542
|
+
var GEO_STRATEGY_CHANNEL_ASSET_TYPE = import_index2.default.GEO_STRATEGY_CHANNEL_ASSET_TYPE;
|
|
22543
|
+
var GeoStrategyChannelActionsArtifactSchema = import_index2.default.GeoStrategyChannelActionsArtifactSchema;
|
|
22544
|
+
var GeoStrategyChannelActionsArtifactJsonSchemas = import_index2.default.GeoStrategyChannelActionsArtifactJsonSchemas;
|
|
22545
|
+
var GeoStrategyMemoryItemJsonSchema = import_index2.default.GeoStrategyMemoryItemJsonSchema;
|
|
22546
|
+
var GeoStrategyRunContextJsonSchema = import_index2.default.GeoStrategyRunContextJsonSchema;
|
|
22433
22547
|
var GeoStrategyAgentOutputSchema = import_index2.default.GeoStrategyAgentOutputSchema;
|
|
22434
22548
|
var GeoStrategySubagentArtifactSchema = import_index2.default.GeoStrategySubagentArtifactSchema;
|
|
22435
22549
|
var GeoStrategyActionsArtifactSubmitSchema = import_index2.default.GeoStrategyActionsArtifactSubmitSchema;
|
|
@@ -22456,6 +22570,7 @@ var StrategyMapStrategySchema = import_index2.default.StrategyMapStrategySchema;
|
|
|
22456
22570
|
var StrategyMapEvidenceSchema = import_index2.default.StrategyMapEvidenceSchema;
|
|
22457
22571
|
var parseGeoStrategyActionsArtifact = import_index2.default.parseGeoStrategyActionsArtifact;
|
|
22458
22572
|
var parseGeoStrategyActionsArtifactWithMetadata = import_index2.default.parseGeoStrategyActionsArtifactWithMetadata;
|
|
22573
|
+
var parseGeoStrategyChannelActionsArtifactWithMetadata = import_index2.default.parseGeoStrategyChannelActionsArtifactWithMetadata;
|
|
22459
22574
|
var allowedGeoStrategyArtifactPaths = import_index2.default.allowedGeoStrategyArtifactPaths;
|
|
22460
22575
|
var allowedStrategyMapArtifactPaths = import_index2.default.allowedStrategyMapArtifactPaths;
|
|
22461
22576
|
var formatGeoStrategyActionsArtifactContract = import_index2.default.formatGeoStrategyActionsArtifactContract;
|
|
@@ -22492,7 +22607,7 @@ import { join as join6, relative as relative2, resolve as resolve3 } from "node:
|
|
|
22492
22607
|
|
|
22493
22608
|
// src/geo/package-writer.ts
|
|
22494
22609
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
22495
|
-
import { join as join2 } from "node:path";
|
|
22610
|
+
import { dirname, join as join2 } from "node:path";
|
|
22496
22611
|
async function writeGeoRunPackage(input) {
|
|
22497
22612
|
const runDir = join2(input.repoPath, "agent", "runs", input.package.runId);
|
|
22498
22613
|
const agentDir = join2(input.repoPath, "agent");
|
|
@@ -22501,6 +22616,7 @@ async function writeGeoRunPackage(input) {
|
|
|
22501
22616
|
const artifactPaths = allowedArtifactPaths(input.package.runId);
|
|
22502
22617
|
await mkdir(runDir, { recursive: true });
|
|
22503
22618
|
await mkdir(agentDir, { recursive: true });
|
|
22619
|
+
await writeBrandAssets(input.repoPath, input.package.brandAssets);
|
|
22504
22620
|
await writeJson(join2(agentDir, "workspace.json"), buildWorkspaceMetadata(input.package));
|
|
22505
22621
|
await writeJson(join2(runDir, "manifest.json"), {
|
|
22506
22622
|
...isRecord(input.package.manifest) ? input.package.manifest : {},
|
|
@@ -22552,6 +22668,19 @@ async function writeGeoRunPackage(input) {
|
|
|
22552
22668
|
});
|
|
22553
22669
|
return { runDir };
|
|
22554
22670
|
}
|
|
22671
|
+
async function writeBrandAssets(repoPath, brandAssets) {
|
|
22672
|
+
if (!brandAssets?.files?.length) return;
|
|
22673
|
+
for (const file of brandAssets.files) {
|
|
22674
|
+
if (!isManagedBrandAssetPath(file.path)) continue;
|
|
22675
|
+
const target = join2(repoPath, file.path);
|
|
22676
|
+
await mkdir(dirname(target), { recursive: true });
|
|
22677
|
+
await writeFile(target, `${file.content.replace(/\s*$/, "")}
|
|
22678
|
+
`, "utf8");
|
|
22679
|
+
}
|
|
22680
|
+
}
|
|
22681
|
+
function isManagedBrandAssetPath(path2) {
|
|
22682
|
+
return path2 === "agent/BRAND.md" || path2 === "agent/BRAND_RULES.md" || /^agent\/BRAND_VOICE\.[a-z][a-z0-9-]*\.md$/i.test(path2);
|
|
22683
|
+
}
|
|
22555
22684
|
function buildWorkspaceMetadata(pkg) {
|
|
22556
22685
|
return {
|
|
22557
22686
|
schemaVersion: 1,
|
|
@@ -23013,9 +23142,9 @@ var VFile = class {
|
|
|
23013
23142
|
* @returns {undefined}
|
|
23014
23143
|
* Nothing.
|
|
23015
23144
|
*/
|
|
23016
|
-
set dirname(
|
|
23145
|
+
set dirname(dirname3) {
|
|
23017
23146
|
assertPath(this.basename, "dirname");
|
|
23018
|
-
this.path = default3.join(
|
|
23147
|
+
this.path = default3.join(dirname3 || "", this.basename);
|
|
23019
23148
|
}
|
|
23020
23149
|
/**
|
|
23021
23150
|
* Get the extname (including dot) (example: `'.js'`).
|
|
@@ -45424,7 +45553,7 @@ import {
|
|
|
45424
45553
|
writeFile as writeFile2
|
|
45425
45554
|
} from "node:fs/promises";
|
|
45426
45555
|
import { homedir as homedir2 } from "node:os";
|
|
45427
|
-
import { dirname, join as join4, relative, resolve as resolve2 } from "node:path";
|
|
45556
|
+
import { dirname as dirname2, join as join4, relative, resolve as resolve2 } from "node:path";
|
|
45428
45557
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
45429
45558
|
import { promisify as promisify7 } from "node:util";
|
|
45430
45559
|
var execFileAsync6 = promisify7(execFile7);
|
|
@@ -45515,7 +45644,7 @@ async function resolveSkillSourceDir(explicit) {
|
|
|
45515
45644
|
);
|
|
45516
45645
|
}
|
|
45517
45646
|
async function resolveBundledSkillSourceDir(fromUrl = new URL(import.meta.url)) {
|
|
45518
|
-
const moduleDir =
|
|
45647
|
+
const moduleDir = dirname2(fileURLToPath3(fromUrl));
|
|
45519
45648
|
const candidate = join4(moduleDir, BUNDLED_SKILLPACK_RELATIVE_PATH);
|
|
45520
45649
|
if (await isDirectory(candidate)) return candidate;
|
|
45521
45650
|
return null;
|
|
@@ -45558,7 +45687,7 @@ async function applyGeoScaffold(input, options) {
|
|
|
45558
45687
|
}
|
|
45559
45688
|
async function syncManagedDirectory(sourceDir, targetDir, changed) {
|
|
45560
45689
|
await rm(targetDir, { recursive: true, force: true });
|
|
45561
|
-
await mkdir3(
|
|
45690
|
+
await mkdir3(dirname2(targetDir), { recursive: true });
|
|
45562
45691
|
await cp(sourceDir, targetDir, { recursive: true });
|
|
45563
45692
|
changed.push(relative(process.cwd(), targetDir) || targetDir);
|
|
45564
45693
|
}
|
|
@@ -45567,13 +45696,27 @@ async function syncContracts(repoPath, changed) {
|
|
|
45567
45696
|
await mkdir3(contractsDir, { recursive: true });
|
|
45568
45697
|
await writeIfChanged(
|
|
45569
45698
|
join4(contractsDir, "actions.schema.json"),
|
|
45570
|
-
`${JSON.stringify(
|
|
45699
|
+
`${JSON.stringify(GeoStrategyActionsArtifactJsonSchema, null, 2)}
|
|
45571
45700
|
`,
|
|
45572
45701
|
changed
|
|
45573
45702
|
);
|
|
45703
|
+
for (const [channel, schema] of Object.entries(GeoStrategyChannelActionsArtifactJsonSchemas)) {
|
|
45704
|
+
await writeIfChanged(
|
|
45705
|
+
join4(contractsDir, `${channel}.actions.schema.json`),
|
|
45706
|
+
`${JSON.stringify(schema, null, 2)}
|
|
45707
|
+
`,
|
|
45708
|
+
changed
|
|
45709
|
+
);
|
|
45710
|
+
}
|
|
45574
45711
|
await writeIfChanged(
|
|
45575
45712
|
join4(contractsDir, "memory-item.schema.json"),
|
|
45576
|
-
`${JSON.stringify(
|
|
45713
|
+
`${JSON.stringify(GeoStrategyMemoryItemJsonSchema, null, 2)}
|
|
45714
|
+
`,
|
|
45715
|
+
changed
|
|
45716
|
+
);
|
|
45717
|
+
await writeIfChanged(
|
|
45718
|
+
join4(contractsDir, "run-context.schema.json"),
|
|
45719
|
+
`${JSON.stringify(GeoStrategyRunContextJsonSchema, null, 2)}
|
|
45577
45720
|
`,
|
|
45578
45721
|
changed
|
|
45579
45722
|
);
|
|
@@ -45689,14 +45832,14 @@ async function listFiles(dir, base = "") {
|
|
|
45689
45832
|
}
|
|
45690
45833
|
async function writeIfMissing(path2, content3, changed) {
|
|
45691
45834
|
if (await exists2(path2)) return;
|
|
45692
|
-
await mkdir3(
|
|
45835
|
+
await mkdir3(dirname2(path2), { recursive: true });
|
|
45693
45836
|
await writeFile2(path2, content3);
|
|
45694
45837
|
changed.push(relative(process.cwd(), path2) || path2);
|
|
45695
45838
|
}
|
|
45696
45839
|
async function writeIfChanged(path2, content3, changed) {
|
|
45697
45840
|
const current2 = await readFile(path2, "utf8").catch(() => null);
|
|
45698
45841
|
if (current2 === content3) return;
|
|
45699
|
-
await mkdir3(
|
|
45842
|
+
await mkdir3(dirname2(path2), { recursive: true });
|
|
45700
45843
|
await writeFile2(path2, content3);
|
|
45701
45844
|
changed.push(relative(process.cwd(), path2) || path2);
|
|
45702
45845
|
}
|
|
@@ -45749,7 +45892,7 @@ async function downloadAuthenticatedSkillpack() {
|
|
|
45749
45892
|
await mkdir3(cacheDir, { recursive: true });
|
|
45750
45893
|
for (const file of payload.files) {
|
|
45751
45894
|
const target = safeJoin(cacheDir, file.path);
|
|
45752
|
-
await mkdir3(
|
|
45895
|
+
await mkdir3(dirname2(target), { recursive: true });
|
|
45753
45896
|
await writeFile2(target, file.content);
|
|
45754
45897
|
}
|
|
45755
45898
|
return join4(cacheDir, "skills");
|
|
@@ -45794,24 +45937,24 @@ function searchRoots() {
|
|
|
45794
45937
|
let cwd = resolve2(process.cwd());
|
|
45795
45938
|
for (; ; ) {
|
|
45796
45939
|
roots.add(cwd);
|
|
45797
|
-
const parent =
|
|
45940
|
+
const parent = dirname2(cwd);
|
|
45798
45941
|
if (parent === cwd) break;
|
|
45799
45942
|
cwd = parent;
|
|
45800
45943
|
}
|
|
45801
|
-
let here =
|
|
45944
|
+
let here = dirname2(fileURLToPath3(import.meta.url));
|
|
45802
45945
|
for (; ; ) {
|
|
45803
45946
|
roots.add(here);
|
|
45804
|
-
const parent =
|
|
45947
|
+
const parent = dirname2(here);
|
|
45805
45948
|
if (parent === here) break;
|
|
45806
45949
|
here = parent;
|
|
45807
45950
|
}
|
|
45808
45951
|
return [...roots];
|
|
45809
45952
|
}
|
|
45810
45953
|
function rootScaffoldSourceDir(skillsSourceDir) {
|
|
45811
|
-
return join4(
|
|
45954
|
+
return join4(dirname2(skillsSourceDir), "scaffold");
|
|
45812
45955
|
}
|
|
45813
45956
|
function rootSharedSourceDir(skillsSourceDir) {
|
|
45814
|
-
return join4(
|
|
45957
|
+
return join4(dirname2(skillsSourceDir), "shared");
|
|
45815
45958
|
}
|
|
45816
45959
|
async function ensureDirectory(path2) {
|
|
45817
45960
|
const s = await stat2(path2);
|
|
@@ -45823,31 +45966,11 @@ async function isDirectory(path2) {
|
|
|
45823
45966
|
async function exists2(path2) {
|
|
45824
45967
|
return stat2(path2).then(() => true).catch(() => false);
|
|
45825
45968
|
}
|
|
45826
|
-
var ACTIONS_SCHEMA = {
|
|
45827
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
45828
|
-
title: "Anymorph GEO actions artifact",
|
|
45829
|
-
type: "object",
|
|
45830
|
-
required: ["runId", "actions"],
|
|
45831
|
-
properties: {
|
|
45832
|
-
runId: { type: "string" },
|
|
45833
|
-
actions: { type: "array", items: { type: "object" } },
|
|
45834
|
-
artifactPaths: { type: "array", items: { type: "string" } }
|
|
45835
|
-
}
|
|
45836
|
-
};
|
|
45837
|
-
var MEMORY_ITEM_SCHEMA = {
|
|
45838
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
45839
|
-
title: "Anymorph GEO memory item",
|
|
45840
|
-
type: "object",
|
|
45841
|
-
required: ["summary"],
|
|
45842
|
-
properties: {
|
|
45843
|
-
summary: { type: "string" },
|
|
45844
|
-
evidence: { type: "array", items: { type: "string" } }
|
|
45845
|
-
}
|
|
45846
|
-
};
|
|
45847
45969
|
|
|
45848
45970
|
// src/geo/validate.ts
|
|
45849
45971
|
import { readFile as readFile2, stat as stat3 } from "node:fs/promises";
|
|
45850
45972
|
import { join as join5 } from "node:path";
|
|
45973
|
+
var CHANNELS = ["brand_owned", "geo_pages", "third_party"];
|
|
45851
45974
|
async function validateGeoRunArtifacts(input) {
|
|
45852
45975
|
const runDir = join5(input.repoPath, "agent", "runs", input.runId);
|
|
45853
45976
|
const errors = [];
|
|
@@ -45865,8 +45988,15 @@ async function validateGeoRunArtifacts(input) {
|
|
|
45865
45988
|
errors.push(`Missing agent/runs/${input.runId}/${file}`);
|
|
45866
45989
|
}
|
|
45867
45990
|
}
|
|
45868
|
-
|
|
45869
|
-
|
|
45991
|
+
const hasRootActions = await exists3(join5(runDir, "actions.json"));
|
|
45992
|
+
const presentChannels = [];
|
|
45993
|
+
for (const channel of CHANNELS) {
|
|
45994
|
+
if (await exists3(join5(runDir, channel, "actions.json"))) presentChannels.push(channel);
|
|
45995
|
+
}
|
|
45996
|
+
if (!hasRootActions && presentChannels.length === 0) {
|
|
45997
|
+
errors.push(
|
|
45998
|
+
`Missing GEO actions artifact. Write agent/runs/${input.runId}/{brand_owned|geo_pages|third_party}/actions.json`
|
|
45999
|
+
);
|
|
45870
46000
|
}
|
|
45871
46001
|
if (!await exists3(join5(runDir, "rationale.md"))) {
|
|
45872
46002
|
errors.push(`Missing agent/runs/${input.runId}/rationale.md`);
|
|
@@ -45876,7 +46006,7 @@ async function validateGeoRunArtifacts(input) {
|
|
|
45876
46006
|
const policy = await readJson2(join5(runDir, "policy.json"), errors);
|
|
45877
46007
|
const products = await readJson2(join5(runDir, "products.json"), errors);
|
|
45878
46008
|
const status = await readJson2(join5(runDir, "status.json"), errors);
|
|
45879
|
-
const actions = await readJson2(join5(runDir, "actions.json"), errors);
|
|
46009
|
+
const actions = hasRootActions ? await readJson2(join5(runDir, "actions.json"), errors) : null;
|
|
45880
46010
|
if (isRecord2(manifest)) validateManifest(manifest, input.runId, errors);
|
|
45881
46011
|
if (isRecord2(status)) validateStatus(status, errors);
|
|
45882
46012
|
if (isRecord2(actions)) {
|
|
@@ -45891,6 +46021,56 @@ async function validateGeoRunArtifacts(input) {
|
|
|
45891
46021
|
errors
|
|
45892
46022
|
);
|
|
45893
46023
|
}
|
|
46024
|
+
for (const channel of presentChannels) {
|
|
46025
|
+
const channelActions = await readJson2(join5(runDir, channel, "actions.json"), errors);
|
|
46026
|
+
if (isRecord2(channelActions)) {
|
|
46027
|
+
validateActionsArtifact(
|
|
46028
|
+
channelActions,
|
|
46029
|
+
{
|
|
46030
|
+
runId: input.runId,
|
|
46031
|
+
policy,
|
|
46032
|
+
isCommerce: isCommerceRun(context, products),
|
|
46033
|
+
productIds: collectProductIds(products),
|
|
46034
|
+
channel
|
|
46035
|
+
},
|
|
46036
|
+
errors
|
|
46037
|
+
);
|
|
46038
|
+
}
|
|
46039
|
+
if (!await exists3(join5(runDir, channel, "rationale.md"))) {
|
|
46040
|
+
errors.push(`Missing agent/runs/${input.runId}/${channel}/rationale.md`);
|
|
46041
|
+
}
|
|
46042
|
+
}
|
|
46043
|
+
return {
|
|
46044
|
+
ok: errors.length === 0,
|
|
46045
|
+
errors,
|
|
46046
|
+
warnings: [],
|
|
46047
|
+
runDir
|
|
46048
|
+
};
|
|
46049
|
+
}
|
|
46050
|
+
async function validateGeoChannelArtifacts(input) {
|
|
46051
|
+
const runDir = join5(input.repoPath, "agent", "runs", input.runId);
|
|
46052
|
+
const errors = [];
|
|
46053
|
+
const context = await readJson2(join5(runDir, "context.json"), errors);
|
|
46054
|
+
const policy = await readJson2(join5(runDir, "policy.json"), errors);
|
|
46055
|
+
const products = await readJson2(join5(runDir, "products.json"), errors);
|
|
46056
|
+
const actionsPath = join5(runDir, input.channel, "actions.json");
|
|
46057
|
+
const actions = await readJson2(actionsPath, errors);
|
|
46058
|
+
if (!await exists3(join5(runDir, input.channel, "rationale.md"))) {
|
|
46059
|
+
errors.push(`Missing agent/runs/${input.runId}/${input.channel}/rationale.md`);
|
|
46060
|
+
}
|
|
46061
|
+
if (isRecord2(actions)) {
|
|
46062
|
+
validateActionsArtifact(
|
|
46063
|
+
actions,
|
|
46064
|
+
{
|
|
46065
|
+
runId: input.runId,
|
|
46066
|
+
policy,
|
|
46067
|
+
isCommerce: isCommerceRun(context, products),
|
|
46068
|
+
productIds: collectProductIds(products),
|
|
46069
|
+
channel: input.channel
|
|
46070
|
+
},
|
|
46071
|
+
errors
|
|
46072
|
+
);
|
|
46073
|
+
}
|
|
45894
46074
|
return {
|
|
45895
46075
|
ok: errors.length === 0,
|
|
45896
46076
|
errors,
|
|
@@ -45923,7 +46103,7 @@ function validateManifest(value, runId, errors) {
|
|
|
45923
46103
|
}
|
|
45924
46104
|
}
|
|
45925
46105
|
function validateActionsArtifact(artifact, context, errors) {
|
|
45926
|
-
const parsed = GeoStrategyActionsArtifactSchema.safeParse(artifact);
|
|
46106
|
+
const parsed = context.channel ? GeoStrategyChannelActionsArtifactSchema.safeParse(artifact) : GeoStrategyActionsArtifactSchema.safeParse(artifact);
|
|
45927
46107
|
if (!parsed.success) {
|
|
45928
46108
|
for (const issue of parsed.error.issues) {
|
|
45929
46109
|
errors.push(
|
|
@@ -45934,10 +46114,13 @@ function validateActionsArtifact(artifact, context, errors) {
|
|
|
45934
46114
|
}
|
|
45935
46115
|
rejectExtraKeys(
|
|
45936
46116
|
artifact,
|
|
45937
|
-
["schemaVersion", "runId", "policy", "actions"],
|
|
46117
|
+
context.channel ? ["schemaVersion", "runId", "channel", "policy", "actions"] : ["schemaVersion", "runId", "policy", "actions"],
|
|
45938
46118
|
"actions.json",
|
|
45939
46119
|
errors
|
|
45940
46120
|
);
|
|
46121
|
+
if (context.channel && artifact.channel !== context.channel) {
|
|
46122
|
+
errors.push(`actions.json channel must be ${context.channel}`);
|
|
46123
|
+
}
|
|
45941
46124
|
if (artifact.schemaVersion !== 1) errors.push("actions.json schemaVersion must be 1");
|
|
45942
46125
|
if (artifact.runId !== context.runId) {
|
|
45943
46126
|
errors.push(`actions.json runId must match ${context.runId}`);
|
|
@@ -46002,6 +46185,12 @@ function validateActionItem(action, index2, context, seen, errors) {
|
|
|
46002
46185
|
if (!["brand_owned", "geo_page", "third_party"].includes(String(action.assetType))) {
|
|
46003
46186
|
errors.push(`${path2}.assetType must be brand_owned, geo_page, or third_party`);
|
|
46004
46187
|
}
|
|
46188
|
+
if (context.channel) {
|
|
46189
|
+
const expectedAssetType = context.channel === "geo_pages" ? "geo_page" : context.channel;
|
|
46190
|
+
if (action.assetType !== expectedAssetType) {
|
|
46191
|
+
errors.push(`${path2}.assetType must be ${expectedAssetType} for ${context.channel}`);
|
|
46192
|
+
}
|
|
46193
|
+
}
|
|
46005
46194
|
validateIntentRef(action, path2, errors);
|
|
46006
46195
|
validateActionFields(action, path2, errors);
|
|
46007
46196
|
validateActionByType(action, path2, context, errors);
|
|
@@ -46250,11 +46439,14 @@ Examples:
|
|
|
46250
46439
|
$ anymorph validate 20260517T074200Z
|
|
46251
46440
|
$ anymorph validate run 20260517T074200Z
|
|
46252
46441
|
$ anymorph validate actions 20260517T074200Z
|
|
46442
|
+
$ anymorph validate brand-owned 20260517T074200Z
|
|
46443
|
+
$ anymorph validate geo-pages 20260517T074200Z
|
|
46444
|
+
$ anymorph validate third-party 20260517T074200Z
|
|
46253
46445
|
$ anymorph validate mdx content/guide/page.mdx
|
|
46254
46446
|
$ anymorph validate mdx "content/**/*.mdx"
|
|
46255
46447
|
$ anymorph validate 20260517T074200Z --json
|
|
46256
46448
|
|
|
46257
|
-
Checks required run files,
|
|
46449
|
+
Checks required run files, shared root/channel actions.json contracts, policy hash,
|
|
46258
46450
|
per-asset target rules, commerce targetProductIds, or CMS renderer MDX validation.`
|
|
46259
46451
|
).action(async (runId, opts) => {
|
|
46260
46452
|
if (!runId) {
|
|
@@ -46269,6 +46461,21 @@ per-asset target rules, commerce targetProductIds, or CMS renderer MDX validatio
|
|
|
46269
46461
|
validateCommand.addCommand(
|
|
46270
46462
|
new Command("actions").argument("<runId>").description("Validate actions.json and related local GEO run artifacts").option("--json", "Output as JSON").action(geoValidateCommand)
|
|
46271
46463
|
);
|
|
46464
|
+
validateCommand.addCommand(
|
|
46465
|
+
new Command("brand-owned").argument("<runId>").description("Validate brand_owned/actions.json for a local GEO run").option("--json", "Output as JSON").action(
|
|
46466
|
+
(runId, opts) => geoValidateChannelCommand(runId, "brand_owned", opts)
|
|
46467
|
+
)
|
|
46468
|
+
);
|
|
46469
|
+
validateCommand.addCommand(
|
|
46470
|
+
new Command("geo-pages").argument("<runId>").description("Validate geo_pages/actions.json for a local GEO run").option("--json", "Output as JSON").action(
|
|
46471
|
+
(runId, opts) => geoValidateChannelCommand(runId, "geo_pages", opts)
|
|
46472
|
+
)
|
|
46473
|
+
);
|
|
46474
|
+
validateCommand.addCommand(
|
|
46475
|
+
new Command("third-party").argument("<runId>").description("Validate third_party/actions.json for a local GEO run").option("--json", "Output as JSON").action(
|
|
46476
|
+
(runId, opts) => geoValidateChannelCommand(runId, "third_party", opts)
|
|
46477
|
+
)
|
|
46478
|
+
);
|
|
46272
46479
|
validateCommand.addCommand(
|
|
46273
46480
|
new Command("mdx").argument("<paths...>").description("Validate CMS MDX with the renderer publish gate").option("--json", "Output as JSON").addHelpText(
|
|
46274
46481
|
"after",
|
|
@@ -46439,6 +46646,24 @@ async function geoValidateCommand(runId, opts) {
|
|
|
46439
46646
|
console.error();
|
|
46440
46647
|
process.exit(1);
|
|
46441
46648
|
}
|
|
46649
|
+
async function geoValidateChannelCommand(runId, channel, opts) {
|
|
46650
|
+
const repoPath = await resolveCurrentRepoRoot();
|
|
46651
|
+
const result = await validateGeoChannelArtifacts({ repoPath, runId, channel });
|
|
46652
|
+
if (opts.json) {
|
|
46653
|
+
console.log(JSON.stringify({ ...result, repoPath, channel }, null, 2));
|
|
46654
|
+
process.exit(result.ok ? 0 : 1);
|
|
46655
|
+
}
|
|
46656
|
+
if (result.ok) {
|
|
46657
|
+
console.log(source_default.green(`
|
|
46658
|
+
GEO ${channel} actions for ${runId} are valid.
|
|
46659
|
+
`));
|
|
46660
|
+
return;
|
|
46661
|
+
}
|
|
46662
|
+
console.error(source_default.red("\n Validation failed\n"));
|
|
46663
|
+
for (const error of result.errors) console.error(` - ${error}`);
|
|
46664
|
+
console.error();
|
|
46665
|
+
process.exit(1);
|
|
46666
|
+
}
|
|
46442
46667
|
async function geoValidateMdxCommand(paths, opts) {
|
|
46443
46668
|
const json = opts.json || paths.includes("--json");
|
|
46444
46669
|
const cleanPaths = paths.filter((path2) => path2 !== "--json");
|
|
@@ -46698,7 +46923,7 @@ function printScaffoldError(prefix, err) {
|
|
|
46698
46923
|
|
|
46699
46924
|
// src/index.ts
|
|
46700
46925
|
var program2 = new Command();
|
|
46701
|
-
program2.name("anymorph").description("Check AI visibility and run local GEO strategy workflows").version("0.
|
|
46926
|
+
program2.name("anymorph").description("Check AI visibility and run local GEO strategy workflows").version("0.13.0");
|
|
46702
46927
|
program2.command("login").description("Sign in to your Anymorph account").addHelpText(
|
|
46703
46928
|
"after",
|
|
46704
46929
|
`
|
|
@@ -46775,7 +47000,11 @@ Command usage:
|
|
|
46775
47000
|
Must be run from the tenant repo root.
|
|
46776
47001
|
|
|
46777
47002
|
anymorph validate <runId> [--json]
|
|
46778
|
-
Validate local run files and actions
|
|
47003
|
+
Validate local run files and channel actions before pushing.
|
|
47004
|
+
Must be run from the tenant repo root.
|
|
47005
|
+
|
|
47006
|
+
anymorph validate brand-owned|geo-pages|third-party <runId> [--json]
|
|
47007
|
+
Validate one channel actions artifact before pushing.
|
|
46779
47008
|
Must be run from the tenant repo root.
|
|
46780
47009
|
|
|
46781
47010
|
anymorph validate mdx <paths...> [--json]
|