create-tacit-agent 0.1.0 → 0.1.1
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/dist/index.js +160 -112
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,12 +5,33 @@
|
|
|
5
5
|
var import_node_fs = require("fs");
|
|
6
6
|
var import_node_path = require("path");
|
|
7
7
|
var import_node_child_process = require("child_process");
|
|
8
|
-
var
|
|
8
|
+
var import_node_readline = require("readline");
|
|
9
9
|
var bold = (s) => `\x1B[1m${s}\x1B[0m`;
|
|
10
10
|
var green = (s) => `\x1B[32m${s}\x1B[0m`;
|
|
11
11
|
var cyan = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
12
12
|
var dim = (s) => `\x1B[2m${s}\x1B[0m`;
|
|
13
13
|
var red = (s) => `\x1B[31m${s}\x1B[0m`;
|
|
14
|
+
function ask(question) {
|
|
15
|
+
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
|
|
16
|
+
return new Promise((resolve2) => {
|
|
17
|
+
rl.question(question, (answer) => {
|
|
18
|
+
rl.close();
|
|
19
|
+
resolve2(answer.trim());
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function choose(question, options, defaultIndex = 0) {
|
|
24
|
+
console.log(question);
|
|
25
|
+
options.forEach((opt, i) => {
|
|
26
|
+
const marker = i === defaultIndex ? green("> ") : " ";
|
|
27
|
+
const label = i === defaultIndex ? bold(opt) : opt;
|
|
28
|
+
console.log(`${marker}${dim(`${i + 1})`)} ${label}`);
|
|
29
|
+
});
|
|
30
|
+
const answer = await ask(`
|
|
31
|
+
${dim(`Choice [${defaultIndex + 1}]:`)} `);
|
|
32
|
+
const idx = answer ? parseInt(answer, 10) - 1 : defaultIndex;
|
|
33
|
+
return options[idx] || options[defaultIndex];
|
|
34
|
+
}
|
|
14
35
|
var args = process.argv.slice(2);
|
|
15
36
|
var projectName = args[0];
|
|
16
37
|
if (!projectName || projectName === "--help" || projectName === "-h") {
|
|
@@ -40,135 +61,160 @@ console.log(`
|
|
|
40
61
|
${bold("Tacit Protocol")} ${dim("v0.1")}
|
|
41
62
|
${dim("The trust layer for the internet")}
|
|
42
63
|
`);
|
|
43
|
-
console.log(`Creating ${cyan(projectName)}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
console.log(`Creating ${cyan(projectName)}...
|
|
65
|
+
`);
|
|
66
|
+
async function main() {
|
|
67
|
+
const domains = ["professional", "dating", "commerce", "local-services", "learning"];
|
|
68
|
+
const domain = await choose(
|
|
69
|
+
` ${bold("What domain will your agent operate in?")}`,
|
|
70
|
+
domains,
|
|
71
|
+
0
|
|
72
|
+
);
|
|
73
|
+
console.log();
|
|
74
|
+
const seeking = await ask(` ${bold("What are you looking for?")} ${dim('(e.g., "collaboration on AI projects")')}
|
|
75
|
+
> `) || "meaningful connections";
|
|
76
|
+
console.log();
|
|
77
|
+
const offering = await ask(` ${bold("What do you offer?")} ${dim('(e.g., "full-stack engineering, 10yr experience")')}
|
|
78
|
+
> `) || "unique expertise";
|
|
79
|
+
console.log();
|
|
80
|
+
console.log(` ${green("Got it!")} Setting up your ${cyan(domain)} agent...
|
|
81
|
+
`);
|
|
82
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.join)(projectDir, "src"), { recursive: true });
|
|
83
|
+
(0, import_node_fs.writeFileSync)(
|
|
84
|
+
(0, import_node_path.join)(projectDir, "package.json"),
|
|
85
|
+
JSON.stringify(
|
|
86
|
+
{
|
|
87
|
+
name: projectName,
|
|
88
|
+
version: "0.1.0",
|
|
89
|
+
private: true,
|
|
90
|
+
type: "module",
|
|
91
|
+
scripts: {
|
|
92
|
+
start: "npx tsx src/agent.ts",
|
|
93
|
+
dev: "npx tsx --watch src/agent.ts"
|
|
94
|
+
},
|
|
95
|
+
dependencies: {
|
|
96
|
+
"@tacitprotocol/sdk": "^0.1.2"
|
|
97
|
+
},
|
|
98
|
+
devDependencies: {
|
|
99
|
+
typescript: "^5.4.0",
|
|
100
|
+
tsx: "^4.7.0",
|
|
101
|
+
"@types/node": "^20.11.0"
|
|
102
|
+
}
|
|
60
103
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
esModuleInterop: true,
|
|
82
|
-
skipLibCheck: true,
|
|
83
|
-
outDir: "./dist",
|
|
84
|
-
rootDir: "./src"
|
|
104
|
+
null,
|
|
105
|
+
2
|
|
106
|
+
) + "\n"
|
|
107
|
+
);
|
|
108
|
+
(0, import_node_fs.writeFileSync)(
|
|
109
|
+
(0, import_node_path.join)(projectDir, "tsconfig.json"),
|
|
110
|
+
JSON.stringify(
|
|
111
|
+
{
|
|
112
|
+
compilerOptions: {
|
|
113
|
+
target: "ES2022",
|
|
114
|
+
module: "ESNext",
|
|
115
|
+
moduleResolution: "bundler",
|
|
116
|
+
lib: ["ES2022", "DOM"],
|
|
117
|
+
strict: true,
|
|
118
|
+
esModuleInterop: true,
|
|
119
|
+
skipLibCheck: true,
|
|
120
|
+
outDir: "./dist",
|
|
121
|
+
rootDir: "./src"
|
|
122
|
+
},
|
|
123
|
+
include: ["src/**/*"]
|
|
85
124
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`/**
|
|
96
|
-
* ${projectName} \u2014 Tacit Protocol Agent
|
|
125
|
+
null,
|
|
126
|
+
2
|
|
127
|
+
) + "\n"
|
|
128
|
+
);
|
|
129
|
+
const esc = (s) => s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
130
|
+
(0, import_node_fs.writeFileSync)(
|
|
131
|
+
(0, import_node_path.join)(projectDir, "src", "agent.ts"),
|
|
132
|
+
`/**
|
|
133
|
+
* ${esc(projectName)} \u2014 Tacit Protocol Agent
|
|
97
134
|
*
|
|
98
135
|
* Your AI agent that verifies identity, prevents fraud,
|
|
99
136
|
* and brokers trusted introductions with cryptographic proof.
|
|
100
137
|
*/
|
|
101
138
|
|
|
102
|
-
import {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
MatchScorer,
|
|
106
|
-
} from '@tacitprotocol/sdk';
|
|
139
|
+
import { TacitAgent, IntentBuilder } from '@tacitprotocol/sdk';
|
|
140
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
141
|
+
import { join } from 'node:path';
|
|
107
142
|
|
|
108
143
|
async function main() {
|
|
109
|
-
console.log('
|
|
144
|
+
console.log('\\x1b[1mInitializing Tacit agent...\\x1b[0m\\n');
|
|
110
145
|
|
|
111
|
-
// Create
|
|
146
|
+
// Create agent with cryptographic identity
|
|
112
147
|
const agent = await TacitAgent.create({
|
|
113
|
-
domain: '
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
introductionStyle: 'professional',
|
|
117
|
-
},
|
|
148
|
+
domain: '${esc(domain)}',
|
|
149
|
+
seeking: '${esc(seeking)}',
|
|
150
|
+
offering: '${esc(offering)}',
|
|
118
151
|
});
|
|
119
152
|
|
|
120
|
-
|
|
121
|
-
|
|
153
|
+
// Persist identity to disk
|
|
154
|
+
const idDir = join(process.cwd(), '.tacit');
|
|
155
|
+
const idPath = join(idDir, 'identity.json');
|
|
156
|
+
|
|
157
|
+
if (existsSync(idPath)) {
|
|
158
|
+
console.log(\` \\x1b[2mLoaded identity:\\x1b[0m \${agent.did}\`);
|
|
159
|
+
} else {
|
|
160
|
+
mkdirSync(idDir, { recursive: true });
|
|
161
|
+
writeFileSync(idPath, JSON.stringify({ did: agent.did, created: new Date().toISOString() }, null, 2));
|
|
162
|
+
console.log(\` \\x1b[32m+\\x1b[0m Created identity: \\x1b[36m\${agent.did}\\x1b[0m\`);
|
|
163
|
+
}
|
|
122
164
|
|
|
123
165
|
// Build and publish an intent
|
|
124
166
|
const intent = new IntentBuilder(agent.did)
|
|
125
167
|
.type('introduction')
|
|
126
|
-
.domain('
|
|
127
|
-
.seeking({
|
|
128
|
-
|
|
129
|
-
skills: ['ai', 'distributed-systems'],
|
|
130
|
-
})
|
|
131
|
-
.context({
|
|
132
|
-
offering: 'Your expertise here',
|
|
133
|
-
urgency: 'moderate',
|
|
134
|
-
})
|
|
168
|
+
.domain('${esc(domain)}')
|
|
169
|
+
.seeking({ what: '${esc(seeking)}' })
|
|
170
|
+
.context({ offering: '${esc(offering)}' })
|
|
135
171
|
.minAuthenticity(50)
|
|
136
172
|
.build();
|
|
137
173
|
|
|
138
|
-
console.log(\`Intent published: \${intent.id}\`);
|
|
174
|
+
console.log(\` \\x1b[32m+\\x1b[0m Intent published: \\x1b[2m\${intent.id}\\x1b[0m\`);
|
|
139
175
|
|
|
140
176
|
// Listen for matches
|
|
141
177
|
agent.on('match', async (event) => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
console.log(
|
|
178
|
+
const match = (event as any).match;
|
|
179
|
+
const score = match?.score;
|
|
180
|
+
console.log();
|
|
181
|
+
console.log(' \\x1b[32m\\u250C\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2510\\x1b[0m');
|
|
182
|
+
console.log(' \\x1b[32m\\u2502\\x1b[0m \\x1b[1m\\x1b[32mMatch Found!\\x1b[0m \\x1b[32m\\u2502\\x1b[0m');
|
|
183
|
+
console.log(\` \\x1b[32m\\u2502\\x1b[0m Score: \\x1b[1m\${score?.overall}/100\\x1b[0m \\x1b[32m\\u2502\\x1b[0m\`);
|
|
184
|
+
console.log(\` \\x1b[32m\\u2502\\x1b[0m Intent alignment: \${(score?.breakdown?.intentAlignment * 100).toFixed(0)}% \\x1b[32m\\u2502\\x1b[0m\`);
|
|
185
|
+
console.log(\` \\x1b[32m\\u2502\\x1b[0m Domain fit: \${(score?.breakdown?.domainFit * 100).toFixed(0)}% \\x1b[32m\\u2502\\x1b[0m\`);
|
|
186
|
+
console.log(\` \\x1b[32m\\u2502\\x1b[0m Authenticity: \\x1b[32mverified\\x1b[0m \\x1b[32m\\u2502\\x1b[0m\`);
|
|
187
|
+
console.log(' \\x1b[32m\\u2514\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2518\\x1b[0m');
|
|
188
|
+
console.log();
|
|
189
|
+
console.log(' \\x1b[2mThis is a simulated match. Deploy a relay node to match with real agents.\\x1b[0m');
|
|
190
|
+
console.log(' \\x1b[2mLearn more: https://github.com/tacitprotocol/tacit\\x1b[0m');
|
|
191
|
+
console.log();
|
|
192
|
+
process.exit(0);
|
|
148
193
|
});
|
|
149
194
|
|
|
150
195
|
console.log();
|
|
151
|
-
console.log('
|
|
152
|
-
console.log('
|
|
196
|
+
console.log(' \\x1b[1mAgent is running.\\x1b[0m Listening for matches...');
|
|
197
|
+
console.log(' \\x1b[2mPress Ctrl+C to stop.\\x1b[0m\\n');
|
|
153
198
|
|
|
154
|
-
// Connect
|
|
155
|
-
await agent.connect();
|
|
199
|
+
// Connect in demo mode (simulates a match after ~3s)
|
|
200
|
+
await agent.connect({ demo: true });
|
|
156
201
|
}
|
|
157
202
|
|
|
158
203
|
main().catch(console.error);
|
|
159
204
|
`
|
|
160
|
-
);
|
|
161
|
-
(0, import_node_fs.writeFileSync)(
|
|
162
|
-
|
|
163
|
-
|
|
205
|
+
);
|
|
206
|
+
(0, import_node_fs.writeFileSync)(
|
|
207
|
+
(0, import_node_path.join)(projectDir, ".gitignore"),
|
|
208
|
+
`node_modules/
|
|
164
209
|
dist/
|
|
165
210
|
.env
|
|
166
211
|
*.local
|
|
212
|
+
.tacit/
|
|
167
213
|
`
|
|
168
|
-
);
|
|
169
|
-
(0, import_node_fs.writeFileSync)(
|
|
170
|
-
|
|
171
|
-
|
|
214
|
+
);
|
|
215
|
+
(0, import_node_fs.writeFileSync)(
|
|
216
|
+
(0, import_node_path.join)(projectDir, "README.md"),
|
|
217
|
+
`# ${projectName}
|
|
172
218
|
|
|
173
219
|
A [Tacit Protocol](https://tacitprotocol.com) agent \u2014 verify identity, prevent fraud, and broker trusted introductions.
|
|
174
220
|
|
|
@@ -195,22 +241,24 @@ Edit \`src/agent.ts\` to configure your agent's domain, intent, and preferences.
|
|
|
195
241
|
- [SDK Reference](https://www.npmjs.com/package/@tacitprotocol/sdk)
|
|
196
242
|
- [Protocol Spec](https://github.com/tacitprotocol/tacit/blob/main/docs/PROTOCOL_SPEC.md)
|
|
197
243
|
`
|
|
198
|
-
);
|
|
199
|
-
console.log(`${dim("Installing dependencies...")}`);
|
|
200
|
-
console.log();
|
|
201
|
-
try {
|
|
202
|
-
|
|
203
|
-
} catch {
|
|
244
|
+
);
|
|
245
|
+
console.log(`${dim("Installing dependencies...")}`);
|
|
246
|
+
console.log();
|
|
247
|
+
try {
|
|
248
|
+
(0, import_node_child_process.execSync)("npm install", { cwd: projectDir, stdio: "inherit" });
|
|
249
|
+
} catch {
|
|
250
|
+
console.log();
|
|
251
|
+
console.log(dim("npm install failed \u2014 you can run it manually:"));
|
|
252
|
+
console.log(` cd ${projectName} && npm install`);
|
|
253
|
+
}
|
|
254
|
+
console.log();
|
|
255
|
+
console.log(green("Done!") + ` Your Tacit agent is ready.`);
|
|
256
|
+
console.log();
|
|
257
|
+
console.log(` ${bold("cd")} ${cyan(projectName)}`);
|
|
258
|
+
console.log(` ${bold("npm start")}`);
|
|
259
|
+
console.log();
|
|
260
|
+
console.log(dim("Your agent will create a cryptographic identity, publish an intent,"));
|
|
261
|
+
console.log(dim("and show a simulated match in ~3 seconds. Edit src/agent.ts to customize."));
|
|
204
262
|
console.log();
|
|
205
|
-
console.log(dim("npm install failed \u2014 you can run it manually:"));
|
|
206
|
-
console.log(` cd ${projectName} && npm install`);
|
|
207
263
|
}
|
|
208
|
-
console.
|
|
209
|
-
console.log(green("Done!") + ` Your Tacit agent is ready.`);
|
|
210
|
-
console.log();
|
|
211
|
-
console.log(` ${bold("cd")} ${cyan(projectName)}`);
|
|
212
|
-
console.log(` ${bold("npm start")}`);
|
|
213
|
-
console.log();
|
|
214
|
-
console.log(dim("Your agent will create a cryptographic identity and start listening for matches."));
|
|
215
|
-
console.log(dim("Edit src/agent.ts to customize your intent and preferences."));
|
|
216
|
-
console.log();
|
|
264
|
+
main().catch(console.error);
|