agentlinkops 0.6.10 → 0.6.11
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +7 -0
- package/README.md +4 -4
- package/cli/client.js +1 -1
- package/cli/import.js +4 -1
- package/cli/main.js +8 -7
- package/cli/mcp-client.js +2 -2
- package/package.json +1 -1
- package/skills/agentlinkops-connect/references/agentlinkops.md +1 -1
- package/skills/agentlinkops-crm/SKILL.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentlinkops",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.11",
|
|
4
4
|
"description": "Connect an agent to AgentLinkOps and run backlink work with it: the connect skill (views, the three discovery verbs, evidence rules), local ledger and campaign skills, a portable CRM, the source-cited content pipeline, user-managed disavow lists, HTML reports and monitoring-event sync.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AgentLinkOps"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentlinkops",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.11",
|
|
4
4
|
"description": "Connect an agent to AgentLinkOps and run backlink work with it: the connect skill (views, the three discovery verbs, evidence rules), local ledger and campaign skills, a portable CRM, the source-cited content pipeline, user-managed disavow lists, HTML reports and monitoring-event sync.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AgentLinkOps"
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to the `agentlinkops` package are recorded here. The version follows the
|
|
4
4
|
plugin manifests in `.claude-plugin/` and `.codex-plugin/`.
|
|
5
5
|
|
|
6
|
+
## 0.6.11 (2026-10-06)
|
|
7
|
+
|
|
8
|
+
- Keep `check --json` stdout limited to observation rows. Send empty-ledger, not-due and filter notices to stderr.
|
|
9
|
+
- Reject malformed ledger rows with line numbers and exit with status 2 before fetching or updating customer records.
|
|
10
|
+
- Apply `--fail-on-unknown` to JSON and human output. Unknown observations remain nonfailing by default.
|
|
11
|
+
- Detect duplicate placements across import batches and retain their original file line numbers.
|
|
12
|
+
|
|
6
13
|
## 0.6.10 (2026-10-06)
|
|
7
14
|
|
|
8
15
|
Inspect the installed version's help before using selectors; older published versions
|
package/README.md
CHANGED
|
@@ -98,10 +98,10 @@ agentlinkops status
|
|
|
98
98
|
the source page and appends an observation to the mirror. `status` names every entry whose
|
|
99
99
|
observations disagree with its intent and proposes the edit; applying it is a commit you make.
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
Ledger checks return `0` when no expected placement is conclusively absent and `1` when
|
|
102
|
+
an expected placement is observed absent with complete evidence. Unknown observations do
|
|
103
|
+
not fail a run by default. Pass `--fail-on-unknown` to return `1` for an unknown result
|
|
104
|
+
in text or JSON output. Usage, configuration and malformed-ledger errors return `2`.
|
|
105
105
|
|
|
106
106
|
`agentlinkops doctor` verifies the ledger, the verifier self-test, cloud reachability and the
|
|
107
107
|
token, and prints a fix line for anything that fails.
|
package/cli/client.js
CHANGED
|
@@ -5,7 +5,7 @@ export {CloudError} from './cloud-error.js';
|
|
|
5
5
|
// A small HTTP client for the cloud. Scoped keys only; no human session ever reaches here.
|
|
6
6
|
// DP-0036-T13: the CLI names itself so the usage counters can tell it from other REST callers.
|
|
7
7
|
// The version follows the plugin manifests; bump it with them.
|
|
8
|
-
export const CLI_VERSION = '0.6.
|
|
8
|
+
export const CLI_VERSION = '0.6.11';
|
|
9
9
|
export const CLI_USER_AGENT = `agentlinkops-cli/${CLI_VERSION}`;
|
|
10
10
|
const MAX_ATTEMPTS = 3;
|
|
11
11
|
const MAX_RETRY_WAIT_MS = 5_000;
|
package/cli/import.js
CHANGED
|
@@ -74,11 +74,14 @@ export async function readImport(path, {
|
|
|
74
74
|
// chunks, so a placement repeated in two different parts of one file is still one candidate.
|
|
75
75
|
const prepared = { accepted: [], rejected: [], duplicates: [] };
|
|
76
76
|
const seen = new Map();
|
|
77
|
+
// Candidate identity includes the run. These bounded slices describe one preview, so keep
|
|
78
|
+
// its first-slice identity throughout the file or a repeated placement gets a new ID.
|
|
79
|
+
const previewRunId = `${runId}_0`;
|
|
77
80
|
const chunks = [];
|
|
78
81
|
for (let index = 0; index < rows.length; index += DISCOVERY_LIMITS.rows) chunks.push(index);
|
|
79
82
|
for (const offset of chunks) {
|
|
80
83
|
const part = await prepareImport({
|
|
81
|
-
runId:
|
|
84
|
+
runId: previewRunId, workspaceId, projectId, supplier,
|
|
82
85
|
rows: rows.slice(offset, offset + DISCOVERY_LIMITS.rows), target: targetUrl, scope,
|
|
83
86
|
taskId: 'import_preview', retrievedAt: now, generatedAt: supplierGeneratedAt,
|
|
84
87
|
seen, rowOffset: offset,
|
package/cli/main.js
CHANGED
|
@@ -115,8 +115,9 @@ const USAGE = `agentlinkops — a backlink ledger that lives in your repository
|
|
|
115
115
|
Suppliers: ${SUPPLIER_NAMES.join(', ')}
|
|
116
116
|
A preset is a convenience over --map, never a requirement.
|
|
117
117
|
|
|
118
|
-
Exit codes: 0
|
|
119
|
-
evidence · 2 usage, configuration or ledger error.
|
|
118
|
+
Exit codes: 0 no expected link conclusively absent · 1 an expected link observed absent with complete
|
|
119
|
+
evidence · 2 usage, configuration or ledger error. Unknown is nonfailing by default;
|
|
120
|
+
--fail-on-unknown returns 1 when any observation is unknown.
|
|
120
121
|
|
|
121
122
|
Names: \`linktrail\` still runs this CLI, LINKTRAIL_* variables are still read, and an existing
|
|
122
123
|
.linktrail/ directory is still used, each with a one-line notice, until the DP-0029 cutover.`;
|
|
@@ -586,10 +587,11 @@ export async function main(argv = process.argv.slice(2), { cwd = process.cwd(),
|
|
|
586
587
|
}
|
|
587
588
|
|
|
588
589
|
if (command === 'check') {
|
|
590
|
+
if (ledger.problems.length) { reportProblems(ledger.problems, 'ledger line(s)', err); return 2; }
|
|
589
591
|
const state = await readState(config.paths.state);
|
|
590
592
|
const selected = selectEntries(ledger.entries, { filter: args.filter === true ? null : args.filter });
|
|
591
593
|
const entries = args.all ? selected : dueEntries(selected, lastCheckedMap(state));
|
|
592
|
-
if (!entries.length) { out(`nothing due (${plural(selected.length, 'entry', 'entries')} in scope; pass --all to recheck)`); return 0; }
|
|
594
|
+
if (!entries.length) { (args.json ? err : out)(`nothing due (${plural(selected.length, 'entry', 'entries')} in scope; pass --all to recheck)`); return 0; }
|
|
593
595
|
if (!args.json) err(`checking ${plural(entries.length, 'entry', 'entries')}…`);
|
|
594
596
|
const rows = await runCheck(entries, {
|
|
595
597
|
concurrency: Number(args.concurrency ?? config.defaults.concurrency ?? DEFAULTS.concurrency),
|
|
@@ -603,8 +605,8 @@ export async function main(argv = process.argv.slice(2), { cwd = process.cwd(),
|
|
|
603
605
|
await appendObservations(config.paths.observations, changed);
|
|
604
606
|
await writeState(config.paths.state, applyRun(state, rows));
|
|
605
607
|
const summary = summarize(entries, rows);
|
|
606
|
-
|
|
607
|
-
|
|
608
|
+
const exitCode = args['fail-on-unknown'] && summary.counts.unknown ? 1 : summary.exitCode;
|
|
609
|
+
if (args.json) { out(rows.map(row => JSON.stringify(row)).join('\n')); return exitCode; }
|
|
608
610
|
for (const { entry, row } of summary.appeared) out(`APPEARED ${entry.id} ${entry.source} (${row.occurrences} occurrence(s))`);
|
|
609
611
|
for (const { entry, row } of summary.failures) out(`ABSENT ${entry.id} ${entry.source} [${row.reason}]`);
|
|
610
612
|
out(`\n${JSON.stringify(summary.counts)}`);
|
|
@@ -612,8 +614,7 @@ export async function main(argv = process.argv.slice(2), { cwd = process.cwd(),
|
|
|
612
614
|
if (summary.counts.unknown) {
|
|
613
615
|
out(`${plural(summary.counts.unknown, 'page')} could not be concluded. An unknown is not a lost link; run \`agentlinkops status\` for the reasons.`);
|
|
614
616
|
}
|
|
615
|
-
|
|
616
|
-
return summary.exitCode;
|
|
617
|
+
return exitCode;
|
|
617
618
|
}
|
|
618
619
|
|
|
619
620
|
err(`unknown command: ${command}\n\n${USAGE}`);
|
package/cli/mcp-client.js
CHANGED
|
@@ -62,7 +62,7 @@ function retryDelay(error, attempt, now) {
|
|
|
62
62
|
|
|
63
63
|
async function sdkClient({url, token, workspaceId, fetchImpl}) {
|
|
64
64
|
const {Client, StreamableHTTPClientTransport} = await import('@modelcontextprotocol/client');
|
|
65
|
-
const client = new Client({name: 'agentlinkops-cli', version: '0.6.
|
|
65
|
+
const client = new Client({name: 'agentlinkops-cli', version: '0.6.11'});
|
|
66
66
|
const destination = new URL(url);
|
|
67
67
|
const transport = new StreamableHTTPClientTransport(destination, {
|
|
68
68
|
authProvider: {token: async () => token},
|
|
@@ -71,7 +71,7 @@ async function sdkClient({url, token, workspaceId, fetchImpl}) {
|
|
|
71
71
|
if (target.href !== destination.href) fail('OAUTH_TOKEN_DESTINATION_MISMATCH');
|
|
72
72
|
const headers = new Headers(init.headers ?? (input instanceof Request ? input.headers : undefined));
|
|
73
73
|
if (workspaceId) headers.set('X-Workspace-ID', workspaceId);
|
|
74
|
-
headers.set('User-Agent', 'agentlinkops-cli/0.6.
|
|
74
|
+
headers.set('User-Agent', 'agentlinkops-cli/0.6.11');
|
|
75
75
|
const response = await fetchImpl(input, {...init, headers, redirect: 'error', signal: AbortSignal.timeout(30000)});
|
|
76
76
|
if (response.redirected || response.status >= 300 && response.status < 400
|
|
77
77
|
|| response.url && response.url !== destination.href) fail('OAUTH_TOKEN_DESTINATION_MISMATCH');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentlinkops",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.11",
|
|
4
4
|
"description": "Backlink checks with dated evidence and portable results, optional repository ledgers, supplier-export imports and sync to AgentLinkOps.",
|
|
5
5
|
"author": "AgentLinkOps (https://agentlinkops.com)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -9,7 +9,7 @@ records. This page is the complete agent reference: the same text prints from
|
|
|
9
9
|
full once per session, then use `describe` (or `exec describe` on MCP) for any command's exact schema.
|
|
10
10
|
|
|
11
11
|
<!-- generated:skill-version begin (npm run generate:tools) -->
|
|
12
|
-
Pack version 0.6.
|
|
12
|
+
Pack version 0.6.11. 139 commands in 15 toolsets.
|
|
13
13
|
<!-- generated:skill-version end -->
|
|
14
14
|
|
|
15
15
|
## Install and connect (once per machine)
|
|
@@ -6,7 +6,7 @@ allowed-tools: Read Bash(python3 ../../scripts/agentlinkops.py *) Bash(python3 .
|
|
|
6
6
|
|
|
7
7
|
**For the optional bundled CLI, the local surface is the ledger file.** `.agentlinkops/links.jsonl` in the user's repository (or a `.linktrail/` directory from an earlier install, read until `agentlinkops migrate` renames it) declares the links they expect, want and have earned, and `agentlinkops check` runs the exact cloud verifier against it without an account. Run the CLI as `node cli/agentlinkops.mjs` from the repository or plugin-package root (`cli/linktrail.mjs` still works and prints a one-line notice); the packaged plugin ships the CLI, its pinned verifier modules and their pinned runtime dependencies inside the package, so the installed package needs no npm install; checking a publisher still requires a read-only network fetch. It needs Node 22 or newer (`adopt` reads SQLite databases through `node:sqlite`); the Python helper below needs Python 3.10+. This CRM is one optional adapter beside CSV and JSONL: it is available, tested and unchanged, and nothing requires it. When a user already keeps links here, `agentlinkops adopt <db>` reads it into ledger entries — read-only, adding no schema — and previews unless `--write` is given. Do not propose the CRM as the place a user should start keeping links; propose it when they want contacts and outreach activity beside them, or when they already have one.
|
|
8
8
|
|
|
9
|
-
To record a link in the ledger: `agentlinkops add --source URL --target URL --intent expected [--anchor TEXT] [--ref ID] [--note TEXT]` (`--intent wanted` for a link not yet earned; `agentlinkops init` first in a repository without `.agentlinkops/`). `agentlinkops check` then verifies every expected link and
|
|
9
|
+
To record a link in the ledger: `agentlinkops add --source URL --target URL --intent expected [--anchor TEXT] [--ref ID] [--note TEXT]` (`--intent wanted` for a link not yet earned; `agentlinkops init` first in a repository without `.agentlinkops/`). `agentlinkops check` then verifies every expected link and returns 0 when no expected placement is conclusively absent, 1 when one is observed absent with complete evidence, 2 on a usage or ledger error. Unknown is nonfailing by default; `--fail-on-unknown` returns 1 for an unknown result in text or JSON output.
|
|
10
10
|
|
|
11
11
|
Use the deterministic Python helper at `../../scripts/agentlinkops.py`, resolved relative to this skill's directory. It requires Python 3.10+ and only its standard library. Run `--help` for the command surface. Keep the database outside the plugin installation directory; updates can replace that directory.
|
|
12
12
|
|