agentosity 0.2.1 → 0.2.3
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/package.json +1 -1
- package/src/index.js +65 -34
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -25,10 +25,9 @@ export async function main(argv) {
|
|
|
25
25
|
default:
|
|
26
26
|
console.log(`agentosity — AI-native is a number now.
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
npx agentosity
|
|
30
|
-
|
|
31
|
-
(无浏览器环境:login <邮箱> 收验证码,再 login <邮箱> <验证码>)
|
|
28
|
+
一步开始:
|
|
29
|
+
npx agentosity init 登录 → 网页选公司 → 自动接入所有 harness,全程引导
|
|
30
|
+
(无浏览器环境:login <邮箱> 收验证码登录后,init "<公司名>")
|
|
32
31
|
|
|
33
32
|
其他:
|
|
34
33
|
npx agentosity radar 进程雷达:补录本机未接入 MCP 的 Agent 会话(常驻)
|
|
@@ -39,38 +38,66 @@ export async function main(argv) {
|
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
async function init(
|
|
43
|
-
|
|
44
|
-
if (
|
|
45
|
-
console.error(
|
|
46
|
-
npx agentosity login <邮箱> # 收验证码
|
|
47
|
-
npx agentosity login <邮箱> <验证码> # 登录
|
|
48
|
-
然后再跑 init。`);
|
|
41
|
+
async function init(companyArg) {
|
|
42
|
+
// 防占位符事故:范例文本被原样粘贴执行
|
|
43
|
+
if (companyArg && /你的公司名|公司名|your ?company|company ?name/i.test(companyArg)) {
|
|
44
|
+
console.error("「" + companyArg + "」看起来是示例占位符,不是真实公司名。直接跑 npx agentosity init(不带参数),公司在网页上选。");
|
|
49
45
|
process.exit(1);
|
|
50
46
|
}
|
|
51
|
-
if (!company) {
|
|
52
|
-
console.error('用法:npx agentosity init "你的公司名"');
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
saveConfig({ company });
|
|
56
47
|
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
else console.log(`✅ 公司已绑定:${created.name ?? company}`);
|
|
48
|
+
// 1. 登录(没有就当场走浏览器授权)
|
|
49
|
+
let cfg = loadConfig();
|
|
50
|
+
if (!cfg.accessToken) {
|
|
51
|
+
await browserLogin(); // 失败会自行退出
|
|
52
|
+
cfg = loadConfig();
|
|
63
53
|
} else {
|
|
64
|
-
console.log(
|
|
54
|
+
console.log(`✓ 已登录 ${cfg.email ?? ""}`);
|
|
65
55
|
}
|
|
66
56
|
|
|
67
|
-
//
|
|
57
|
+
// 2. 公司绑定(统一收口网页;--company 仅供无浏览器环境)
|
|
58
|
+
// 拿"明确答复"才做判断:网络抖动/服务瞬时失败(返回 error)一律重试,绝不误判成"未绑定"
|
|
59
|
+
const fetchProfileDefinitive = async (attempts = 5) => {
|
|
60
|
+
for (let i = 0; i < attempts; i++) {
|
|
61
|
+
const p = await get(`/api/profile?device=${cfg.deviceId ?? ""}`);
|
|
62
|
+
if (p && "company" in p) return p;
|
|
63
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
};
|
|
67
|
+
let prof = await fetchProfileDefinitive();
|
|
68
|
+
if (prof === null) {
|
|
69
|
+
console.error("服务暂时不可达,稍后重跑 npx agentosity init");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
if (!prof?.company && companyArg) {
|
|
73
|
+
const created = await post("/api/companies", { name: companyArg });
|
|
74
|
+
if (created?.id) await post("/api/profile", { companyId: created.id }, { method: "PUT" });
|
|
75
|
+
prof = await get(`/api/profile?device=${cfg.deviceId ?? ""}`);
|
|
76
|
+
}
|
|
77
|
+
if (!prof?.company) {
|
|
78
|
+
const url = `${apiBase()}/checkin`;
|
|
79
|
+
console.log(`在网页上选择你的公司…\n打不开就手动访问:${url}`);
|
|
80
|
+
await openBrowser(url);
|
|
81
|
+
for (let i = 0; i < 150 && !prof?.company; i++) {
|
|
82
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
83
|
+
const p = await get(`/api/profile?device=${cfg.deviceId ?? ""}`);
|
|
84
|
+
if (p && "company" in p) prof = p; // 错误答复不覆盖,继续等
|
|
85
|
+
}
|
|
86
|
+
if (!prof?.company) {
|
|
87
|
+
console.error("等待超时。在网页上绑定公司后,重新跑 npx agentosity init");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
console.log(`✓ 公司:${prof.company.name}`);
|
|
92
|
+
saveConfig({ company: prof.company.name }); // 本地缓存,考勤/雷达归属用
|
|
93
|
+
|
|
94
|
+
// 3. 全家 harness 自动接入
|
|
68
95
|
console.log("\n接入 Agent 考勤:");
|
|
69
96
|
const results = installAllHarnesses();
|
|
70
97
|
console.log(formatInstallResults(results) || " (未发现已安装的 harness)");
|
|
71
98
|
|
|
72
99
|
console.log(`
|
|
73
|
-
|
|
100
|
+
✅ 完成。从现在起,新开的 Agent 会话会自动考勤——模型零参与,只上报时长,不读任何内容。
|
|
74
101
|
已开着的老会话不会被追踪(配置只对新会话生效),要收编它们:npx agentosity radar
|
|
75
102
|
|
|
76
103
|
看榜:${apiBase()}/agents`);
|
|
@@ -99,6 +126,18 @@ async function login(email, code) {
|
|
|
99
126
|
}
|
|
100
127
|
}
|
|
101
128
|
|
|
129
|
+
async function openBrowser(url) {
|
|
130
|
+
try {
|
|
131
|
+
const { spawn } = await import("node:child_process");
|
|
132
|
+
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
133
|
+
const child = spawn(opener, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" });
|
|
134
|
+
child.on("error", () => {});
|
|
135
|
+
child.unref();
|
|
136
|
+
} catch {
|
|
137
|
+
/* 打不开浏览器就靠打印的 URL */
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
102
141
|
async function browserLogin() {
|
|
103
142
|
const cfg = saveConfig({}); // 确保 deviceId 存在
|
|
104
143
|
const start = await post("/api/device/start", {});
|
|
@@ -108,15 +147,7 @@ async function browserLogin() {
|
|
|
108
147
|
}
|
|
109
148
|
const url = `${apiBase()}/login?device=${start.code}`;
|
|
110
149
|
console.log(`在浏览器里完成登录…\n打不开就手动访问:${url}`);
|
|
111
|
-
|
|
112
|
-
const { spawn } = await import("node:child_process");
|
|
113
|
-
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
114
|
-
const child = spawn(opener, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" });
|
|
115
|
-
child.on("error", () => {});
|
|
116
|
-
child.unref();
|
|
117
|
-
} catch {
|
|
118
|
-
/* 打不开浏览器就靠上面打印的 URL */
|
|
119
|
-
}
|
|
150
|
+
await openBrowser(url);
|
|
120
151
|
for (let i = 0; i < 150; i++) {
|
|
121
152
|
await new Promise((r) => setTimeout(r, 2000));
|
|
122
153
|
const poll = await post(`/api/device/poll?code=${start.code}`, undefined, { method: "GET" });
|