@agirails/sdk 2.6.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/agirails +10 -0
- package/dist/ACTPClient.d.ts +9 -4
- package/dist/ACTPClient.d.ts.map +1 -1
- package/dist/ACTPClient.js +12 -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/adapters/X402Adapter.d.ts.map +1 -1
- package/dist/adapters/X402Adapter.js +14 -12
- package/dist/adapters/X402Adapter.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 +310 -17
- 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 +254 -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 +24 -14
- package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
- package/dist/runtime/BlockchainRuntime.js +60 -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 +22 -9
- package/dist/runtime/MockRuntime.d.ts.map +1 -1
- package/dist/runtime/MockRuntime.js +76 -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/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/types/x402.d.ts +17 -9
- package/dist/types/x402.d.ts.map +1 -1
- package/dist/types/x402.js +9 -9
- package/dist/types/x402.js.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":"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"}
|
|
@@ -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 {
|
|
@@ -283,6 +379,172 @@ async function runPublish(filePath, options, output) {
|
|
|
283
379
|
}
|
|
284
380
|
// Always save mainnet pending (lazy — activates on first mainnet payment)
|
|
285
381
|
(0, pendingPublish_1.savePendingPublish)({ ...pendingData, network: 'base-mainnet' });
|
|
382
|
+
// ================================================================
|
|
383
|
+
// Write-back: wallet, agent_id, did into AGIRAILS.md frontmatter
|
|
384
|
+
// These are in PUBLISH_METADATA_KEYS — stripped before hash computation.
|
|
385
|
+
// ================================================================
|
|
386
|
+
const publishMetadata = {};
|
|
387
|
+
// Wallet write-back: Smart Wallet is the on-chain identity (NFT owner,
|
|
388
|
+
// escrow party). EOA is only a fallback for non-Smart-Wallet flows.
|
|
389
|
+
const existingWallet = frontmatter.wallet;
|
|
390
|
+
const canonicalWallet = smartWalletAddress || existingWallet || walletAddress;
|
|
391
|
+
if (canonicalWallet) {
|
|
392
|
+
publishMetadata.wallet = canonicalWallet;
|
|
393
|
+
publishMetadata.did = `did:ethr:84532:${canonicalWallet}`;
|
|
394
|
+
}
|
|
395
|
+
// agent_id: query ERC-8004 Identity Registry for minted tokenId
|
|
396
|
+
// Use Smart Wallet address (NFT owner) when available, fall back to EOA
|
|
397
|
+
const ownerAddress = smartWalletAddress || existingWallet || walletAddress;
|
|
398
|
+
if (testnetTxHash && ownerAddress) {
|
|
399
|
+
try {
|
|
400
|
+
const { getNetwork: getNet } = await Promise.resolve().then(() => __importStar(require('../../config/networks')));
|
|
401
|
+
const { ethers: eth } = await Promise.resolve().then(() => __importStar(require('ethers')));
|
|
402
|
+
const net = getNet('base-sepolia');
|
|
403
|
+
const prov = new eth.JsonRpcProvider(net.rpcUrl);
|
|
404
|
+
// Query ERC-8004 Identity Registry for the agent's NFT tokenId
|
|
405
|
+
const erc8004Addr = net.contracts.erc8004IdentityRegistry;
|
|
406
|
+
if (erc8004Addr) {
|
|
407
|
+
const { ERC8004_IDENTITY_ABI } = await Promise.resolve().then(() => __importStar(require('../../types/erc8004')));
|
|
408
|
+
const erc8004 = new eth.Contract(erc8004Addr, ERC8004_IDENTITY_ABI, prov);
|
|
409
|
+
// Parse Registered event from tx receipt for exact agentId
|
|
410
|
+
let agentId;
|
|
411
|
+
try {
|
|
412
|
+
const receipt = await prov.getTransactionReceipt(testnetTxHash);
|
|
413
|
+
if (receipt) {
|
|
414
|
+
const registeredTopic = eth.id('Registered(uint256,string,address)');
|
|
415
|
+
for (const log of receipt.logs) {
|
|
416
|
+
if (log.address.toLowerCase() === erc8004Addr.toLowerCase()
|
|
417
|
+
&& log.topics[0] === registeredTopic) {
|
|
418
|
+
// agentId is the first indexed parameter
|
|
419
|
+
agentId = BigInt(log.topics[1]).toString();
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
// Event parsing failed — fall back to balanceOf query
|
|
427
|
+
}
|
|
428
|
+
// Fallback: query by balance if event parsing didn't work
|
|
429
|
+
if (!agentId) {
|
|
430
|
+
const balance = await erc8004.balanceOf(ownerAddress);
|
|
431
|
+
if (Number(balance) > 0) {
|
|
432
|
+
const lastIndex = Number(balance) - 1;
|
|
433
|
+
agentId = (await erc8004.tokenOfOwnerByIndex(ownerAddress, lastIndex)).toString();
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (agentId) {
|
|
437
|
+
publishMetadata.agent_id = agentId;
|
|
438
|
+
publishMetadata.did = `did:ethr:84532:${ownerAddress}`;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// Fallback: check AgentRegistry if ERC-8004 didn't yield an agent_id
|
|
442
|
+
if (!publishMetadata.agent_id) {
|
|
443
|
+
const registryAddr = net.contracts.agentRegistry;
|
|
444
|
+
if (registryAddr) {
|
|
445
|
+
const { AgentRegistryClient: ARC } = await Promise.resolve().then(() => __importStar(require('../../registry/AgentRegistryClient')));
|
|
446
|
+
const regClient = ARC.readOnly(registryAddr, prov);
|
|
447
|
+
const onChainConfig = await regClient.getConfig(ownerAddress);
|
|
448
|
+
if (onChainConfig.isActive) {
|
|
449
|
+
const agentId = BigInt(ownerAddress).toString();
|
|
450
|
+
publishMetadata.agent_id = agentId;
|
|
451
|
+
publishMetadata.did = `did:ethr:84532:${ownerAddress}`;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
catch {
|
|
457
|
+
// Best-effort — agent_id will be written on re-publish
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
// ================================================================
|
|
461
|
+
// Phase 1: API upsert to agirails.app (post-chain, non-blocking)
|
|
462
|
+
// Requires agent_id — skipped on first publish (agent_id assigned
|
|
463
|
+
// on-chain, written back to YAML, available on re-publish).
|
|
464
|
+
// API routes: POST /api/v1/agents (dual auth: session + wallet-sig)
|
|
465
|
+
// ================================================================
|
|
466
|
+
if (v4Config && v4Config.agent_id && walletAddress) {
|
|
467
|
+
const apiSpinner = output.spinner('Syncing with agirails.app...');
|
|
468
|
+
try {
|
|
469
|
+
const publishTimestamp = Math.floor(Date.now() / 1000);
|
|
470
|
+
// C-2 fix: include network in signed message to prevent cross-network replay
|
|
471
|
+
// Upsert only fires after testnet activation, so network is always base-sepolia
|
|
472
|
+
const publishNetwork = 'base-sepolia';
|
|
473
|
+
const upsertMessage = `agirails-publish:${v4Config.slug}:${configHash}:${publishNetwork}:${publishTimestamp}`;
|
|
474
|
+
const { resolvePrivateKey: resolveKey } = await Promise.resolve().then(() => __importStar(require('../../wallet/keystore')));
|
|
475
|
+
const privKey = await resolveKey(projectRoot, { network: 'testnet' });
|
|
476
|
+
if (privKey) {
|
|
477
|
+
const signer = new ethers_1.ethers.Wallet(privKey);
|
|
478
|
+
const sig = await signer.signMessage(upsertMessage);
|
|
479
|
+
const apiResult = await (0, agirailsApp_1.upsertAgent)({
|
|
480
|
+
slug: v4Config.slug,
|
|
481
|
+
agentId: v4Config.agent_id,
|
|
482
|
+
wallet: smartWalletAddress || existingWallet || walletAddress,
|
|
483
|
+
signer: walletAddress, // EOA that signed the message
|
|
484
|
+
configCid: cid,
|
|
485
|
+
configHash,
|
|
486
|
+
signature: sig,
|
|
487
|
+
message: upsertMessage,
|
|
488
|
+
timestamp: publishTimestamp,
|
|
489
|
+
network: publishNetwork,
|
|
490
|
+
config: {
|
|
491
|
+
name: v4Config.name,
|
|
492
|
+
description: (v4Config.description || "").replace(/^#\s+[^\n]+\n*/, "").trim(),
|
|
493
|
+
capabilities: v4Config.services,
|
|
494
|
+
pricing: {
|
|
495
|
+
model: "fixed",
|
|
496
|
+
amount: String(v4Config.pricing.base),
|
|
497
|
+
unit: v4Config.pricing.unit || "job",
|
|
498
|
+
currency: v4Config.pricing.currency || "USDC",
|
|
499
|
+
minimum: String(v4Config.pricing.min_price ?? v4Config.pricing.base),
|
|
500
|
+
},
|
|
501
|
+
sla: {
|
|
502
|
+
availability: "24/7",
|
|
503
|
+
responseTime: { p50: 30, p95: 300 },
|
|
504
|
+
...(v4Config.sla.concurrency ? { throughput: v4Config.sla.concurrency + " concurrent" } : {}),
|
|
505
|
+
},
|
|
506
|
+
...(v4Config.sla.concurrency ? { concurrency: v4Config.sla.concurrency } : {}),
|
|
507
|
+
payment_mode: v4Config.payment.modes.includes("x402") ? "x402" : "actp",
|
|
508
|
+
network: v4Config.network,
|
|
509
|
+
// Covenant: map V4 accepts/returns to web input/output format
|
|
510
|
+
...(v4Config.covenant.accepts && Object.keys(v4Config.covenant.accepts).length > 0 ? {
|
|
511
|
+
covenant: {
|
|
512
|
+
input: Object.entries(v4Config.covenant.accepts).map(([k, v]) => k + ": " + v).join("\n"),
|
|
513
|
+
output: Object.entries(v4Config.covenant.returns).map(([k, v]) => k + ": " + v).join("\n"),
|
|
514
|
+
guarantees: [],
|
|
515
|
+
dispute: { window_hours: 24, resolution: "auto-refund" },
|
|
516
|
+
},
|
|
517
|
+
} : {}),
|
|
518
|
+
// Endpoint: for x402 agents
|
|
519
|
+
...(v4Config.endpoint ? {
|
|
520
|
+
endpoints: { execute: v4Config.endpoint },
|
|
521
|
+
} : {}),
|
|
522
|
+
},
|
|
523
|
+
});
|
|
524
|
+
apiSpinner.stop(true);
|
|
525
|
+
output.success(`Profile live at: agirails.app/a/${v4Config.slug}`);
|
|
526
|
+
// Display claim code if returned (for linking to dashboard)
|
|
527
|
+
if (apiResult.claimCode) {
|
|
528
|
+
output.print(` Claim code: ${apiResult.claimCode}`);
|
|
529
|
+
output.print(` Claim link: https://agirails.app/claim?code=${apiResult.claimCode}`);
|
|
530
|
+
output.print(' (use this to link the agent to your dashboard account)');
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
apiSpinner.stop(false);
|
|
535
|
+
output.info('Skipped agirails.app sync (no wallet key for signing).');
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
catch (apiErr) {
|
|
539
|
+
apiSpinner.stop(false);
|
|
540
|
+
// Non-blocking — agent is already on-chain
|
|
541
|
+
output.warning(`agirails.app sync failed: ${apiErr.message}`);
|
|
542
|
+
output.print(' Agent is on-chain. Retry with: actp publish');
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
else if (v4Config && !v4Config.agent_id) {
|
|
546
|
+
output.info('First publish — agirails.app sync will happen on re-publish (after agent_id is assigned).');
|
|
547
|
+
}
|
|
286
548
|
// Update AGIRAILS.md frontmatter
|
|
287
549
|
const updatedFrontmatter = {
|
|
288
550
|
...frontmatter,
|
|
@@ -290,9 +552,25 @@ async function runPublish(filePath, options, output) {
|
|
|
290
552
|
config_cid: cid,
|
|
291
553
|
published_at: new Date().toISOString(),
|
|
292
554
|
...(arweaveTxId ? { arweave_tx: arweaveTxId } : {}),
|
|
555
|
+
...publishMetadata,
|
|
293
556
|
};
|
|
294
557
|
const updatedContent = (0, agirailsmd_1.serializeAgirailsMd)(updatedFrontmatter, body);
|
|
295
558
|
(0, fs_1.writeFileSync)(resolvedPath, updatedContent, 'utf-8');
|
|
559
|
+
// Update identity pointer in config.json if this is a {slug}.md file
|
|
560
|
+
if (v4Config) {
|
|
561
|
+
try {
|
|
562
|
+
const { basename } = await Promise.resolve().then(() => __importStar(require('path')));
|
|
563
|
+
const config = (0, config_1.loadConfig)(projectRoot);
|
|
564
|
+
const filename = basename(resolvedPath);
|
|
565
|
+
if (config.identity !== filename) {
|
|
566
|
+
config.identity = filename;
|
|
567
|
+
(0, config_1.saveConfig)(config, projectRoot);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
catch {
|
|
571
|
+
// Best-effort — config might not exist yet
|
|
572
|
+
}
|
|
573
|
+
}
|
|
296
574
|
// Output results
|
|
297
575
|
output.result({
|
|
298
576
|
configHash,
|
|
@@ -310,17 +588,31 @@ async function runPublish(filePath, options, output) {
|
|
|
310
588
|
}
|
|
311
589
|
output.print('');
|
|
312
590
|
output.print('Mainnet: on-chain activation will happen on your first payment.');
|
|
591
|
+
// Context-aware next steps
|
|
592
|
+
const hasEndpoint = frontmatter.endpoint && frontmatter.endpoint !== publishPipeline_1.PENDING_ENDPOINT;
|
|
313
593
|
output.print('');
|
|
314
594
|
output.print('Next steps:');
|
|
315
|
-
|
|
316
|
-
|
|
595
|
+
if (!hasEndpoint) {
|
|
596
|
+
output.print(' 1. Set your endpoint: Add "endpoint: https://..." to AGIRAILS.md');
|
|
597
|
+
output.print(' 2. Check endpoint: actp health');
|
|
598
|
+
output.print(' 3. Check your balance: actp balance');
|
|
599
|
+
output.print(' 4. Verify config match: actp diff');
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
output.print(' 1. Check endpoint: actp health');
|
|
603
|
+
output.print(' 2. Check your balance: actp balance');
|
|
604
|
+
output.print(' 3. Verify config match: actp diff');
|
|
605
|
+
}
|
|
606
|
+
// Suggest test payment on testnet
|
|
607
|
+
if (testnetTxHash && v4Config?.slug) {
|
|
608
|
+
output.print('');
|
|
609
|
+
output.print(` Try a test payment: actp pay agirails.app/a/${v4Config.slug} 5`);
|
|
610
|
+
}
|
|
317
611
|
// Warn if placeholder endpoint
|
|
318
|
-
if (!
|
|
612
|
+
if (!hasEndpoint) {
|
|
319
613
|
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');
|
|
614
|
+
output.warning('No endpoint set — your agent can\'t receive jobs yet.');
|
|
615
|
+
output.print(' Add "endpoint: https://your-agent.com/webhook" to AGIRAILS.md, then: actp publish');
|
|
324
616
|
}
|
|
325
617
|
}
|
|
326
618
|
catch (error) {
|
|
@@ -393,7 +685,7 @@ async function activateOnTestnet(projectRoot, configHash, cid, endpoint, service
|
|
|
393
685
|
// Already up-to-date on-chain — no activation needed
|
|
394
686
|
return undefined;
|
|
395
687
|
}
|
|
396
|
-
// Build activation calls
|
|
688
|
+
// Build activation calls (includes ERC-8004 identity mint for scenario A)
|
|
397
689
|
const activationCalls = buildActivationBatch({
|
|
398
690
|
scenario,
|
|
399
691
|
agentRegistryAddress: networkConfig.contracts.agentRegistry,
|
|
@@ -401,6 +693,7 @@ async function activateOnTestnet(projectRoot, configHash, cid, endpoint, service
|
|
|
401
693
|
configHash,
|
|
402
694
|
listed: true,
|
|
403
695
|
...(scenario === 'A' ? { endpoint, serviceDescriptors } : {}),
|
|
696
|
+
erc8004IdentityRegistry: networkConfig.contracts.erc8004IdentityRegistry,
|
|
404
697
|
});
|
|
405
698
|
// Always mint test USDC on testnet (SPEC: "always")
|
|
406
699
|
const mintCalls = buildTestnetMintBatch(networkConfig.contracts.usdc, smartWalletAddress, '1000000000');
|
|
@@ -416,6 +709,6 @@ async function activateOnTestnet(projectRoot, configHash, cid, endpoint, service
|
|
|
416
709
|
throw new Error(`Testnet activation UserOp failed: ${receipt.hash}`);
|
|
417
710
|
}
|
|
418
711
|
output.success('Minted 1,000 test USDC to Smart Wallet');
|
|
419
|
-
return receipt.hash;
|
|
712
|
+
return { txHash: receipt.hash, smartWalletAddress };
|
|
420
713
|
}
|
|
421
714
|
//# sourceMappingURL=publish.js.map
|