agentlinkops 0.6.13 → 0.6.16

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.
Files changed (178) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/.codex-plugin/plugin.json +2 -2
  3. package/CHANGELOG.md +25 -2
  4. package/PACK-ARTIFACT.json +16 -0
  5. package/PACKS.json +591 -0
  6. package/README.md +34 -48
  7. package/cli/adapters/suppliers.js +1 -1
  8. package/cli/agent-setup.js +101 -17
  9. package/cli/campaign-bridge.js +325 -0
  10. package/cli/campaign-outcomes.js +107 -0
  11. package/cli/catalog.js +45702 -18674
  12. package/cli/check.js +40 -10
  13. package/cli/client.js +2 -1
  14. package/cli/commands.js +17 -8
  15. package/cli/connection.js +92 -18
  16. package/cli/contact-adoption.js +91 -0
  17. package/cli/context.js +13 -2
  18. package/cli/doctor.js +15 -4
  19. package/cli/import.js +7 -1
  20. package/cli/key-store.js +115 -0
  21. package/cli/ledger.js +1 -0
  22. package/cli/local-result.js +41 -6
  23. package/cli/main.js +51 -12
  24. package/cli/mcp-client.js +2 -2
  25. package/cli/migration.js +308 -0
  26. package/cli/prompt.js +25 -0
  27. package/cli/public-http.js +168 -0
  28. package/cli/state.js +14 -0
  29. package/cli/sync.js +1 -1
  30. package/package.json +7 -8
  31. package/references/citation-panels.md +2 -0
  32. package/references/cli.md +2 -2
  33. package/references/disavow.md +1 -1
  34. package/references/discovery-handoff.md +1 -1
  35. package/references/local-crm-draft-handoff.md +1 -1
  36. package/references/portable-ledger-handoff.md +11 -10
  37. package/references/recipes/catalog.json +263 -7
  38. package/references/recipes/command-notes.md +5 -3
  39. package/references/recipes/internal-link-improvement.md +25 -0
  40. package/references/recipes/placement-reconciliation.md +53 -1
  41. package/scripts/portable-handoff.py +17 -4
  42. package/shared/admission-contract.js +3 -2
  43. package/shared/admission-report-contract.js +3 -2
  44. package/shared/analytics-history-contract.js +15 -0
  45. package/shared/campaign-outcome-contract.js +12 -0
  46. package/shared/campaign-prospect-contract.js +23 -0
  47. package/shared/classification-contract.js +54 -0
  48. package/shared/contact-record-contract.js +27 -0
  49. package/shared/disavow-contract.js +37 -9
  50. package/shared/index-observation-contract.js +5 -4
  51. package/shared/internal-links-contract.js +143 -0
  52. package/shared/link-category-contract.js +35 -0
  53. package/shared/link-category.js +138 -0
  54. package/shared/link-labels.js +26 -0
  55. package/shared/link-summary-contract.js +17 -0
  56. package/shared/observation-event.js +1 -1
  57. package/shared/onboarding.js +20 -0
  58. package/shared/response-contract.js +38 -5
  59. package/shared/search-connection-contract.js +2 -1
  60. package/shared/table-page-contract.js +13 -0
  61. package/skills/agentlinkops-assets/SKILL-DEPS.json +290 -0
  62. package/skills/agentlinkops-assets/SKILL.md +3 -1
  63. package/skills/agentlinkops-assets/agents/openai.yaml +1 -1
  64. package/skills/agentlinkops-assets/references/portable/references/cli.md +220 -0
  65. package/skills/agentlinkops-assets/references/portable/references/disavow.md +73 -0
  66. package/skills/agentlinkops-assets/references/portable/references/reports.md +53 -0
  67. package/skills/agentlinkops-assets/references/portable/scripts/agentlinkops.py +676 -0
  68. package/skills/agentlinkops-assets/references/portable/scripts/disavow.py +207 -0
  69. package/skills/agentlinkops-assets/references/portable/scripts/migrations/001_crm.sql +45 -0
  70. package/skills/agentlinkops-assets/references/portable/scripts/migrations/002_cloud_events.sql +13 -0
  71. package/skills/agentlinkops-assets/references/portable/scripts/migrations/003_disavow.sql +20 -0
  72. package/skills/agentlinkops-assets/references/portable/scripts/migrations/004_placement_costs.sql +2 -0
  73. package/skills/agentlinkops-assets/references/portable/scripts/report.py +113 -0
  74. package/skills/agentlinkops-assets/references/portable/templates/campaigns.v1.json +65 -0
  75. package/skills/agentlinkops-campaigns/SKILL-DEPS.json +336 -0
  76. package/skills/agentlinkops-campaigns/SKILL.md +7 -5
  77. package/skills/agentlinkops-campaigns/agents/openai.yaml +1 -1
  78. package/skills/agentlinkops-campaigns/references/first-campaign.md +31 -0
  79. package/skills/agentlinkops-campaigns/references/mailbox-campaign.md +46 -0
  80. package/skills/agentlinkops-campaigns/references/portable/references/cli.md +220 -0
  81. package/skills/agentlinkops-campaigns/references/portable/references/disavow.md +73 -0
  82. package/skills/agentlinkops-campaigns/references/portable/references/reports.md +53 -0
  83. package/skills/agentlinkops-campaigns/references/portable/scripts/agentlinkops.py +676 -0
  84. package/skills/agentlinkops-campaigns/references/portable/scripts/disavow.py +207 -0
  85. package/skills/agentlinkops-campaigns/references/portable/scripts/migrations/001_crm.sql +45 -0
  86. package/skills/agentlinkops-campaigns/references/portable/scripts/migrations/002_cloud_events.sql +13 -0
  87. package/skills/agentlinkops-campaigns/references/portable/scripts/migrations/003_disavow.sql +20 -0
  88. package/skills/agentlinkops-campaigns/references/portable/scripts/migrations/004_placement_costs.sql +2 -0
  89. package/skills/agentlinkops-campaigns/references/portable/scripts/report.py +113 -0
  90. package/skills/agentlinkops-campaigns/references/portable/templates/campaigns.v1.json +65 -0
  91. package/skills/agentlinkops-connect/SKILL-DEPS.json +104 -0
  92. package/skills/agentlinkops-connect/SKILL.md +2 -0
  93. package/skills/agentlinkops-connect/agents/openai.yaml +1 -1
  94. package/skills/agentlinkops-connect/references/agentlinkops.md +164 -62
  95. package/skills/agentlinkops-connect/references/placement-workflows.md +19 -0
  96. package/skills/agentlinkops-crm/SKILL-DEPS.json +381 -0
  97. package/skills/agentlinkops-crm/SKILL.md +26 -9
  98. package/skills/agentlinkops-crm/agents/openai.yaml +1 -1
  99. package/skills/agentlinkops-crm/references/portable/references/cli.md +220 -0
  100. package/skills/agentlinkops-crm/references/portable/references/disavow.md +73 -0
  101. package/skills/agentlinkops-crm/references/portable/references/local-crm-draft-handoff.md +76 -0
  102. package/skills/agentlinkops-crm/references/portable/references/portable-ledger-handoff.md +51 -0
  103. package/skills/agentlinkops-crm/references/portable/references/reports.md +53 -0
  104. package/skills/agentlinkops-crm/references/portable/scripts/agentlinkops.py +676 -0
  105. package/skills/agentlinkops-crm/references/portable/scripts/disavow.py +207 -0
  106. package/skills/agentlinkops-crm/references/portable/scripts/migrations/001_crm.sql +45 -0
  107. package/skills/agentlinkops-crm/references/portable/scripts/migrations/002_cloud_events.sql +13 -0
  108. package/skills/agentlinkops-crm/references/portable/scripts/migrations/003_disavow.sql +20 -0
  109. package/skills/agentlinkops-crm/references/portable/scripts/migrations/004_placement_costs.sql +2 -0
  110. package/skills/agentlinkops-crm/references/portable/scripts/outreach-crm-draft.py +121 -0
  111. package/skills/agentlinkops-crm/references/portable/scripts/portable-handoff.py +197 -0
  112. package/skills/agentlinkops-crm/references/portable/scripts/report.py +113 -0
  113. package/skills/agentlinkops-crm/references/portable/templates/campaigns.v1.json +65 -0
  114. package/skills/agentlinkops-discovery/SKILL-DEPS.json +301 -0
  115. package/skills/agentlinkops-discovery/SKILL.md +4 -2
  116. package/skills/agentlinkops-discovery/references/portable/references/cli.md +220 -0
  117. package/skills/agentlinkops-discovery/references/portable/references/disavow.md +73 -0
  118. package/skills/agentlinkops-discovery/references/portable/references/discovery-handoff.md +32 -0
  119. package/skills/agentlinkops-discovery/references/portable/references/reports.md +53 -0
  120. package/skills/agentlinkops-discovery/references/portable/scripts/agentlinkops.py +676 -0
  121. package/skills/agentlinkops-discovery/references/portable/scripts/disavow.py +207 -0
  122. package/skills/agentlinkops-discovery/references/portable/scripts/migrations/001_crm.sql +45 -0
  123. package/skills/agentlinkops-discovery/references/portable/scripts/migrations/002_cloud_events.sql +13 -0
  124. package/skills/agentlinkops-discovery/references/portable/scripts/migrations/003_disavow.sql +20 -0
  125. package/skills/agentlinkops-discovery/references/portable/scripts/migrations/004_placement_costs.sql +2 -0
  126. package/skills/agentlinkops-discovery/references/portable/scripts/report.py +113 -0
  127. package/skills/agentlinkops-discovery/references/portable/templates/campaigns.v1.json +65 -0
  128. package/skills/agentlinkops-discovery/references/saved-backlink-workflows.md +23 -0
  129. package/src/competitors/contract.js +17 -1
  130. package/src/context/site-profile.js +34 -121
  131. package/src/corpus/acquire.js +68 -32
  132. package/src/corpus/extract.js +147 -0
  133. package/src/corpus/frontier.js +151 -0
  134. package/src/discovery/contract.js +8 -0
  135. package/src/discovery/import.js +13 -1
  136. package/src/mentions.js +193 -0
  137. package/src/page-acquisition/acquire.js +50 -0
  138. package/src/page-acquisition/bytes.js +138 -0
  139. package/src/page-acquisition/capture.js +11 -0
  140. package/src/page-acquisition/contracts.js +67 -0
  141. package/src/page-acquisition/documents.js +166 -0
  142. package/src/page-acquisition/http.js +307 -0
  143. package/src/page-acquisition/policy.js +20 -0
  144. package/src/page-acquisition/recovery.js +164 -0
  145. package/src/page-acquisition/render-failure.js +82 -0
  146. package/src/page-extraction/html.js +359 -0
  147. package/src/page-extraction/index.js +30 -0
  148. package/src/page-extraction/metadata.js +16 -0
  149. package/src/response-shaping.js +4 -3
  150. package/src/tool-views.js +22 -12
  151. package/src/verifier/fetch.js +4 -339
  152. package/src/verifier/index.js +81 -23
  153. package/src/verifier/page-quality.js +14 -0
  154. package/src/verifier/parser.js +2 -241
  155. package/src/verifier/readiness.js +64 -13
  156. package/src/verifier/render-evidence.js +25 -2
  157. package/src/verifier/target.js +201 -0
  158. package/src/verifier/transition.js +18 -3
  159. package/src/verifier/url.js +31 -0
  160. package/src/watch-crawlability.js +144 -0
  161. package/skills/content-defingerprinting/SKILL.md +0 -29
  162. package/skills/content-defingerprinting/scripts/watermarks/README.md +0 -102
  163. package/skills/content-defingerprinting/scripts/watermarks/UPSTREAM.json +0 -26
  164. package/skills/content-defingerprinting/scripts/watermarks/revendor.sh +0 -52
  165. package/skills/content-defingerprinting/scripts/watermarks/vendor/LICENSE.upstream +0 -21
  166. package/skills/content-defingerprinting/scripts/watermarks/vendor/clean_text.py +0 -96
  167. package/skills/content-defingerprinting/scripts/watermarks/vendor/common.py +0 -432
  168. package/skills/content-defingerprinting/scripts/watermarks/vendor/inspect_text.py +0 -86
  169. package/skills/content-defingerprinting/scripts/watermarks/vendor/score_stylometry.py +0 -460
  170. package/skills/content-defingerprinting/scripts/watermarks/vendor/text_unicode.py +0 -651
  171. package/skills/content-defingerprinting/scripts/watermarks/verify-vendor.py +0 -27
  172. package/skills/content-defingerprinting/scripts/watermarks/wm-scan.py +0 -212
  173. package/skills/internal-linking-optimizer/SKILL.md +0 -56
  174. package/skills/internal-linking-optimizer/references/source-prompt.md +0 -76
  175. package/skills/pre-publish-review/SKILL.md +0 -179
  176. package/skills/source-cited-content-builder/SKILL.md +0 -56
  177. package/skills/source-cited-content-builder/references/source-prompt.md +0 -19
  178. package/skills/source-cited-humanizer/SKILL.md +0 -20
