@agirails/sdk 2.7.0 → 3.1.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 +1 -1
- package/bin/agirails +10 -0
- package/dist/ACTPClient.d.ts +15 -4
- package/dist/ACTPClient.d.ts.map +1 -1
- package/dist/ACTPClient.js +20 -8
- package/dist/ACTPClient.js.map +1 -1
- package/dist/abi/ACTPKernel.json +87 -6
- package/dist/adapters/BaseAdapter.d.ts +3 -3
- package/dist/adapters/BaseAdapter.js +3 -3
- package/dist/adapters/BasicAdapter.d.ts +1 -1
- package/dist/adapters/BasicAdapter.js +2 -2
- package/dist/adapters/BasicAdapter.js.map +1 -1
- package/dist/adapters/StandardAdapter.d.ts +30 -8
- package/dist/adapters/StandardAdapter.d.ts.map +1 -1
- package/dist/adapters/StandardAdapter.js +34 -9
- package/dist/adapters/StandardAdapter.js.map +1 -1
- package/dist/api/agirailsApp.d.ts +197 -0
- package/dist/api/agirailsApp.d.ts.map +1 -0
- package/dist/api/agirailsApp.js +175 -0
- package/dist/api/agirailsApp.js.map +1 -0
- package/dist/cli/agirails.d.ts +10 -0
- package/dist/cli/agirails.d.ts.map +1 -0
- package/dist/cli/agirails.js +187 -0
- package/dist/cli/agirails.js.map +1 -0
- package/dist/cli/commands/autopublish.d.ts +13 -0
- package/dist/cli/commands/autopublish.d.ts.map +1 -0
- package/dist/cli/commands/autopublish.js +156 -0
- package/dist/cli/commands/autopublish.js.map +1 -0
- package/dist/cli/commands/batch.js +1 -1
- package/dist/cli/commands/claim-code.d.ts +11 -0
- package/dist/cli/commands/claim-code.d.ts.map +1 -0
- package/dist/cli/commands/claim-code.js +160 -0
- package/dist/cli/commands/claim-code.js.map +1 -0
- package/dist/cli/commands/claim.d.ts +17 -0
- package/dist/cli/commands/claim.d.ts.map +1 -0
- package/dist/cli/commands/claim.js +104 -0
- package/dist/cli/commands/claim.js.map +1 -0
- package/dist/cli/commands/config.js +1 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/find.d.ts +23 -0
- package/dist/cli/commands/find.d.ts.map +1 -0
- package/dist/cli/commands/find.js +230 -0
- package/dist/cli/commands/find.js.map +1 -0
- package/dist/cli/commands/health.d.ts +16 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +287 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +42 -13
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/negotiate.d.ts +11 -0
- package/dist/cli/commands/negotiate.d.ts.map +1 -0
- package/dist/cli/commands/negotiate.js +192 -0
- package/dist/cli/commands/negotiate.js.map +1 -0
- package/dist/cli/commands/publish.d.ts.map +1 -1
- package/dist/cli/commands/publish.js +313 -18
- package/dist/cli/commands/publish.js.map +1 -1
- package/dist/cli/commands/pull.d.ts +7 -3
- package/dist/cli/commands/pull.d.ts.map +1 -1
- package/dist/cli/commands/pull.js +105 -13
- package/dist/cli/commands/pull.js.map +1 -1
- package/dist/cli/commands/receipt.d.ts +31 -0
- package/dist/cli/commands/receipt.d.ts.map +1 -0
- package/dist/cli/commands/receipt.js +92 -0
- package/dist/cli/commands/receipt.js.map +1 -0
- package/dist/cli/commands/test.d.ts +15 -0
- package/dist/cli/commands/test.d.ts.map +1 -0
- package/dist/cli/commands/test.js +176 -0
- package/dist/cli/commands/test.js.map +1 -0
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/testjobs/index.d.ts +18 -0
- package/dist/cli/testjobs/index.d.ts.map +1 -0
- package/dist/cli/testjobs/index.js +45 -0
- package/dist/cli/testjobs/index.js.map +1 -0
- package/dist/cli/testjobs/templates/automation.d.ts +3 -0
- package/dist/cli/testjobs/templates/automation.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/automation.js +32 -0
- package/dist/cli/testjobs/templates/automation.js.map +1 -0
- package/dist/cli/testjobs/templates/code-review.d.ts +3 -0
- package/dist/cli/testjobs/templates/code-review.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/code-review.js +27 -0
- package/dist/cli/testjobs/templates/code-review.js.map +1 -0
- package/dist/cli/testjobs/templates/content-writing.d.ts +3 -0
- package/dist/cli/testjobs/templates/content-writing.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/content-writing.js +20 -0
- package/dist/cli/testjobs/templates/content-writing.js.map +1 -0
- package/dist/cli/testjobs/templates/data-analysis.d.ts +3 -0
- package/dist/cli/testjobs/templates/data-analysis.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/data-analysis.js +34 -0
- package/dist/cli/testjobs/templates/data-analysis.js.map +1 -0
- package/dist/cli/testjobs/templates/generic.d.ts +3 -0
- package/dist/cli/testjobs/templates/generic.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/generic.js +17 -0
- package/dist/cli/testjobs/templates/generic.js.map +1 -0
- package/dist/cli/testjobs/templates/security-audit.d.ts +3 -0
- package/dist/cli/testjobs/templates/security-audit.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/security-audit.js +30 -0
- package/dist/cli/testjobs/templates/security-audit.js.map +1 -0
- package/dist/cli/testjobs/templates/testing.d.ts +3 -0
- package/dist/cli/testjobs/templates/testing.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/testing.js +29 -0
- package/dist/cli/testjobs/templates/testing.js.map +1 -0
- package/dist/cli/testjobs/templates/translation.d.ts +3 -0
- package/dist/cli/testjobs/templates/translation.d.ts.map +1 -0
- package/dist/cli/testjobs/templates/translation.js +16 -0
- package/dist/cli/testjobs/templates/translation.js.map +1 -0
- package/dist/cli/testjobs/types.d.ts +16 -0
- package/dist/cli/testjobs/types.d.ts.map +1 -0
- package/dist/cli/testjobs/types.js +8 -0
- package/dist/cli/testjobs/types.js.map +1 -0
- package/dist/cli/utils/client.js +1 -1
- package/dist/cli/utils/client.js.map +1 -1
- package/dist/cli/utils/config.d.ts +12 -0
- package/dist/cli/utils/config.d.ts.map +1 -1
- package/dist/cli/utils/config.js +29 -2
- package/dist/cli/utils/config.js.map +1 -1
- package/dist/config/agirailsmd.d.ts +1 -1
- package/dist/config/agirailsmd.d.ts.map +1 -1
- package/dist/config/agirailsmd.js +3 -0
- package/dist/config/agirailsmd.js.map +1 -1
- package/dist/config/agirailsmdV4.d.ts +82 -0
- package/dist/config/agirailsmdV4.d.ts.map +1 -0
- package/dist/config/agirailsmdV4.js +260 -0
- package/dist/config/agirailsmdV4.js.map +1 -0
- package/dist/config/defaults.d.ts +50 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +77 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/networks.d.ts +1 -0
- package/dist/config/networks.d.ts.map +1 -1
- package/dist/config/networks.js +16 -13
- package/dist/config/networks.js.map +1 -1
- package/dist/config/publishPipeline.d.ts.map +1 -1
- package/dist/config/publishPipeline.js +4 -0
- package/dist/config/publishPipeline.js.map +1 -1
- package/dist/config/slugUtils.d.ts +28 -0
- package/dist/config/slugUtils.d.ts.map +1 -0
- package/dist/config/slugUtils.js +51 -0
- package/dist/config/slugUtils.js.map +1 -0
- package/dist/level0/ServiceDirectory.d.ts +6 -6
- package/dist/level0/ServiceDirectory.js +11 -11
- package/dist/level0/ServiceDirectory.js.map +1 -1
- package/dist/level1/Agent.d.ts +10 -10
- package/dist/level1/Agent.d.ts.map +1 -1
- package/dist/level1/Agent.js +45 -29
- package/dist/level1/Agent.js.map +1 -1
- package/dist/level1/pricing/PriceCalculator.js +2 -2
- package/dist/level1/pricing/PriceCalculator.js.map +1 -1
- package/dist/negotiation/BuyerOrchestrator.d.ts +108 -0
- package/dist/negotiation/BuyerOrchestrator.d.ts.map +1 -0
- package/dist/negotiation/BuyerOrchestrator.js +377 -0
- package/dist/negotiation/BuyerOrchestrator.js.map +1 -0
- package/dist/negotiation/DecisionEngine.d.ts +44 -0
- package/dist/negotiation/DecisionEngine.d.ts.map +1 -0
- package/dist/negotiation/DecisionEngine.js +116 -0
- package/dist/negotiation/DecisionEngine.js.map +1 -0
- package/dist/negotiation/PolicyEngine.d.ts +126 -0
- package/dist/negotiation/PolicyEngine.d.ts.map +1 -0
- package/dist/negotiation/PolicyEngine.js +265 -0
- package/dist/negotiation/PolicyEngine.js.map +1 -0
- package/dist/negotiation/SessionStore.d.ts +57 -0
- package/dist/negotiation/SessionStore.d.ts.map +1 -0
- package/dist/negotiation/SessionStore.js +179 -0
- package/dist/negotiation/SessionStore.js.map +1 -0
- package/dist/negotiation/index.d.ts +9 -0
- package/dist/negotiation/index.d.ts.map +1 -0
- package/dist/negotiation/index.js +12 -0
- package/dist/negotiation/index.js.map +1 -0
- package/dist/protocol/ACTPKernel.d.ts +32 -4
- package/dist/protocol/ACTPKernel.d.ts.map +1 -1
- package/dist/protocol/ACTPKernel.js +70 -16
- package/dist/protocol/ACTPKernel.js.map +1 -1
- package/dist/protocol/AgentRegistry.js +2 -2
- package/dist/protocol/AgentRegistry.js.map +1 -1
- package/dist/protocol/DIDResolver.js +2 -2
- package/dist/protocol/DIDResolver.js.map +1 -1
- package/dist/protocol/EASHelper.d.ts +2 -2
- package/dist/protocol/EASHelper.js +5 -5
- package/dist/protocol/EASHelper.js.map +1 -1
- package/dist/protocol/EscrowVault.d.ts +2 -2
- package/dist/protocol/EscrowVault.js +4 -4
- package/dist/protocol/EscrowVault.js.map +1 -1
- package/dist/protocol/EventMonitor.d.ts +4 -4
- package/dist/protocol/EventMonitor.js +5 -5
- package/dist/protocol/EventMonitor.js.map +1 -1
- package/dist/protocol/MessageSigner.d.ts +5 -5
- package/dist/protocol/MessageSigner.js +8 -8
- package/dist/protocol/MessageSigner.js.map +1 -1
- package/dist/protocol/ProofGenerator.d.ts +4 -4
- package/dist/protocol/ProofGenerator.js +6 -6
- package/dist/protocol/ProofGenerator.js.map +1 -1
- package/dist/runtime/BlockchainRuntime.d.ts +36 -14
- package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
- package/dist/runtime/BlockchainRuntime.js +78 -45
- package/dist/runtime/BlockchainRuntime.js.map +1 -1
- package/dist/runtime/IACTPRuntime.d.ts +12 -1
- package/dist/runtime/IACTPRuntime.d.ts.map +1 -1
- package/dist/runtime/MockRuntime.d.ts +29 -9
- package/dist/runtime/MockRuntime.d.ts.map +1 -1
- package/dist/runtime/MockRuntime.js +88 -24
- package/dist/runtime/MockRuntime.js.map +1 -1
- package/dist/runtime/MockStateManager.js +2 -2
- package/dist/runtime/MockStateManager.js.map +1 -1
- package/dist/runtime/types/MockState.d.ts +1 -1
- package/dist/settle/SettleOnInteract.d.ts +32 -0
- package/dist/settle/SettleOnInteract.d.ts.map +1 -0
- package/dist/settle/SettleOnInteract.js +74 -0
- package/dist/settle/SettleOnInteract.js.map +1 -0
- package/dist/types/erc8004.d.ts +2 -2
- package/dist/types/erc8004.d.ts.map +1 -1
- package/dist/types/erc8004.js +4 -1
- package/dist/types/erc8004.js.map +1 -1
- package/dist/types/state.d.ts +1 -1
- package/dist/types/state.js +1 -1
- package/dist/types/transaction.d.ts +4 -0
- package/dist/types/transaction.d.ts.map +1 -1
- package/dist/utils/ErrorRecoveryGuide.d.ts +1 -1
- package/dist/utils/ErrorRecoveryGuide.js +1 -1
- package/dist/utils/Helpers.d.ts +6 -6
- package/dist/utils/Helpers.js +7 -7
- package/dist/utils/Helpers.js.map +1 -1
- package/dist/utils/IPFSClient.d.ts +7 -7
- package/dist/utils/IPFSClient.js +9 -9
- package/dist/utils/IPFSClient.js.map +1 -1
- package/dist/utils/Logger.d.ts +4 -4
- package/dist/utils/Logger.js +8 -8
- package/dist/utils/Logger.js.map +1 -1
- package/dist/utils/NonceManager.d.ts +9 -9
- package/dist/utils/NonceManager.js +19 -19
- package/dist/utils/NonceManager.js.map +1 -1
- package/dist/utils/RateLimiter.d.ts +10 -10
- package/dist/utils/RateLimiter.d.ts.map +1 -1
- package/dist/utils/RateLimiter.js +22 -22
- package/dist/utils/RateLimiter.js.map +1 -1
- package/dist/utils/ReceivedNonceTracker.d.ts +10 -10
- package/dist/utils/ReceivedNonceTracker.js +20 -20
- package/dist/utils/ReceivedNonceTracker.js.map +1 -1
- package/dist/utils/SDKLifecycle.d.ts +3 -3
- package/dist/utils/SDKLifecycle.js +7 -7
- package/dist/utils/SDKLifecycle.js.map +1 -1
- package/dist/utils/SecureNonce.d.ts +1 -1
- package/dist/utils/SecureNonce.js +1 -1
- package/dist/utils/Semaphore.d.ts +2 -2
- package/dist/utils/Semaphore.js +2 -2
- package/dist/utils/UsedAttestationTracker.d.ts +13 -13
- package/dist/utils/UsedAttestationTracker.js +20 -20
- package/dist/utils/UsedAttestationTracker.js.map +1 -1
- package/dist/utils/security.d.ts +3 -3
- package/dist/utils/security.js +4 -4
- package/dist/utils/security.js.map +1 -1
- package/dist/utils/validation.d.ts +4 -4
- package/dist/utils/validation.js +9 -9
- package/dist/utils/validation.js.map +1 -1
- package/dist/wallet/AutoWalletProvider.d.ts.map +1 -1
- package/dist/wallet/AutoWalletProvider.js +2 -1
- package/dist/wallet/AutoWalletProvider.js.map +1 -1
- package/dist/wallet/IWalletProvider.d.ts +2 -0
- package/dist/wallet/IWalletProvider.d.ts.map +1 -1
- package/dist/wallet/aa/TransactionBatcher.d.ts +22 -2
- package/dist/wallet/aa/TransactionBatcher.d.ts.map +1 -1
- package/dist/wallet/aa/TransactionBatcher.js +51 -9
- package/dist/wallet/aa/TransactionBatcher.js.map +1 -1
- package/package.json +6 -12
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Negotiate Command — Autonomous buyer-side negotiation
|
|
4
|
+
*
|
|
5
|
+
* Discovers agents, scores them, validates against buyer policy,
|
|
6
|
+
* and optionally executes the full negotiation flow.
|
|
7
|
+
*
|
|
8
|
+
* @module cli/commands/negotiate
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
27
|
+
if (mod && mod.__esModule) return mod;
|
|
28
|
+
var result = {};
|
|
29
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
30
|
+
__setModuleDefault(result, mod);
|
|
31
|
+
return result;
|
|
32
|
+
};
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.createNegotiateCommand = void 0;
|
|
35
|
+
const commander_1 = require("commander");
|
|
36
|
+
const fs_1 = require("fs");
|
|
37
|
+
const output_1 = require("../utils/output");
|
|
38
|
+
const client_1 = require("../utils/client");
|
|
39
|
+
const BuyerOrchestrator_1 = require("../../negotiation/BuyerOrchestrator");
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Command Definition
|
|
42
|
+
// ============================================================================
|
|
43
|
+
function createNegotiateCommand() {
|
|
44
|
+
const cmd = new commander_1.Command('negotiate')
|
|
45
|
+
.description('Run autonomous buyer-side negotiation')
|
|
46
|
+
.requiredOption('--policy <path>', 'Path to buyer policy JSON file')
|
|
47
|
+
.option('--dry-run', 'Score candidates without creating transactions')
|
|
48
|
+
.option('--poll-interval <ms>', 'Poll interval for quote state (ms)', '3000')
|
|
49
|
+
.option('--json', 'Output as JSON')
|
|
50
|
+
.option('-q, --quiet', 'Minimal output')
|
|
51
|
+
.action(async (options) => {
|
|
52
|
+
const output = new output_1.Output(options.json ? 'json' : options.quiet ? 'quiet' : 'human');
|
|
53
|
+
try {
|
|
54
|
+
await runNegotiate(options, output);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
const structuredError = (0, client_1.mapError)(error);
|
|
58
|
+
output.errorResult({
|
|
59
|
+
code: structuredError.code,
|
|
60
|
+
message: structuredError.message,
|
|
61
|
+
details: structuredError.details,
|
|
62
|
+
});
|
|
63
|
+
process.exit(output_1.ExitCode.ERROR);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return cmd;
|
|
67
|
+
}
|
|
68
|
+
exports.createNegotiateCommand = createNegotiateCommand;
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Implementation
|
|
71
|
+
// ============================================================================
|
|
72
|
+
async function runNegotiate(options, output) {
|
|
73
|
+
// Load policy
|
|
74
|
+
let policy;
|
|
75
|
+
try {
|
|
76
|
+
const raw = (0, fs_1.readFileSync)(options.policy, 'utf8');
|
|
77
|
+
policy = JSON.parse(raw);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
output.errorResult({
|
|
81
|
+
code: 'INVALID_POLICY',
|
|
82
|
+
message: `Failed to load policy: ${err instanceof Error ? err.message : String(err)}`,
|
|
83
|
+
});
|
|
84
|
+
process.exit(output_1.ExitCode.ERROR);
|
|
85
|
+
}
|
|
86
|
+
// Validate required policy fields (structure + types + ranges)
|
|
87
|
+
const errors = [];
|
|
88
|
+
if (!policy.task || typeof policy.task !== 'string') {
|
|
89
|
+
errors.push('task must be a non-empty string');
|
|
90
|
+
}
|
|
91
|
+
if (typeof policy.constraints?.max_unit_price?.amount !== 'number' || !Number.isFinite(policy.constraints.max_unit_price.amount) || policy.constraints.max_unit_price.amount <= 0) {
|
|
92
|
+
errors.push('constraints.max_unit_price.amount must be a finite positive number');
|
|
93
|
+
}
|
|
94
|
+
if (typeof policy.constraints?.max_daily_spend?.amount !== 'number' || !Number.isFinite(policy.constraints.max_daily_spend.amount) || policy.constraints.max_daily_spend.amount <= 0) {
|
|
95
|
+
errors.push('constraints.max_daily_spend.amount must be a finite positive number');
|
|
96
|
+
}
|
|
97
|
+
if (typeof policy.negotiation?.rounds_max !== 'number' || !Number.isInteger(policy.negotiation.rounds_max) || policy.negotiation.rounds_max < 1) {
|
|
98
|
+
errors.push('negotiation.rounds_max must be a positive integer');
|
|
99
|
+
}
|
|
100
|
+
if (!policy.negotiation?.quote_ttl || typeof policy.negotiation.quote_ttl !== 'string') {
|
|
101
|
+
errors.push('negotiation.quote_ttl must be a string (e.g. "15m", "2h")');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Validate TTL format early (before orchestrator)
|
|
105
|
+
try {
|
|
106
|
+
const { PolicyEngine } = await Promise.resolve().then(() => __importStar(require('../../negotiation/PolicyEngine')));
|
|
107
|
+
PolicyEngine.parseTtl(policy.negotiation.quote_ttl);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
errors.push(`negotiation.quote_ttl has invalid format: "${policy.negotiation.quote_ttl}" (expected e.g. "15m", "2h", "30s")`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!Array.isArray(policy.selection?.prioritize) || policy.selection.prioritize.length === 0) {
|
|
114
|
+
errors.push('selection.prioritize must be a non-empty array');
|
|
115
|
+
}
|
|
116
|
+
if (errors.length > 0) {
|
|
117
|
+
output.errorResult({
|
|
118
|
+
code: 'INVALID_POLICY',
|
|
119
|
+
message: `Invalid policy: ${errors.join('; ')}`,
|
|
120
|
+
});
|
|
121
|
+
process.exit(output_1.ExitCode.ERROR);
|
|
122
|
+
}
|
|
123
|
+
const rawPollInterval = options.pollInterval ?? '3000';
|
|
124
|
+
const pollInterval = /^\d+$/.test(rawPollInterval) ? Number(rawPollInterval) : NaN;
|
|
125
|
+
if (isNaN(pollInterval) || pollInterval < 100) {
|
|
126
|
+
output.errorResult({
|
|
127
|
+
code: 'INVALID_OPTION',
|
|
128
|
+
message: `--poll-interval must be a whole number >= 100ms, got: "${rawPollInterval}"`,
|
|
129
|
+
});
|
|
130
|
+
process.exit(output_1.ExitCode.ERROR);
|
|
131
|
+
}
|
|
132
|
+
const spinner = output.spinner(options.dryRun ? 'Scoring candidates...' : 'Negotiating...');
|
|
133
|
+
const client = await (0, client_1.createClient)();
|
|
134
|
+
const orchestrator = new BuyerOrchestrator_1.BuyerOrchestrator(policy, client.runtime, client.getAddress());
|
|
135
|
+
// Progress callback for human mode
|
|
136
|
+
const onProgress = (event) => {
|
|
137
|
+
if (options.json || options.quiet)
|
|
138
|
+
return;
|
|
139
|
+
switch (event.type) {
|
|
140
|
+
case 'discovery':
|
|
141
|
+
spinner.stop(true);
|
|
142
|
+
output.print(`Found ${event.candidates} candidates`);
|
|
143
|
+
break;
|
|
144
|
+
case 'scoring':
|
|
145
|
+
output.print(`Ranked ${event.ranked} candidates`);
|
|
146
|
+
break;
|
|
147
|
+
case 'round_start':
|
|
148
|
+
output.print(`Round ${event.round}: trying ${output_1.fmt.cyan(event.provider)}...`);
|
|
149
|
+
break;
|
|
150
|
+
case 'waiting_quote':
|
|
151
|
+
output.print(` Waiting for quote (${event.ttlSeconds}s TTL)...`);
|
|
152
|
+
break;
|
|
153
|
+
case 'quote_received':
|
|
154
|
+
output.print(' Quote received, validating...');
|
|
155
|
+
break;
|
|
156
|
+
case 'round_end':
|
|
157
|
+
if (event.action === 'accepted') {
|
|
158
|
+
output.success(`Round ${event.round}: ${output_1.fmt.green('accepted')} — ${event.reason}`);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
output.print(` Round ${event.round}: ${output_1.fmt.dim(event.action)} — ${event.reason}`);
|
|
162
|
+
}
|
|
163
|
+
break;
|
|
164
|
+
case 'complete':
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
try {
|
|
169
|
+
const result = await orchestrator.negotiate({
|
|
170
|
+
dryRun: options.dryRun,
|
|
171
|
+
pollIntervalMs: pollInterval,
|
|
172
|
+
onProgress,
|
|
173
|
+
});
|
|
174
|
+
spinner.stop(result.success);
|
|
175
|
+
// Output result
|
|
176
|
+
output.result({
|
|
177
|
+
success: result.success,
|
|
178
|
+
commerce_session_id: result.commerce_session_id,
|
|
179
|
+
actp_tx_id: result.actp_tx_id,
|
|
180
|
+
selected_provider: result.selected_provider,
|
|
181
|
+
rounds_used: result.rounds_used,
|
|
182
|
+
reason: result.reason,
|
|
183
|
+
rounds: result.rounds,
|
|
184
|
+
}, { quietKey: result.success ? 'actp_tx_id' : 'reason' });
|
|
185
|
+
process.exit(result.success ? output_1.ExitCode.SUCCESS : output_1.ExitCode.ERROR);
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
spinner.stop(false);
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=negotiate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"negotiate.js","sourceRoot":"","sources":["../../../src/cli/commands/negotiate.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,yCAAoC;AACpC,2BAAkC;AAClC,4CAAwD;AACxD,4CAAyD;AACzD,2EAAuF;AAGvF,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,SAAgB,sBAAsB;IACpC,MAAM,GAAG,GAAG,IAAI,mBAAO,CAAC,WAAW,CAAC;SACjC,WAAW,CAAC,uCAAuC,CAAC;SACpD,cAAc,CAAC,iBAAiB,EAAE,gCAAgC,CAAC;SACnE,MAAM,CAAC,WAAW,EAAE,gDAAgD,CAAC;SACrE,MAAM,CAAC,sBAAsB,EAAE,oCAAoC,EAAE,MAAM,CAAC;SAC5E,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC;SACvC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,IAAI,eAAM,CACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAC1D,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,eAAe,GAAG,IAAA,iBAAQ,EAAC,KAAK,CAAC,CAAC;YACxC,MAAM,CAAC,WAAW,CAAC;gBACjB,IAAI,EAAE,eAAe,CAAC,IAAI;gBAC1B,OAAO,EAAE,eAAe,CAAC,OAAO;gBAChC,OAAO,EAAE,eAAe,CAAC,OAAO;aACjC,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,iBAAQ,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO,GAAG,CAAC;AACb,CAAC;AA3BD,wDA2BC;AAED,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,KAAK,UAAU,YAAY,CACzB,OAAqG,EACrG,MAAc;IAEd,cAAc;IACd,IAAI,MAAmB,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,WAAW,CAAC;YACjB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;SACtF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,iBAAQ,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,+DAA+D;IAC/D,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAClL,MAAM,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,WAAW,EAAE,eAAe,EAAE,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACrL,MAAM,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,WAAW,EAAE,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QAChJ,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,IAAI,OAAO,MAAM,CAAC,WAAW,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACvF,MAAM,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;IAC3E,CAAC;SAAM,CAAC;QACN,kDAAkD;QAClD,IAAI,CAAC;YACH,MAAM,EAAE,YAAY,EAAE,GAAG,wDAAa,gCAAgC,GAAC,CAAC;YACxE,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,8CAA8C,MAAM,CAAC,WAAW,CAAC,SAAS,sCAAsC,CAAC,CAAC;QAChI,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7F,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,WAAW,CAAC;YACjB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,mBAAmB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAChD,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,iBAAQ,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,eAAe,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAC;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACnF,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,GAAG,EAAE,CAAC;QAC9C,MAAM,CAAC,WAAW,CAAC;YACjB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,0DAA0D,eAAe,GAAG;SACtF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,iBAAQ,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAY,GAAE,CAAC;IAEpC,MAAM,YAAY,GAAG,IAAI,qCAAiB,CACxC,MAAM,EACN,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,UAAU,EAAE,CACpB,CAAC;IAEF,mCAAmC;IACnC,MAAM,UAAU,GAAG,CAAC,KAAoB,EAAE,EAAE;QAC1C,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO;QAE1C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,WAAW;gBACd,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,MAAM,CAAC,KAAK,CAAC,SAAS,KAAK,CAAC,UAAU,aAAa,CAAC,CAAC;gBACrD,MAAM;YACR,KAAK,SAAS;gBACZ,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,MAAM,aAAa,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,aAAa;gBAChB,MAAM,CAAC,KAAK,CAAC,SAAS,KAAK,CAAC,KAAK,YAAY,YAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC5E,MAAM;YACR,KAAK,eAAe;gBAClB,MAAM,CAAC,KAAK,CAAC,wBAAwB,KAAK,CAAC,UAAU,WAAW,CAAC,CAAC;gBAClE,MAAM;YACR,KAAK,gBAAgB;gBACnB,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;gBAChD,MAAM;YACR,KAAK,WAAW;gBACd,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBAChC,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,CAAC,KAAK,KAAK,YAAG,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrF,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC,KAAK,KAAK,YAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrF,CAAC;gBACD,MAAM;YACR,KAAK,UAAU;gBACb,MAAM;QACV,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC;YAC1C,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,cAAc,EAAE,YAAY;YAC5B,UAAU;SACX,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE7B,gBAAgB;QAChB,MAAM,CAAC,MAAM,CACX;YACE,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;YAC/C,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;YAC3C,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,EACD,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE,CACvD,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAQ,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyEpC,wBAAgB,oBAAoB,IAAI,OAAO,CA4B9C"}
|
|
@@ -49,9 +49,12 @@ const agirailsmd_1 = require("../../config/agirailsmd");
|
|
|
49
49
|
const publishPipeline_1 = require("../../config/publishPipeline");
|
|
50
50
|
const pendingPublish_1 = require("../../config/pendingPublish");
|
|
51
51
|
const config_1 = require("../utils/config");
|
|
52
|
+
const ethers_1 = require("ethers");
|
|
52
53
|
const FilebaseClient_1 = require("../../storage/FilebaseClient");
|
|
53
54
|
const ArweaveClient_1 = require("../../storage/ArweaveClient");
|
|
54
55
|
const wallet_1 = require("../utils/wallet");
|
|
56
|
+
const agirailsmdV4_1 = require("../../config/agirailsmdV4");
|
|
57
|
+
const agirailsApp_1 = require("../../api/agirailsApp");
|
|
55
58
|
// ============================================================================
|
|
56
59
|
// Publish Proxy (fallback when no Filebase credentials)
|
|
57
60
|
// ============================================================================
|
|
@@ -101,7 +104,7 @@ async function publishViaProxy(content, localConfigHash) {
|
|
|
101
104
|
function createPublishCommand() {
|
|
102
105
|
const cmd = new commander_1.Command('publish')
|
|
103
106
|
.description('Publish AGIRAILS.md config (offline — activates on first payment)')
|
|
104
|
-
.argument('[path]', 'Path to AGIRAILS.md
|
|
107
|
+
.argument('[path]', 'Path to AGIRAILS.md or {slug}.md')
|
|
105
108
|
.option('-n, --network <network>', 'DEPRECATED: network is auto-detected (accepted but ignored)')
|
|
106
109
|
.option('--skip-arweave', 'Skip permanent Arweave storage (dev mode)')
|
|
107
110
|
.option('--dry-run', 'Show what would happen without executing')
|
|
@@ -130,16 +133,33 @@ async function runPublish(filePath, options, output) {
|
|
|
130
133
|
if (options.network) {
|
|
131
134
|
output.warning('--network flag is deprecated and ignored. Network is auto-detected at payment time.');
|
|
132
135
|
}
|
|
133
|
-
|
|
136
|
+
// Resolve file path: explicit arg > identity pointer > ./AGIRAILS.md fallback
|
|
137
|
+
let effectivePath = filePath;
|
|
138
|
+
if (!effectivePath) {
|
|
139
|
+
const { resolveIdentityPath } = await Promise.resolve().then(() => __importStar(require('../utils/config')));
|
|
140
|
+
const identityPath = resolveIdentityPath();
|
|
141
|
+
if (identityPath) {
|
|
142
|
+
effectivePath = identityPath;
|
|
143
|
+
}
|
|
144
|
+
else if ((0, fs_1.existsSync)((0, path_1.resolve)('./AGIRAILS.md'))) {
|
|
145
|
+
effectivePath = './AGIRAILS.md';
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
output.error('No file to publish. Provide a path, or create a {slug}.md identity file.\n' +
|
|
149
|
+
'Usage: actp publish [path]');
|
|
150
|
+
process.exit(output_1.ExitCode.INVALID_INPUT);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let resolvedPath = (0, path_1.resolve)(effectivePath);
|
|
134
154
|
if (!(0, fs_1.existsSync)(resolvedPath)) {
|
|
135
|
-
output.error(`File not found: ${
|
|
155
|
+
output.error(`File not found: ${effectivePath}`);
|
|
136
156
|
process.exit(output_1.ExitCode.INVALID_INPUT);
|
|
137
157
|
}
|
|
138
158
|
const spinner = output.spinner('Reading AGIRAILS.md...');
|
|
139
159
|
try {
|
|
140
160
|
// Read and compute hash
|
|
141
|
-
|
|
142
|
-
|
|
161
|
+
let content = (0, fs_1.readFileSync)(resolvedPath, 'utf-8');
|
|
162
|
+
let { configHash, structuredHash, bodyHash } = (0, agirailsmd_1.computeConfigHash)(content);
|
|
143
163
|
if (options.dryRun) {
|
|
144
164
|
spinner.stop(true);
|
|
145
165
|
output.result({
|
|
@@ -153,6 +173,79 @@ async function runPublish(filePath, options, output) {
|
|
|
153
173
|
output.success('Dry run complete. No changes made.');
|
|
154
174
|
return;
|
|
155
175
|
}
|
|
176
|
+
// ================================================================
|
|
177
|
+
// Phase 1: Slug check (pre-chain, no auth, only on first publish)
|
|
178
|
+
// ================================================================
|
|
179
|
+
let v4Config;
|
|
180
|
+
try {
|
|
181
|
+
v4Config = (0, agirailsmdV4_1.parseAgirailsMdV4)(content);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// Not a v4 file — skip slug check (backward compatible with v3 AGIRAILS.md)
|
|
185
|
+
}
|
|
186
|
+
if (v4Config && !v4Config.agent_id) {
|
|
187
|
+
// First publish — check slug availability
|
|
188
|
+
const slugSpinner = output.spinner(`Checking slug availability: ${v4Config.slug}...`);
|
|
189
|
+
try {
|
|
190
|
+
const slugResult = await (0, agirailsApp_1.checkSlug)(v4Config.slug);
|
|
191
|
+
if (!slugResult.available) {
|
|
192
|
+
if (slugResult.suggestion) {
|
|
193
|
+
slugSpinner.stop(true);
|
|
194
|
+
const oldSlug = v4Config.slug;
|
|
195
|
+
const newSlug = slugResult.suggestion;
|
|
196
|
+
// Auto-rename: update frontmatter slug, rename file, update config pointer
|
|
197
|
+
output.info(`Slug "${oldSlug}" was taken. Renamed to "${newSlug}".`);
|
|
198
|
+
// Rename file on disk
|
|
199
|
+
const { dirname, join: pathJoin } = await Promise.resolve().then(() => __importStar(require('path')));
|
|
200
|
+
const dir = dirname(resolvedPath);
|
|
201
|
+
const newPath = pathJoin(dir, `${newSlug}.md`);
|
|
202
|
+
(0, fs_1.renameSync)(resolvedPath, newPath);
|
|
203
|
+
// Re-read, update slug in frontmatter, rewrite, re-parse, recompute hash
|
|
204
|
+
const rawContent = (0, fs_1.readFileSync)(newPath, 'utf-8');
|
|
205
|
+
const parsed = (0, agirailsmd_1.parseAgirailsMd)(rawContent);
|
|
206
|
+
const updatedFm = { ...parsed.frontmatter, slug: newSlug };
|
|
207
|
+
const newContent = (0, agirailsmd_1.serializeAgirailsMd)(updatedFm, parsed.body);
|
|
208
|
+
(0, fs_1.writeFileSync)(newPath, newContent, 'utf-8');
|
|
209
|
+
// Update in-memory references for the rest of publish
|
|
210
|
+
resolvedPath = newPath;
|
|
211
|
+
v4Config.slug = newSlug;
|
|
212
|
+
// Recompute configHash with new slug
|
|
213
|
+
const reHash = (0, agirailsmd_1.computeConfigHash)(newContent);
|
|
214
|
+
configHash = reHash.configHash;
|
|
215
|
+
content = newContent;
|
|
216
|
+
// Update config.json identity pointer
|
|
217
|
+
try {
|
|
218
|
+
const config = (0, config_1.loadConfig)((0, path_1.resolve)(newPath, '..'));
|
|
219
|
+
config.identity = `${newSlug}.md`;
|
|
220
|
+
(0, config_1.saveConfig)(config, (0, path_1.resolve)(newPath, '..'));
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Best-effort
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
slugSpinner.stop(false);
|
|
228
|
+
throw new Error(`Slug "${v4Config.slug}" is already taken on agirails.app. Choose a different name.`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
slugSpinner.stop(true);
|
|
233
|
+
output.success(`Slug "${v4Config.slug}" is available.`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (slugErr) {
|
|
237
|
+
if (slugErr.message.includes('already taken'))
|
|
238
|
+
throw slugErr;
|
|
239
|
+
if (slugErr.message.includes('was taken')) {
|
|
240
|
+
// Auto-rename succeeded — not an error
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
slugSpinner.stop(false);
|
|
244
|
+
// Non-fatal: slug check API failure doesn't block publish
|
|
245
|
+
output.warning(`Slug check failed: ${slugErr.message}. Proceeding.`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
156
249
|
// Ensure .actp directory exists
|
|
157
250
|
const actpDir = (0, pendingPublish_1.getActpDir)();
|
|
158
251
|
if (!(0, fs_1.existsSync)(actpDir)) {
|
|
@@ -231,7 +324,7 @@ async function runPublish(filePath, options, output) {
|
|
|
231
324
|
serviceDescriptors: regParams.serviceDescriptors,
|
|
232
325
|
createdAt: new Date().toISOString(),
|
|
233
326
|
};
|
|
234
|
-
const projectRoot = (0, path_1.resolve)(
|
|
327
|
+
const projectRoot = (0, path_1.resolve)(resolvedPath, '..');
|
|
235
328
|
// ================================================================
|
|
236
329
|
// Local setup: bootstrap or migrate config, ensure .gitignore
|
|
237
330
|
// "publish covers setup" — no separate `actp init` required.
|
|
@@ -263,11 +356,14 @@ async function runPublish(filePath, options, output) {
|
|
|
263
356
|
// ALWAYS activate on testnet (one command, both networks per SPEC)
|
|
264
357
|
// ================================================================
|
|
265
358
|
let testnetTxHash;
|
|
359
|
+
let smartWalletAddress;
|
|
266
360
|
const activationSpinner = output.spinner('Activating on testnet...');
|
|
267
361
|
try {
|
|
268
|
-
|
|
362
|
+
const activationResult = await activateOnTestnet(projectRoot, configHash, cid, regParams.endpoint, regParams.serviceDescriptors, output);
|
|
269
363
|
activationSpinner.stop(true);
|
|
270
|
-
if (
|
|
364
|
+
if (activationResult) {
|
|
365
|
+
testnetTxHash = activationResult.txHash;
|
|
366
|
+
smartWalletAddress = activationResult.smartWalletAddress;
|
|
271
367
|
output.success(`Testnet activation: ${testnetTxHash}`);
|
|
272
368
|
}
|
|
273
369
|
else {
|
|
@@ -281,8 +377,176 @@ async function runPublish(filePath, options, output) {
|
|
|
281
377
|
output.warning(`Testnet activation failed: ${activationError.message}\n` +
|
|
282
378
|
' Saved as pending — will activate on first testnet payment.');
|
|
283
379
|
}
|
|
284
|
-
//
|
|
380
|
+
// Save mainnet pending (lazy — activates on first mainnet payment).
|
|
381
|
+
// This is intentional even when config mode is testnet: the agent may later
|
|
382
|
+
// switch to mainnet, and the pending file ensures activation happens automatically.
|
|
285
383
|
(0, pendingPublish_1.savePendingPublish)({ ...pendingData, network: 'base-mainnet' });
|
|
384
|
+
// ================================================================
|
|
385
|
+
// Write-back: wallet, agent_id, did into AGIRAILS.md frontmatter
|
|
386
|
+
// These are in PUBLISH_METADATA_KEYS — stripped before hash computation.
|
|
387
|
+
// ================================================================
|
|
388
|
+
const publishMetadata = {};
|
|
389
|
+
// Wallet write-back: Smart Wallet is the on-chain identity (NFT owner,
|
|
390
|
+
// escrow party). EOA is only a fallback for non-Smart-Wallet flows.
|
|
391
|
+
const existingWallet = frontmatter.wallet;
|
|
392
|
+
const canonicalWallet = smartWalletAddress || existingWallet || walletAddress;
|
|
393
|
+
if (canonicalWallet) {
|
|
394
|
+
publishMetadata.wallet = canonicalWallet;
|
|
395
|
+
publishMetadata.did = `did:ethr:84532:${canonicalWallet}`;
|
|
396
|
+
}
|
|
397
|
+
// agent_id: query ERC-8004 Identity Registry for minted tokenId
|
|
398
|
+
// Use Smart Wallet address (NFT owner) when available, fall back to EOA
|
|
399
|
+
const ownerAddress = smartWalletAddress || existingWallet || walletAddress;
|
|
400
|
+
if (testnetTxHash && ownerAddress) {
|
|
401
|
+
try {
|
|
402
|
+
const { getNetwork: getNet } = await Promise.resolve().then(() => __importStar(require('../../config/networks')));
|
|
403
|
+
const { ethers: eth } = await Promise.resolve().then(() => __importStar(require('ethers')));
|
|
404
|
+
const net = getNet('base-sepolia');
|
|
405
|
+
const prov = new eth.JsonRpcProvider(net.rpcUrl);
|
|
406
|
+
// Query ERC-8004 Identity Registry for the agent's NFT tokenId
|
|
407
|
+
const erc8004Addr = net.contracts.erc8004IdentityRegistry;
|
|
408
|
+
if (erc8004Addr) {
|
|
409
|
+
const { ERC8004_IDENTITY_ABI } = await Promise.resolve().then(() => __importStar(require('../../types/erc8004')));
|
|
410
|
+
const erc8004 = new eth.Contract(erc8004Addr, ERC8004_IDENTITY_ABI, prov);
|
|
411
|
+
// Parse Registered event from tx receipt for exact agentId
|
|
412
|
+
let agentId;
|
|
413
|
+
try {
|
|
414
|
+
const receipt = await prov.getTransactionReceipt(testnetTxHash);
|
|
415
|
+
if (receipt) {
|
|
416
|
+
const registeredTopic = eth.id('Registered(uint256,string,address)');
|
|
417
|
+
for (const log of receipt.logs) {
|
|
418
|
+
if (log.address.toLowerCase() === erc8004Addr.toLowerCase()
|
|
419
|
+
&& log.topics[0] === registeredTopic) {
|
|
420
|
+
// agentId is the first indexed parameter
|
|
421
|
+
agentId = BigInt(log.topics[1]).toString();
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
// Event parsing failed — fall back to balanceOf query
|
|
429
|
+
}
|
|
430
|
+
// Fallback: query by balance if event parsing didn't work
|
|
431
|
+
if (!agentId) {
|
|
432
|
+
const balance = await erc8004.balanceOf(ownerAddress);
|
|
433
|
+
if (Number(balance) > 0) {
|
|
434
|
+
const lastIndex = Number(balance) - 1;
|
|
435
|
+
agentId = (await erc8004.tokenOfOwnerByIndex(ownerAddress, lastIndex)).toString();
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (agentId) {
|
|
439
|
+
publishMetadata.agent_id = agentId;
|
|
440
|
+
publishMetadata.did = `did:ethr:84532:${ownerAddress}`;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
// Fallback: check AgentRegistry if ERC-8004 didn't yield an agent_id
|
|
444
|
+
if (!publishMetadata.agent_id) {
|
|
445
|
+
const registryAddr = net.contracts.agentRegistry;
|
|
446
|
+
if (registryAddr) {
|
|
447
|
+
const { AgentRegistryClient: ARC } = await Promise.resolve().then(() => __importStar(require('../../registry/AgentRegistryClient')));
|
|
448
|
+
const regClient = ARC.readOnly(registryAddr, prov);
|
|
449
|
+
const onChainConfig = await regClient.getConfig(ownerAddress);
|
|
450
|
+
if (onChainConfig.isActive) {
|
|
451
|
+
const agentId = BigInt(ownerAddress).toString();
|
|
452
|
+
publishMetadata.agent_id = agentId;
|
|
453
|
+
publishMetadata.did = `did:ethr:84532:${ownerAddress}`;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
catch {
|
|
459
|
+
// Best-effort — agent_id will be written on re-publish
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
// ================================================================
|
|
463
|
+
// Phase 1: API upsert to agirails.app (post-chain, non-blocking)
|
|
464
|
+
// Uses agent_id from YAML or freshly minted (publishMetadata).
|
|
465
|
+
// API routes: POST /api/v1/agents (dual auth: session + wallet-sig)
|
|
466
|
+
// ================================================================
|
|
467
|
+
const effectiveAgentId = v4Config?.agent_id || publishMetadata.agent_id;
|
|
468
|
+
if (v4Config && effectiveAgentId && walletAddress) {
|
|
469
|
+
const apiSpinner = output.spinner('Syncing with agirails.app...');
|
|
470
|
+
try {
|
|
471
|
+
const publishTimestamp = Math.floor(Date.now() / 1000);
|
|
472
|
+
// C-2 fix: include network in signed message to prevent cross-network replay
|
|
473
|
+
// Upsert only fires after testnet activation, so network is always base-sepolia
|
|
474
|
+
const publishNetwork = 'base-sepolia';
|
|
475
|
+
const upsertMessage = `agirails-publish:${v4Config.slug}:${configHash}:${publishNetwork}:${publishTimestamp}`;
|
|
476
|
+
const { resolvePrivateKey: resolveKey } = await Promise.resolve().then(() => __importStar(require('../../wallet/keystore')));
|
|
477
|
+
const privKey = await resolveKey(projectRoot, { network: 'testnet' });
|
|
478
|
+
if (privKey) {
|
|
479
|
+
const signer = new ethers_1.ethers.Wallet(privKey);
|
|
480
|
+
const sig = await signer.signMessage(upsertMessage);
|
|
481
|
+
const apiResult = await (0, agirailsApp_1.upsertAgent)({
|
|
482
|
+
slug: v4Config.slug,
|
|
483
|
+
agentId: effectiveAgentId,
|
|
484
|
+
wallet: smartWalletAddress || existingWallet || walletAddress,
|
|
485
|
+
signer: walletAddress, // EOA that signed the message
|
|
486
|
+
configCid: cid,
|
|
487
|
+
configHash,
|
|
488
|
+
signature: sig,
|
|
489
|
+
message: upsertMessage,
|
|
490
|
+
timestamp: publishTimestamp,
|
|
491
|
+
network: publishNetwork,
|
|
492
|
+
config: {
|
|
493
|
+
name: v4Config.name,
|
|
494
|
+
description: (v4Config.description || "").replace(/^#\s+[^\n]+\n*/, "").trim(),
|
|
495
|
+
capabilities: v4Config.services,
|
|
496
|
+
pricing: {
|
|
497
|
+
model: "fixed",
|
|
498
|
+
amount: String(v4Config.pricing.base),
|
|
499
|
+
unit: v4Config.pricing.unit || "job",
|
|
500
|
+
currency: v4Config.pricing.currency || "USDC",
|
|
501
|
+
minimum: String(v4Config.pricing.min_price ?? v4Config.pricing.base),
|
|
502
|
+
},
|
|
503
|
+
sla: {
|
|
504
|
+
availability: "24/7",
|
|
505
|
+
responseTime: { p50: 30, p95: 300 },
|
|
506
|
+
...(v4Config.sla.concurrency ? { throughput: v4Config.sla.concurrency + " concurrent" } : {}),
|
|
507
|
+
},
|
|
508
|
+
...(v4Config.sla.concurrency ? { concurrency: v4Config.sla.concurrency } : {}),
|
|
509
|
+
payment_mode: v4Config.payment.modes.includes("x402") ? "x402" : "actp",
|
|
510
|
+
network: v4Config.network,
|
|
511
|
+
// Covenant: map V4 accepts/returns to web input/output format
|
|
512
|
+
...(v4Config.covenant.accepts && Object.keys(v4Config.covenant.accepts).length > 0 ? {
|
|
513
|
+
covenant: {
|
|
514
|
+
input: Object.entries(v4Config.covenant.accepts).map(([k, v]) => k + ": " + v).join("\n"),
|
|
515
|
+
output: Object.entries(v4Config.covenant.returns).map(([k, v]) => k + ": " + v).join("\n"),
|
|
516
|
+
guarantees: [],
|
|
517
|
+
dispute: { window_hours: 24, resolution: "auto-refund" },
|
|
518
|
+
},
|
|
519
|
+
} : {}),
|
|
520
|
+
// Endpoint: for x402 agents
|
|
521
|
+
...(v4Config.endpoint ? {
|
|
522
|
+
endpoints: { execute: v4Config.endpoint },
|
|
523
|
+
} : {}),
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
apiSpinner.stop(true);
|
|
527
|
+
output.success(`Profile live at: agirails.app/a/${v4Config.slug}`);
|
|
528
|
+
// Display claim code if returned (for linking to dashboard)
|
|
529
|
+
if (apiResult.claimCode) {
|
|
530
|
+
output.print(` Claim code: ${apiResult.claimCode}`);
|
|
531
|
+
output.print(` Claim link: https://agirails.app/claim?code=${apiResult.claimCode}`);
|
|
532
|
+
output.print(' (use this to link the agent to your dashboard account)');
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
apiSpinner.stop(false);
|
|
537
|
+
output.info('Skipped agirails.app sync (no wallet key for signing).');
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
catch (apiErr) {
|
|
541
|
+
apiSpinner.stop(false);
|
|
542
|
+
// Non-blocking — agent is already on-chain
|
|
543
|
+
output.warning(`agirails.app sync failed: ${apiErr.message}`);
|
|
544
|
+
output.print(' Agent is on-chain. Retry with: actp publish');
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
else if (v4Config && !v4Config.agent_id) {
|
|
548
|
+
output.info('First publish — agirails.app sync will happen on re-publish (after agent_id is assigned).');
|
|
549
|
+
}
|
|
286
550
|
// Update AGIRAILS.md frontmatter
|
|
287
551
|
const updatedFrontmatter = {
|
|
288
552
|
...frontmatter,
|
|
@@ -290,9 +554,25 @@ async function runPublish(filePath, options, output) {
|
|
|
290
554
|
config_cid: cid,
|
|
291
555
|
published_at: new Date().toISOString(),
|
|
292
556
|
...(arweaveTxId ? { arweave_tx: arweaveTxId } : {}),
|
|
557
|
+
...publishMetadata,
|
|
293
558
|
};
|
|
294
559
|
const updatedContent = (0, agirailsmd_1.serializeAgirailsMd)(updatedFrontmatter, body);
|
|
295
560
|
(0, fs_1.writeFileSync)(resolvedPath, updatedContent, 'utf-8');
|
|
561
|
+
// Update identity pointer in config.json if this is a {slug}.md file
|
|
562
|
+
if (v4Config) {
|
|
563
|
+
try {
|
|
564
|
+
const { basename } = await Promise.resolve().then(() => __importStar(require('path')));
|
|
565
|
+
const config = (0, config_1.loadConfig)(projectRoot);
|
|
566
|
+
const filename = basename(resolvedPath);
|
|
567
|
+
if (config.identity !== filename) {
|
|
568
|
+
config.identity = filename;
|
|
569
|
+
(0, config_1.saveConfig)(config, projectRoot);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
catch {
|
|
573
|
+
// Best-effort — config might not exist yet
|
|
574
|
+
}
|
|
575
|
+
}
|
|
296
576
|
// Output results
|
|
297
577
|
output.result({
|
|
298
578
|
configHash,
|
|
@@ -310,17 +590,31 @@ async function runPublish(filePath, options, output) {
|
|
|
310
590
|
}
|
|
311
591
|
output.print('');
|
|
312
592
|
output.print('Mainnet: on-chain activation will happen on your first payment.');
|
|
593
|
+
// Context-aware next steps
|
|
594
|
+
const hasEndpoint = frontmatter.endpoint && frontmatter.endpoint !== publishPipeline_1.PENDING_ENDPOINT;
|
|
313
595
|
output.print('');
|
|
314
596
|
output.print('Next steps:');
|
|
315
|
-
|
|
316
|
-
|
|
597
|
+
if (!hasEndpoint) {
|
|
598
|
+
output.print(' 1. Set your endpoint: Add "endpoint: https://..." to AGIRAILS.md');
|
|
599
|
+
output.print(' 2. Check endpoint: actp health');
|
|
600
|
+
output.print(' 3. Check your balance: actp balance');
|
|
601
|
+
output.print(' 4. Verify config match: actp diff');
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
output.print(' 1. Check endpoint: actp health');
|
|
605
|
+
output.print(' 2. Check your balance: actp balance');
|
|
606
|
+
output.print(' 3. Verify config match: actp diff');
|
|
607
|
+
}
|
|
608
|
+
// Suggest test payment on testnet
|
|
609
|
+
if (testnetTxHash && v4Config?.slug) {
|
|
610
|
+
output.print('');
|
|
611
|
+
output.print(` Try a test payment: actp pay agirails.app/a/${v4Config.slug} 5`);
|
|
612
|
+
}
|
|
317
613
|
// Warn if placeholder endpoint
|
|
318
|
-
if (!
|
|
614
|
+
if (!hasEndpoint) {
|
|
319
615
|
output.print('');
|
|
320
|
-
output.warning('No endpoint
|
|
321
|
-
output.print('
|
|
322
|
-
output.print(' 1. Add "endpoint: https://your-agent.com/webhook" to AGIRAILS.md');
|
|
323
|
-
output.print(' 2. Run: actp publish');
|
|
616
|
+
output.warning('No endpoint set — your agent can\'t receive jobs yet.');
|
|
617
|
+
output.print(' Add "endpoint: https://your-agent.com/webhook" to AGIRAILS.md, then: actp publish');
|
|
324
618
|
}
|
|
325
619
|
}
|
|
326
620
|
catch (error) {
|
|
@@ -393,7 +687,7 @@ async function activateOnTestnet(projectRoot, configHash, cid, endpoint, service
|
|
|
393
687
|
// Already up-to-date on-chain — no activation needed
|
|
394
688
|
return undefined;
|
|
395
689
|
}
|
|
396
|
-
// Build activation calls
|
|
690
|
+
// Build activation calls (includes ERC-8004 identity mint for scenario A)
|
|
397
691
|
const activationCalls = buildActivationBatch({
|
|
398
692
|
scenario,
|
|
399
693
|
agentRegistryAddress: networkConfig.contracts.agentRegistry,
|
|
@@ -401,6 +695,7 @@ async function activateOnTestnet(projectRoot, configHash, cid, endpoint, service
|
|
|
401
695
|
configHash,
|
|
402
696
|
listed: true,
|
|
403
697
|
...(scenario === 'A' ? { endpoint, serviceDescriptors } : {}),
|
|
698
|
+
erc8004IdentityRegistry: networkConfig.contracts.erc8004IdentityRegistry,
|
|
404
699
|
});
|
|
405
700
|
// Always mint test USDC on testnet (SPEC: "always")
|
|
406
701
|
const mintCalls = buildTestnetMintBatch(networkConfig.contracts.usdc, smartWalletAddress, '1000000000');
|
|
@@ -416,6 +711,6 @@ async function activateOnTestnet(projectRoot, configHash, cid, endpoint, service
|
|
|
416
711
|
throw new Error(`Testnet activation UserOp failed: ${receipt.hash}`);
|
|
417
712
|
}
|
|
418
713
|
output.success('Minted 1,000 test USDC to Smart Wallet');
|
|
419
|
-
return receipt.hash;
|
|
714
|
+
return { txHash: receipt.hash, smartWalletAddress };
|
|
420
715
|
}
|
|
421
716
|
//# sourceMappingURL=publish.js.map
|