@mazjq/zhiro 0.0.0-stage → 0.2.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.
@@ -0,0 +1,44 @@
1
+ import {
2
+ claudeSpec,
3
+ nodeArgs
4
+ } from "./chunk-VOUILWMI.js";
5
+ import {
6
+ __name
7
+ } from "./chunk-2SSYR7VW.js";
8
+
9
+ // apps/daemon/src/agent/backends/acp.ts
10
+ import { existsSync, writeFileSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ var jobosTool = /* @__PURE__ */ __name((title) => {
13
+ const m = /(?:^|mcp__|\b)jobos(?:__|[/:.\s]+)([A-Za-z][\w.]*)/i.exec(title);
14
+ return m ? m[1].replace(/_/g, ".") : null;
15
+ }, "jobosTool");
16
+ var nodeFitsDsh = /* @__PURE__ */ __name((v = process.versions.node) => {
17
+ const [a, b] = v.split(".").map(Number);
18
+ return a > 22 || a === 22 && b >= 15;
19
+ }, "nodeFitsDsh");
20
+ function dshLauncher() {
21
+ const bin = process.env.JOBOS_DSH_CLI ?? join(process.env.APPDATA ?? join(process.env.HOME ?? "", ".npm-global"), "npm", "node_modules", "@deepseek-ai", "dsh", "lib", "bin.js");
22
+ return existsSync(bin) && nodeFitsDsh() ? { cmd: process.execPath, args: [bin, "--profile", "acp"] } : null;
23
+ }
24
+ __name(dshLauncher, "dshLauncher");
25
+ function acpSpec(name, agent) {
26
+ return {
27
+ name,
28
+ launcher: /* @__PURE__ */ __name(() => agent() ? { cmd: process.execPath, args: nodeArgs("acp-bridge") } : null, "launcher"),
29
+ argv: /* @__PURE__ */ __name(({ dir, sessionId, rulesFile, mcp, prompt }) => {
30
+ const a = agent();
31
+ const mcpFile = join(dir, "mcp.json");
32
+ writeFileSync(mcpFile, JSON.stringify({ mcpServers: { jobos: mcp } }), "utf8");
33
+ return { args: ["--mcp", mcpFile, "--rules", rulesFile, ...sessionId ? ["--resume", sessionId] : [], "--", a.cmd, ...a.args], stdin: prompt };
34
+ }, "argv"),
35
+ parser: claudeSpec.parser
36
+ };
37
+ }
38
+ __name(acpSpec, "acpSpec");
39
+ var dshSpec = acpSpec("dsh", dshLauncher);
40
+
41
+ export {
42
+ jobosTool,
43
+ dshSpec
44
+ };
@@ -0,0 +1,131 @@
1
+ import {
2
+ WorkflowEngine
3
+ } from "./chunk-GRZ4VMSO.js";
4
+ import {
5
+ SYNC_REASONS,
6
+ addSource,
7
+ httpContext,
8
+ listSources,
9
+ previewSource,
10
+ reasonOf,
11
+ runSource,
12
+ scheduleSources,
13
+ sourceFor,
14
+ sourceScan
15
+ } from "./chunk-4UWMDKMH.js";
16
+ import {
17
+ openDb
18
+ } from "./chunk-4EPNDXRS.js";
19
+ import {
20
+ clearConfigTemps,
21
+ dbPath,
22
+ loadConfig
23
+ } from "./chunk-4JJEOOW2.js";
24
+ import {
25
+ VaultBusy,
26
+ __name,
27
+ lockVault
28
+ } from "./chunk-2SSYR7VW.js";
29
+
30
+ // apps/daemon/src/data/cli.ts
31
+ var [cmd = "", ...args] = process.argv.slice(2);
32
+ var flag = /* @__PURE__ */ __name((name) => {
33
+ const i = args.indexOf(`--${name}`);
34
+ return i >= 0 ? args.splice(i, 2)[1] : void 0;
35
+ }, "flag");
36
+ var say = /* @__PURE__ */ __name((s) => console.log(s), "say");
37
+ var why = /* @__PURE__ */ __name((error) => `${SYNC_REASONS[reasonOf(error)]}(${error.slice(0, 200)})`, "why");
38
+ function open() {
39
+ const config = loadConfig();
40
+ const db = openDb(dbPath(config.vault));
41
+ return { db, vault: config.vault, sources: config.sources, workflows: new WorkflowEngine(db) };
42
+ }
43
+ __name(open, "open");
44
+ async function locked(who) {
45
+ const ctx = open();
46
+ try {
47
+ await lockVault(ctx.vault, who);
48
+ clearConfigTemps(ctx.vault);
49
+ } catch (e) {
50
+ if (e instanceof VaultBusy) {
51
+ console.error(`${e.message}
52
+ 先停掉它,或者改用它的工具(source.add / scan.run)。`);
53
+ process.exit(2);
54
+ }
55
+ throw e;
56
+ }
57
+ return ctx;
58
+ }
59
+ __name(locked, "locked");
60
+ var result = /* @__PURE__ */ __name((name, r) => say(r.ok ? ` ${name}:读到 ${r.result.received} 条,新增岗位 ${r.result.positionsNew},已有 ${r.result.positionsSeen},关闭 ${r.result.positionsClosed}` : ` ${name}:没读成 — ${why(r.error)}`), "result");
61
+ async function main() {
62
+ if (cmd === "probe") {
63
+ const url = args[0];
64
+ if (!url) throw new Error("用法:data probe <链接或文件>");
65
+ const src = sourceFor(url);
66
+ if (!src?.fetch) throw new Error(`还认不出这个链接是哪种招聘站或表格:${url}`);
67
+ say(`读取器:${src.name}(${src.id})`);
68
+ if (src.table) {
69
+ const pv = await previewSource({ db: void 0, vault: "", sources: [] }, { url, cohort: flag("cohort") });
70
+ say(`表头:${pv.headers.join("、")}`);
71
+ say(`列对应:${Object.entries(pv.columns).map(([f, h]) => `${pv.fields.find((x) => x.field === f)?.label}←${h}`).join(",") || "(没认出)"}`);
72
+ say(`${pv.rows} 行 → ${pv.posts} 个岗位,${pv.companies} 家公司${pv.problem ? `
73
+ 问题:${pv.problem}` : ""}`);
74
+ for (const l of pv.sample) say(`- ${l.company} | ${l.title} | ${l.cities.join(";")} | ${l.deadline || "-"} | ${l.url}`);
75
+ return;
76
+ }
77
+ const t0 = Date.now();
78
+ const listings = await src.fetch({ id: "probe", source: src.id, url, name: flag("name"), maxPages: 3, detailCap: 3 }, httpContext((m) => say(`[log] ${m}`)));
79
+ say(`${listings.length} 个岗位,用时 ${Date.now() - t0} ms`);
80
+ for (const l of listings.slice(0, 6)) say(`- ${l.title} | ${l.orgUnit ?? ""} | ${l.locations.join(";")} | ${l.degreeReq ?? "?"} | ${l.validThrough?.slice(0, 10) ?? "-"}`);
81
+ return;
82
+ }
83
+ if (cmd === "list") {
84
+ const { configured } = listSources(open());
85
+ if (!configured.length) say("还没有订阅。data add <链接或文件> 加一个。");
86
+ for (const c of configured) say(`${c.id} ${c.source} 每 ${c.everyHours} 小时 ${c.lastRun ? c.lastRun.error ? `上次没读成:${SYNC_REASONS[c.health.reason] ?? c.health.reason}` : `上次 ${c.lastRun.at.slice(0, 16)} 读到 ${c.lastRun.found} 条` : "还没拉过"} ${c.name}`);
87
+ return;
88
+ }
89
+ if (cmd === "add") {
90
+ const url = args.find((a) => !a.startsWith("--"));
91
+ const name = flag("name"), cohort = flag("cohort");
92
+ if (!url) throw new Error("用法:data add <链接或文件> [--name 名字] [--cohort 2027届]");
93
+ const ctx = await locked("data add");
94
+ const pv = await previewSource(ctx, { url, cohort });
95
+ if (pv.problem) throw new Error(pv.problem);
96
+ const { id } = addSource(ctx, { url, name: name ?? pv.name, cohort, ...pv.table ? { columns: pv.columns } : {} });
97
+ say(`已订阅 ${id}(${pv.name})${pv.table ? `,列对应:${Object.entries(pv.columns).map(([f, h]) => `${f}←${h}`).join(",")}` : ""}`);
98
+ result(id, await runSource(ctx, id));
99
+ return;
100
+ }
101
+ if (cmd === "sync") {
102
+ const ctx = await locked("data sync");
103
+ const ids = args[0] ? [args[0]] : ctx.sources.filter((c) => c.enabled !== false).map((c) => c.id);
104
+ if (!ids.length) say("还没有订阅。");
105
+ for (const id of ids) result(id, await runSource(ctx, id, { quiet: true }));
106
+ return;
107
+ }
108
+ if (cmd === "watch") {
109
+ const ctx = await locked("data watch");
110
+ ctx.workflows.register(sourceScan(ctx));
111
+ ctx.onSourcesChanged = () => {
112
+ scheduleSources(ctx);
113
+ };
114
+ say(`data watch:${scheduleSources(ctx)} 个订阅按各自的周期拉取(数据目录 ${ctx.vault})。Ctrl+C 结束。`);
115
+ ctx.workflows.startPolling();
116
+ process.on("SIGINT", () => {
117
+ ctx.workflows.stopPolling();
118
+ ctx.db.close();
119
+ process.exit(0);
120
+ });
121
+ return;
122
+ }
123
+ say("用法:data probe <链接或文件> | add <链接或文件> [--name 名字] [--cohort 届次] | list | sync [订阅 id] | watch");
124
+ process.exitCode = cmd ? 1 : 0;
125
+ }
126
+ __name(main, "main");
127
+ main().catch((e) => {
128
+ const m = /^([A-Z_]{4,}): ([\s\S]*)$/.exec(String(e?.message ?? e));
129
+ console.error(m ? m[2] : String(e?.message ?? e));
130
+ process.exit(1);
131
+ });
@@ -0,0 +1,75 @@
1
+ import {
2
+ createLlm
3
+ } from "./chunk-7IV2NG2D.js";
4
+ import "./chunk-ZKD2BKN3.js";
5
+ import "./chunk-4UWMDKMH.js";
6
+ import "./chunk-4EPNDXRS.js";
7
+ import {
8
+ loadConfig
9
+ } from "./chunk-4JJEOOW2.js";
10
+ import {
11
+ __name
12
+ } from "./chunk-2SSYR7VW.js";
13
+
14
+ // apps/daemon/src/cli/login.ts
15
+ import { createInterface } from "node:readline/promises";
16
+ import { stdin, stdout } from "node:process";
17
+ import { spawn } from "node:child_process";
18
+ var [providerArg, typeArg] = process.argv.slice(2);
19
+ var config = loadConfig();
20
+ var llm = createLlm(config);
21
+ if (!providerArg || providerArg === "--status") {
22
+ const s = await llm.status();
23
+ console.log(`configured: ${s.provider}/${s.model} loggedIn=${s.loggedIn}`);
24
+ console.log(`stored credentials: ${s.credentials.map((c) => `${c.providerId}(${c.type})`).join(", ") || "(none)"}`);
25
+ console.log(`providers: ${llm.models.getProviders().map((p) => p.id).join(" ")}`);
26
+ process.exit(0);
27
+ }
28
+ var provider = llm.models.getProvider(providerArg);
29
+ if (!provider) {
30
+ console.error(`unknown provider ${providerArg}`);
31
+ process.exit(1);
32
+ }
33
+ var kinds = Object.keys(provider.auth ?? {});
34
+ var type = typeArg ?? (kinds.includes("oauth") ? "oauth" : "api_key");
35
+ console.log(`login ${providerArg} via ${type} (supported: ${kinds.join(", ")})`);
36
+ var rl = createInterface({ input: stdin, output: stdout });
37
+ var open = /* @__PURE__ */ __name((url) => {
38
+ const [bin, args] = process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : process.platform === "darwin" ? ["open", [url]] : ["xdg-open", [url]];
39
+ try {
40
+ spawn(bin, args, { stdio: "ignore", detached: true }).unref();
41
+ } catch {
42
+ }
43
+ }, "open");
44
+ try {
45
+ const cred = await llm.models.login(providerArg, type, {
46
+ async prompt(p) {
47
+ if (p.type === "select") {
48
+ console.log(p.message);
49
+ p.options.forEach((o, i) => console.log(` ${i + 1}. ${o.label}${o.description ? " — " + o.description : ""}`));
50
+ const a = await rl.question("> ");
51
+ return p.options[Number(a) - 1]?.id ?? a;
52
+ }
53
+ return (await rl.question(`${p.message}${p.placeholder ? ` (${p.placeholder})` : ""}
54
+ > `)).trim();
55
+ },
56
+ notify(e) {
57
+ if (e.type === "auth_url") {
58
+ console.log(`打开浏览器登录:${e.url}${e.instructions ? "\n" + e.instructions : ""}`);
59
+ open(e.url);
60
+ } else if (e.type === "device_code") {
61
+ console.log(`访问 ${e.verificationUri} 并输入代码:${e.userCode}`);
62
+ open(e.verificationUri);
63
+ } else if (e.type === "info") console.log(e.message);
64
+ else if (e.type === "progress") console.log(`… ${e.message}`);
65
+ }
66
+ });
67
+ console.log(`✓ 已保存 ${providerArg} 凭据(${cred.type})到 vault/config/credentials.json`);
68
+ const s = await llm.status();
69
+ console.log(`configured model ${s.provider}/${s.model} loggedIn=${s.loggedIn}`);
70
+ } catch (e) {
71
+ console.error(`登录失败:${e?.message ?? e}`);
72
+ process.exit(1);
73
+ } finally {
74
+ rl.close();
75
+ }