@@ -6,7 +6,7 @@ export function eventSnapshot(state) {
6
6
  rel: (item.rel || []).slice(0, 20),
7
7
  }));
8
8
  return {
9
- schema_version: 1, target_scope: state.target_scope,
9
+ schema_version: 1, display_state: state.pipeline?.intent==='prospect' && !state.wasEverPresent ? 'prospect' : ['confirmed_missing','suspected_missing'].includes(state.state) && !state.wasEverPresent ? 'unverified' : state.state||'unknown', was_ever_present:state.wasEverPresent === true, intent:state.pipeline?.intent??'earned', target_scope: state.target_scope,
10
10
  check_state: latest.state ?? 'unknown', link_signature: latest.linkSignature ?? null,
11
11
  checker_version: latest.evidence?.checkerVersion ?? null,
12
12
  // Hash the captured document, not the enclosing R2 receipt object. Older events
@@ -0,0 +1,20 @@
1
+ import {z} from 'zod';
2
+
3
+ export const initialOnboarding = () => ({version:1,revision:0,step:'website',projectId:null,gsc:null,returnTo:null,completedAt:null});
4
+ export const onboardingState = z.object({
5
+ version:z.literal(1),revision:z.number().int().nonnegative(),step:z.enum(['website','google','finish','complete']),
6
+ projectId:z.string().nullable(),gsc:z.enum(['connected','later']).nullable(),returnTo:z.string().nullable(),completedAt:z.string().nullable(),
7
+ });
8
+ export const onboardingResponse = z.object({required:z.boolean(),state:onboardingState.nullable()});
9
+
10
+ // Keep only the two existing account-return destinations. Never persist an OAuth code,
11
+ // bearer, arbitrary URL or user-supplied permission scope in workspace metadata.
12
+ export function onboardingReturnTo(value) {
13
+ if(typeof value!=='string'||!value.startsWith('#/'))return null;
14
+ const [route,query]=value.slice(2).split('?'),params=new URLSearchParams(query);
15
+ if(route==='workspace'&&params.get('section')==='invitations')return '#/workspace?section=invitations';
16
+ const clientId=params.get('clientId');
17
+ if(route==='access'&&params.get('section')==='grants'&&params.getAll('clientId').length===1&&clientId&&clientId.length<=2048&&!/[\s\u0000-\u001f\u007f]/.test(clientId))
18
+ return `#/access?${new URLSearchParams({section:'grants',clientId})}`;
19
+ return null;
20
+ }
@@ -1,19 +1,32 @@
1
+ import {onboardingResponse} from './onboarding.js';
2
+ import {internalLinkPreviewOutput,internalLinkSnapshotOutput,internalLinkListOutput,internalLinkQueryOutput} from './internal-links-contract.js';
3
+ import {profileHistoryOutput,profileHistoryRecordsOutput} from './analytics-history-contract.js';
4
+ import {classificationMetadataResponse,classificationMetadataWriteResponse,classificationMetadataOccurrenceResponse,classificationResponse,classificationHistoryResponse,classificationQuoteResponse,classificationJobResponse} from './classification-contract.js';
1
5
  import {chronologyResponse,assuranceResponse} from './monitoring-read-contract.js';
2
6
  import {lifecycleOutput} from './lifecycle-contract.js';
7
+ import {contactResponses} from './contact-record-contract.js';
8
+ import {prospectResponses} from './campaign-prospect-contract.js';
9
+ import {campaignOutcomeResponses} from './campaign-outcome-contract.js';
3
10
  import {searchConnectionsResponse,searchRowsResponse,searchSyncResponse,searchPropertiesResponse,searchStartResponse,searchConnection,searchImportResponse} from './search-connection-contract.js';
11
+ import {linkSummaryResponse} from './link-summary-contract.js';
12
+ import {linkCategoryFields,linkLabelledWatchResponse,linkLabelledWatchesResponse} from './link-category-contract.js';
13
+ export {linkSummaryResponse};
4
14
  import {z} from 'zod';
5
15
  export const objectResponse=z.looseObject({});
6
16
  export const pageResponse=z.looseObject({items:z.array(objectResponse),next_cursor:z.string().nullable().optional()});
7
- export const watchResponse=z.looseObject({id:z.string(),source_url:z.string(),target_url:z.string(),state:z.string(),observation_state:objectResponse});
17
+ // Category fields share the documented contract while remaining additive for older
18
+ // deployments. List rows may be concise; detailed watch requirements stay separate.
19
+ export const watchPageResponse=pageResponse.extend({items:z.array(z.looseObject(linkCategoryFields))});
20
+ export const watchResponse=z.looseObject({...linkCategoryFields,id:z.string(),source_url:z.string(),target_url:z.string(),state:z.string(),observation_state:objectResponse});
8
21
  export const targetResponse=z.looseObject({id:z.string(),url:z.string(),state:z.string(),observation_state:objectResponse});
9
22
  export const historyResponse=z.looseObject({items:z.array(z.looseObject({id:z.string(),state:z.string(),checked_at:z.string(),result:objectResponse})),next_cursor:z.string().nullable().optional()});
10
23
  export const jobResponse=z.looseObject({id:z.string(),state:z.enum(['queued','running','succeeded','failed','cancelled'])});
11
24
  export const observationEvent=z.looseObject({id:z.string(),data:objectResponse});
12
- export const eventFeedResponse=z.looseObject({events:z.array(observationEvent),next_cursor:z.string(),has_more:z.boolean()});
25
+ export const eventFeedResponse=z.looseObject({events:z.array(observationEvent),next_cursor:z.string().nullable(),has_more:z.boolean()});
13
26
  export const linkChangeReportResponse=z.looseObject({schema_version:z.literal(1),workspace_id:z.string(),project_id:z.string(),coverage_scope:z.literal('retained_event_feed'),
14
27
  from:z.string(),as_of:z.string(),through_sequence:z.number().int().nonnegative(),count:z.number().int().nonnegative(),
15
28
  limit:z.literal(500),truncated:z.boolean(),complete:z.boolean(),retention_limited:z.boolean(),scan_limit:z.literal(10000),scan_limited:z.boolean(),
16
- events:z.array(z.looseObject({id:z.string(),workspace_id:z.string(),project_id:z.string(),type:z.enum(['placement_acquired','placement_recovered','placement_lost']),created_at:z.string()})).max(500)});
29
+ events:z.array(z.looseObject({id:z.string(),workspace_id:z.string(),project_id:z.string(),type:z.enum(['placement_acquired','placement_recovered','placement_lost','prospect_won']),created_at:z.string()})).max(500)});
17
30
  export const usageResponse=z.looseObject({
18
31
  workspace_id:z.string(),period:z.string().regex(/^\d{4}-\d{2}$/),plan:z.string(),
19
32
  check_reservations:z.looseObject({reserved:z.number().nonnegative(),consumed:z.number().nonnegative(),released:z.number().nonnegative()}),
@@ -42,11 +55,27 @@ export const candidateMonitoringResponse=z.looseObject({
42
55
  });
43
56
  /** Network boundary shared by the console and command adapters. Unknown fields survive evolution. */
44
57
  export function restResponseContract(path,method='GET') {
58
+ const contactCommand=path.split('?')[0].match(/^\/v1\/commands\/([^/]+)$/)?.[1];
59
+ const campaignResponse=prospectResponses[contactCommand]??campaignOutcomeResponses[contactCommand]??contactResponses[contactCommand];
60
+ if(method==='POST'&&campaignResponse)return campaignResponse;
61
+ if(/^\/v1\/projects\/[^/]+\/classification-metadata(?:\/(definitions|settings|occurrences))?(?:\?|$)/.test(path))return method==='GET'?(path.split('?')[0].endsWith('/occurrences')?classificationMetadataOccurrenceResponse:classificationMetadataResponse):classificationMetadataWriteResponse;
62
+ if(/^\/v1\/watches\/[^/]+\/classification\/history(?:\?|$)/.test(path))return classificationHistoryResponse;
63
+ if(/^\/v1\/watches\/[^/]+\/classification\/quote(?:\?|$)/.test(path))return classificationQuoteResponse;
64
+ if(/^\/v1\/watches\/[^/]+\/classification\/(?:classify|jobs\/[^/?]+(?:\/reconcile)?)(?:\?|$)/.test(path))return classificationJobResponse;
65
+ if(/^\/v1\/watches\/[^/]+\/classification(?:\/prepare)?(?:\?|$)/.test(path))return classificationResponse;
45
66
  const pathname=path.split('?')[0];
67
+ if(pathname==='/v1/onboarding')return onboardingResponse;
68
+ if(pathname==='/v1/internal-links/preview'&&method==='POST')return internalLinkPreviewOutput;
69
+ if(pathname==='/v1/internal-links/snapshots')return method==='GET'?internalLinkListOutput:internalLinkSnapshotOutput;
70
+ if(/^\/v1\/internal-links\/snapshots\/[^/]+\/query$/.test(pathname))return internalLinkQueryOutput;
71
+ if(/^\/v1\/internal-links\/snapshots\/[^/]+(?:\/process)?$/.test(pathname))return internalLinkSnapshotOutput;
72
+ if(method==='PUT' && /^\/v1\/watches\/[^/]+\/type$/.test(pathname))return linkLabelledWatchResponse;
73
+ if(method==='POST' && pathname==='/v1/watches/bulk-labels')return linkLabelledWatchesResponse;
74
+ if(['POST','DELETE'].includes(method) && /^\/v1\/watches\/[^/]+\/tags(?:\/[^/]+)?$/.test(pathname))return linkLabelledWatchesResponse;
46
75
  if(method==='POST' && /^\/v1\/discovery\/runs\/[^/]+\/verification-batches$/.test(pathname))return candidateVerificationBatchResponse;
47
76
  if(method==='GET' && /^\/v1\/discovery\/verification-batches\/[^/]+$/.test(pathname))return candidateVerificationBatchResponse;
48
77
  if(method==='POST' && /^\/v1\/discovery\/verifications\/[^/]+\/monitor$/.test(pathname))return candidateMonitoringResponse;
49
- if(pathname==='/v1/search-connections'&&method==='GET')return searchConnectionsResponse;
78
+ if(pathname==='/v1/search-connections'&&method==='GET')return /[?&]all=1(?:&|$)/.test(path)?z.looseObject({websites:z.array(z.looseObject({project:z.looseObject({id:z.string()})}))}):searchConnectionsResponse;
50
79
  if(pathname==='/v1/search-connections/start'&&method==='POST')return searchStartResponse;
51
80
  if(/^\/v1\/search-connections\/[^/]+\/rows$/.test(pathname)&&method==='GET')return searchRowsResponse;
52
81
  if(/^\/v1\/search-connections\/[^/]+\/properties$/.test(pathname)&&method==='GET')return searchPropertiesResponse;
@@ -61,9 +90,13 @@ export function restResponseContract(path,method='GET') {
61
90
  if(/^\/v1\/(?:watches|targets)\/[^/]+\/history$/.test(pathname))return historyResponse;
62
91
  if(/^\/v1\/watches\/[^/]+$/.test(pathname))return watchResponse;
63
92
  if(/^\/v1\/targets\/[^/]+$/.test(pathname))return targetResponse;
64
- if(['/v1/watches','/v1/targets','/v1/projects','/v1/exports/watches'].includes(pathname))return pageResponse;
93
+ if(['/v1/watches','/v1/exports/watches'].includes(pathname))return watchPageResponse;
94
+ if(['/v1/targets','/v1/projects'].includes(pathname))return pageResponse;
65
95
  if(pathname==='/v1/usage')return usageResponse;
66
96
  if(pathname==='/v1/reports/link-changes')return linkChangeReportResponse;
97
+ if(pathname==='/v1/reports/history')return profileHistoryOutput;
98
+ if(pathname==='/v1/reports/history/records')return profileHistoryRecordsOutput;
99
+ if(pathname==='/v1/reports/summary')return linkSummaryResponse;
67
100
  if(['/v1/events','/v1/target-events'].includes(pathname))return eventFeedResponse;
68
101
  if(/^\/v1\/(?:jobs|target-jobs)\/[^/]+$/.test(pathname))return jobResponse;
69
102
  return objectResponse;
@@ -1,4 +1,5 @@
1
1
  import {z} from 'zod';
2
+ import {browsePageOutput} from './table-page-contract.js';
2
3
  const text=z.string(),nullable=text.nullable();
3
4
  export const searchConnection=z.looseObject({
4
5
  id:text,project_id:text,provider:z.enum(['google','bing']),status:text,property:nullable,
@@ -11,7 +12,7 @@ export const searchProviderRow=z.discriminatedUnion('kind',[
11
12
  z.looseObject({...rowMeta,kind:z.literal('search_performance'),page:text,query:text,clicks:z.number().nonnegative(),impressions:z.number().nonnegative(),ctr:z.number().nonnegative(),position:z.number().nonnegative(),startDate:text,endDate:text}),
12
13
  z.looseObject({...rowMeta,kind:z.literal('backlinks'),source_url:text,target_url:text,anchor:nullable,supplier:z.literal('bing_webmaster_tools'),verification_status:z.literal('unverified')}),
13
14
  ]);
14
- export const searchRowsResponse=z.looseObject({connection:searchConnection,rows:z.array(searchProviderRow),nextCursor:nullable});
15
+ export const searchRowsResponse=z.looseObject({...browsePageOutput,connection:searchConnection,rows:z.array(searchProviderRow),nextCursor:nullable});
15
16
  export const searchSyncResponse=z.looseObject({connection:searchConnection,rowCount:z.number().int().nonnegative()});
16
17
  export const searchPropertiesResponse=z.looseObject({properties:z.array(z.looseObject({property:text,permission:text}))});
17
18
  export const searchStartResponse=z.looseObject({authorizationUrl:z.url(),expiresAt:text});
@@ -0,0 +1,13 @@
1
+ import {z} from 'zod';
2
+ const filter=z.strictObject({column:z.string().min(1).max(80),operator:z.enum(['contains','is','is_not','empty']),value:z.string().max(500)});
3
+ export const browsePageInput={
4
+ browse:z.boolean().optional().describe('Server-sorted authorized saved rows; omit for legacy paging.'),
5
+ sort:z.string().min(1).max(80).optional().describe('Allowlisted saved-field identifier.'),
6
+ order:z.enum(['asc','desc']).optional().describe('Sort direction; stable ID ties, nulls last.'),
7
+ q:z.string().max(500).optional().describe('Literal search of supported saved fields.'),
8
+ table_filters:z.union([z.string().max(8192),z.array(filter).max(12)]).optional().describe('Up to 12 allowlisted column filters before paging.'),
9
+ };
10
+ export const browseCursor=z.string().min(1).max(16384);
11
+ const count=z.number().int().nonnegative().nullable();
12
+ export const browsePageOutput={total:count.optional(),has_more:z.boolean().optional(),next_cursor:browseCursor.nullable().optional(),
13
+ page:z.strictObject({limit:z.number().int().positive(),sort:z.string(),order:z.enum(['asc','desc']),total:count,query_scope:z.literal('server_dataset'),nulls:z.literal('last')}).optional()};
@@ -0,0 +1,290 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "skill": "agentlinkops-assets",
4
+ "pack": "product",
5
+ "contractSha256": "e3d29a169dd1ecae2db26b22ab666419c4057e84831653df655f04ae61725e93",
6
+ "sourceManifest": [
7
+ {
8
+ "path": "references/cli.md",
9
+ "sha256": "7b665f9d9b60cdab1f0238b71500f8389e0a6df4ea9777db69af6627a000a766"
10
+ },
11
+ {
12
+ "path": "references/disavow.md",
13
+ "sha256": "f8a2ad2c779e15547c6cf6a199b1d4af18ad2ef2c0aa8f27094c00f366c55aaa"
14
+ },
15
+ {
16
+ "path": "references/reports.md",
17
+ "sha256": "361ea12f145daf15c30d35cfaec3f41bfa677fee9c5eabf7dc10b6004cbe617e"
18
+ },
19
+ {
20
+ "path": "scripts/agentlinkops.py",
21
+ "sha256": "91d541768f95e17c059396624c153ca86395bccfc565a8bf3470e2e006404e28"
22
+ },
23
+ {
24
+ "path": "scripts/disavow.py",
25
+ "sha256": "cae36ad7d9e4aef27510975b4c15a66e5649250f6e76df7ca2bfb025a696432e"
26
+ },
27
+ {
28
+ "path": "scripts/migrations/001_crm.sql",
29
+ "sha256": "049fbd38b05c5b8dbab00b6ebee5342b8ed5cf48f65fe6cc1bbf41330ceedf54"
30
+ },
31
+ {
32
+ "path": "scripts/migrations/002_cloud_events.sql",
33
+ "sha256": "9040c607408ffd9a168bb3c30431846ddbc7a3429b2a30ba3ecafd4048ccc0c3"
34
+ },
35
+ {
36
+ "path": "scripts/migrations/003_disavow.sql",
37
+ "sha256": "ff47da734afaff5ab364dc0ae53c3db58254d0a30ca5250de8172a67f8ec2772"
38
+ },
39
+ {
40
+ "path": "scripts/migrations/004_placement_costs.sql",
41
+ "sha256": "e25732a3abd95d54320984068d9a4242ee2d0b89f6c70330a24f63bd0a3671a2"
42
+ },
43
+ {
44
+ "path": "scripts/report.py",
45
+ "sha256": "c7088c3314d0453d62e8a70f0c80f535b219b2ea127ca7d1c0731b216a9cb602"
46
+ },
47
+ {
48
+ "path": "skills/agentlinkops-assets/SKILL.md",
49
+ "sha256": "c7a16a272103c062c1a846f4a5af23a89b5c06dacd4712bbfa3b5d68c912aed0"
50
+ },
51
+ {
52
+ "path": "skills/agentlinkops-assets/agents/openai.yaml",
53
+ "sha256": "ee49f3058b6fb130d8865c4811231579d65c2e58ac13f30cd010c317c1702504"
54
+ },
55
+ {
56
+ "path": "templates/campaigns.v1.json",
57
+ "sha256": "768e1610d64b82a4e5872c301eb2a537705821b2f01e9f2265c8056f7da4a496"
58
+ }
59
+ ],
60
+ "members": [
61
+ {
62
+ "path": "SKILL.md",
63
+ "sha256": "25dba1dbed4e524408dd41794eb7fb7c56c7334e3118b6b108d363534365a0d9"
64
+ },
65
+ {
66
+ "path": "agents/openai.yaml",
67
+ "sha256": "ee49f3058b6fb130d8865c4811231579d65c2e58ac13f30cd010c317c1702504"
68
+ },
69
+ {
70
+ "path": "references/portable/references/cli.md",
71
+ "sha256": "55ad759a920ed5bb683b0354739b7a929a0d733e987c6164977ea466ff606955"
72
+ },
73
+ {
74
+ "path": "references/portable/references/disavow.md",
75
+ "sha256": "47b4b335f7695209ad0758fc19f3b23b38792032a6850277e563a9b7d80eabf1"
76
+ },
77
+ {
78
+ "path": "references/portable/references/reports.md",
79
+ "sha256": "4fc4791d03c7497f0193fb3d6b4114095aad4d551bb063c8c9e9c485f0c8ca56"
80
+ },
81
+ {
82
+ "path": "references/portable/scripts/agentlinkops.py",
83
+ "sha256": "91d541768f95e17c059396624c153ca86395bccfc565a8bf3470e2e006404e28"
84
+ },
85
+ {
86
+ "path": "references/portable/scripts/disavow.py",
87
+ "sha256": "cae36ad7d9e4aef27510975b4c15a66e5649250f6e76df7ca2bfb025a696432e"
88
+ },
89
+ {
90
+ "path": "references/portable/scripts/migrations/001_crm.sql",
91
+ "sha256": "049fbd38b05c5b8dbab00b6ebee5342b8ed5cf48f65fe6cc1bbf41330ceedf54"
92
+ },
93
+ {
94
+ "path": "references/portable/scripts/migrations/002_cloud_events.sql",
95
+ "sha256": "9040c607408ffd9a168bb3c30431846ddbc7a3429b2a30ba3ecafd4048ccc0c3"
96
+ },
97
+ {
98
+ "path": "references/portable/scripts/migrations/003_disavow.sql",
99
+ "sha256": "ff47da734afaff5ab364dc0ae53c3db58254d0a30ca5250de8172a67f8ec2772"
100
+ },
101
+ {
102
+ "path": "references/portable/scripts/migrations/004_placement_costs.sql",
103
+ "sha256": "e25732a3abd95d54320984068d9a4242ee2d0b89f6c70330a24f63bd0a3671a2"
104
+ },
105
+ {
106
+ "path": "references/portable/scripts/report.py",
107
+ "sha256": "c7088c3314d0453d62e8a70f0c80f535b219b2ea127ca7d1c0731b216a9cb602"
108
+ },
109
+ {
110
+ "path": "references/portable/templates/campaigns.v1.json",
111
+ "sha256": "768e1610d64b82a4e5872c301eb2a537705821b2f01e9f2265c8056f7da4a496"
112
+ }
113
+ ],
114
+ "edges": [
115
+ {
116
+ "from": "references/portable/references/cli.md",
117
+ "target": "references/portable/references/disavow.md",
118
+ "kind": "required-bundled"
119
+ },
120
+ {
121
+ "from": "references/portable/references/cli.md",
122
+ "target": "references/portable/references/reports.md",
123
+ "kind": "required-bundled"
124
+ },
125
+ {
126
+ "from": "references/portable/references/cli.md",
127
+ "target": "references/portable/scripts/agentlinkops.py",
128
+ "kind": "required-bundled"
129
+ },
130
+ {
131
+ "from": "references/portable/references/cli.md",
132
+ "target": "references/portable/scripts/agentlinkops.py",
133
+ "kind": "required-bundled"
134
+ },
135
+ {
136
+ "from": "references/portable/references/cli.md",
137
+ "target": "references/portable/scripts/agentlinkops.py",
138
+ "kind": "required-bundled"
139
+ },
140
+ {
141
+ "from": "references/portable/references/cli.md",
142
+ "target": "references/portable/scripts/agentlinkops.py",
143
+ "kind": "required-bundled"
144
+ },
145
+ {
146
+ "from": "references/portable/references/cli.md",
147
+ "target": "references/portable/scripts/agentlinkops.py",
148
+ "kind": "required-bundled"
149
+ },
150
+ {
151
+ "from": "references/portable/references/cli.md",
152
+ "target": "references/portable/scripts/agentlinkops.py",
153
+ "kind": "required-bundled"
154
+ },
155
+ {
156
+ "from": "references/portable/references/cli.md",
157
+ "target": "references/portable/scripts/agentlinkops.py",
158
+ "kind": "required-bundled"
159
+ },
160
+ {
161
+ "from": "references/portable/references/cli.md",
162
+ "target": "references/portable/scripts/agentlinkops.py",
163
+ "kind": "required-bundled"
164
+ },
165
+ {
166
+ "from": "references/portable/references/disavow.md",
167
+ "target": "references/portable/scripts/agentlinkops.py",
168
+ "kind": "required-bundled"
169
+ },
170
+ {
171
+ "from": "references/portable/references/disavow.md",
172
+ "target": "references/portable/scripts/agentlinkops.py",
173
+ "kind": "required-bundled"
174
+ },
175
+ {
176
+ "from": "references/portable/references/disavow.md",
177
+ "target": "references/portable/scripts/agentlinkops.py",
178
+ "kind": "required-bundled"
179
+ },
180
+ {
181
+ "from": "references/portable/references/disavow.md",
182
+ "target": "references/portable/scripts/agentlinkops.py",
183
+ "kind": "required-bundled"
184
+ },
185
+ {
186
+ "from": "references/portable/references/disavow.md",
187
+ "target": "references/portable/scripts/agentlinkops.py",
188
+ "kind": "required-bundled"
189
+ },
190
+ {
191
+ "from": "references/portable/references/reports.md",
192
+ "target": "references/portable/scripts/agentlinkops.py",
193
+ "kind": "required-bundled"
194
+ },
195
+ {
196
+ "from": "references/portable/references/reports.md",
197
+ "target": "references/portable/scripts/agentlinkops.py",
198
+ "kind": "required-bundled"
199
+ },
200
+ {
201
+ "from": "references/portable/scripts/agentlinkops.py",
202
+ "target": "references/portable/scripts/disavow.py",
203
+ "kind": "required-bundled"
204
+ },
205
+ {
206
+ "from": "references/portable/scripts/agentlinkops.py",
207
+ "target": "references/portable/scripts/migrations/001_crm.sql",
208
+ "kind": "required-bundled"
209
+ },
210
+ {
211
+ "from": "references/portable/scripts/agentlinkops.py",
212
+ "target": "references/portable/scripts/report.py",
213
+ "kind": "required-bundled"
214
+ },
215
+ {
216
+ "from": "references/portable/scripts/agentlinkops.py",
217
+ "target": "references/portable/templates/campaigns.v1.json",
218
+ "kind": "required-bundled"
219
+ },
220
+ {
221
+ "from": "SKILL.md",
222
+ "target": "../../references/recipes/internal-link-improvement.md",
223
+ "kind": "optional-selected",
224
+ "selection": "agentlinkops agent setup --recipe internal-link-improvement"
225
+ },
226
+ {
227
+ "from": "SKILL.md",
228
+ "target": "../../references/recipes/sourced-linkable-asset.md",
229
+ "kind": "optional-selected",
230
+ "selection": "agentlinkops agent setup --recipe sourced-linkable-asset"
231
+ },
232
+ {
233
+ "from": "SKILL.md",
234
+ "target": "references/portable/references/cli.md",
235
+ "kind": "required-bundled"
236
+ }
237
+ ],
238
+ "externalRuntime": [
239
+ {
240
+ "kind": "external-runtime",
241
+ "id": "agentlinkops-cli",
242
+ "commands": [
243
+ "agentlinkops",
244
+ "linktrail",
245
+ "node cli/agentlinkops.mjs"
246
+ ],
247
+ "availability": "Install separately for a standalone skill; inspect the installed version and help before using a local command. Hosted discovery does not install local CLI features."
248
+ },
249
+ {
250
+ "kind": "external-runtime",
251
+ "id": "python-standard-library",
252
+ "minimumVersion": "3.10",
253
+ "imports": [
254
+ "argparse",
255
+ "contextlib",
256
+ "csv",
257
+ "datetime",
258
+ "decimal",
259
+ "errno",
260
+ "fcntl",
261
+ "hashlib",
262
+ "html",
263
+ "importlib",
264
+ "io",
265
+ "ipaddress",
266
+ "json",
267
+ "os",
268
+ "pathlib",
269
+ "re",
270
+ "sqlite3",
271
+ "stat",
272
+ "sys",
273
+ "tempfile",
274
+ "time",
275
+ "urllib"
276
+ ]
277
+ },
278
+ {
279
+ "kind": "external-runtime",
280
+ "id": "agentlinkops-hosted-mcp",
281
+ "availability": "Hosted commands require separately connected customer access and current catalog exposure. Installing a skill alone does not establish access."
282
+ }
283
+ ],
284
+ "privateExcluded": [
285
+ "private Fleet/account files",
286
+ "customer records and credentials",
287
+ "unselected or uncleared publisher material"
288
+ ],
289
+ "coverage": "Assembler records source hashes; independent archive verification recomputes required members, supported links/imports and declared resources. Optional selections and external runtimes remain separate."
290
+ }
@@ -10,6 +10,8 @@ Preserve the project's rendering and routing conventions. Inspect nearby pages b
10
10
 
11
11
  Write plainly and specifically. Remove repetition and generic filler without deleting necessary evidence. Add internal links only where the destination answers the reader's next relevant question; inspect the actual routes before linking. Check for an existing competing page before creating a new URL.
12
12
 
13
- Use the site's existing validation commands appropriate to the change. Record the final target URL, reader benefit and evidence in the customer's chosen files, CRM or other record system. The bundled local CRM is optional; use [its contract](../../references/cli.md) only when the customer chooses that store. A completed local edit does not establish that the page is deployed or that a publisher accepted it.
13
+ Use the site's existing validation commands appropriate to the change. Record the final target URL, reader benefit and evidence in the customer's chosen files, CRM or other record system. The bundled local CRM is optional; use [its contract](references/portable/references/cli.md) only when the customer chooses that store. A completed local edit does not establish that the page is deployed or that a publisher accepted it.
14
14
 
15
15
  Recipes are optional. Choose `agentlinkops agent setup --recipe sourced-linkable-asset` before reading `../../references/recipes/sourced-linkable-asset.md` for draft review receipts and publication state. Select `--recipe site-context-brief` separately before reading that recipe if the audience or evidence needs clarification. Your own brief and editorial process can serve the same task.
16
+
17
+ For an optional internal-link plan, select `agentlinkops agent setup --recipe internal-link-improvement` before reading `../../references/recipes/internal-link-improvement.md`. It keeps source evidence, semantic choices, site edits, publication claims and independent verification separate. Supplied pages remain sufficient for a useful plan without hosted access.
@@ -1,5 +1,5 @@
1
1
  interface:
2
2
  display_name: AgentLinkOps Assets
3
- short_description: Improve a code-built site's resource, guide or research page for a specific backlink campaign, with sourced claims and u
3
+ short_description: "Improve sourced site pages for a specific backlink campaign"
4
4
  policy:
5
5
  allow_implicit_invocation: true