@duetso/agent 0.1.202 → 0.2.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 +3 -6
- package/dist/package.json +1 -1
- package/dist/src/cli/help.d.ts.map +1 -1
- package/dist/src/cli/help.js +15 -21
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/login.d.ts +2 -3
- package/dist/src/cli/login.d.ts.map +1 -1
- package/dist/src/cli/login.js +17 -32
- package/dist/src/cli/login.js.map +1 -1
- package/dist/src/cli/model-gateway.d.ts +3 -3
- package/dist/src/cli/model-gateway.js +3 -3
- package/dist/src/cli/rpc.d.ts +0 -2
- package/dist/src/cli/rpc.d.ts.map +1 -1
- package/dist/src/cli/rpc.js +1 -16
- package/dist/src/cli/rpc.js.map +1 -1
- package/dist/src/cli/run.d.ts.map +1 -1
- package/dist/src/cli/run.js +1 -15
- package/dist/src/cli/run.js.map +1 -1
- package/dist/src/cli/send-feedback.d.ts +1 -1
- package/dist/src/cli/send-feedback.js +1 -1
- package/dist/src/cli/train.js +1 -1
- package/dist/src/cli/train.js.map +1 -1
- package/dist/src/lib/duet-api-url.d.ts +9 -0
- package/dist/src/lib/duet-api-url.d.ts.map +1 -0
- package/dist/src/lib/duet-api-url.js +18 -0
- package/dist/src/lib/duet-api-url.js.map +1 -0
- package/dist/src/lib/feedback.d.ts +1 -1
- package/dist/src/lib/feedback.js +4 -4
- package/dist/src/lib/feedback.js.map +1 -1
- package/dist/src/lib/login.d.ts +24 -21
- package/dist/src/lib/login.d.ts.map +1 -1
- package/dist/src/lib/login.js +50 -114
- package/dist/src/lib/login.js.map +1 -1
- package/dist/src/memory/embedding.d.ts +20 -15
- package/dist/src/memory/embedding.d.ts.map +1 -1
- package/dist/src/memory/embedding.js +26 -20
- package/dist/src/memory/embedding.js.map +1 -1
- package/dist/src/model-resolution/duet-gateway.d.ts +4 -3
- package/dist/src/model-resolution/duet-gateway.d.ts.map +1 -1
- package/dist/src/model-resolution/duet-gateway.js +12 -6
- package/dist/src/model-resolution/duet-gateway.js.map +1 -1
- package/dist/src/tui/step-renderer.d.ts +4 -0
- package/dist/src/tui/step-renderer.d.ts.map +1 -1
- package/dist/src/tui/step-renderer.js +41 -37
- package/dist/src/tui/step-renderer.js.map +1 -1
- package/dist/src/tui/tool-formatters.d.ts +2 -2
- package/dist/src/tui/tool-formatters.d.ts.map +1 -1
- package/dist/src/turn-runner/agent-events.d.ts +12 -1
- package/dist/src/turn-runner/agent-events.d.ts.map +1 -1
- package/dist/src/turn-runner/agent-events.js +60 -42
- package/dist/src/turn-runner/agent-events.js.map +1 -1
- package/dist/src/turn-runner/turn-runner.d.ts +2 -0
- package/dist/src/turn-runner/turn-runner.d.ts.map +1 -1
- package/dist/src/turn-runner/turn-runner.js +4 -2
- package/dist/src/turn-runner/turn-runner.js.map +1 -1
- package/dist/src/types/protocol.d.ts +22 -3
- package/dist/src/types/protocol.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/src/lib/duet-app-url.d.ts +0 -10
- package/dist/src/lib/duet-app-url.d.ts.map +0 -1
- package/dist/src/lib/duet-app-url.js +0 -19
- package/dist/src/lib/duet-app-url.js.map +0 -1
- package/dist/src/lib/sync-skills.d.ts +0 -54
- package/dist/src/lib/sync-skills.d.ts.map +0 -1
- package/dist/src/lib/sync-skills.js +0 -215
- package/dist/src/lib/sync-skills.js.map +0 -1
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { dirname, join, resolve } from "node:path";
|
|
5
|
-
import { resolveDuetAppBaseUrl } from "./duet-app-url.js";
|
|
6
|
-
/**
|
|
7
|
-
* Mirror of the chat-app default-skill sync, kept byte-identical so the
|
|
8
|
-
* server's hash and the CLI's local hash match. The chat-app endpoint
|
|
9
|
-
* already renders placeholders against the caller's org; the CLI just
|
|
10
|
-
* verifies the returned hash and dumps the files into ~/.duet/skills/,
|
|
11
|
-
* which the turn runner reads directly.
|
|
12
|
-
*
|
|
13
|
-
* The hash is used as a conditional GET ETag: we send the on-disk hash via
|
|
14
|
-
* `If-None-Match` and the server returns `304 Not Modified` when it still
|
|
15
|
-
* matches, so a no-op `duet login` never transfers the payload at all.
|
|
16
|
-
*/
|
|
17
|
-
const DEFAULT_SKILLS_DIR = join(homedir(), ".duet", "skills");
|
|
18
|
-
const DEFAULT_SKILLS_HASH_FILE = join(homedir(), ".duet", ".skills-hash");
|
|
19
|
-
export async function fetchDefaultSkills(options) {
|
|
20
|
-
const baseUrl = options.appBaseUrl ?? resolveDuetAppBaseUrl();
|
|
21
|
-
const fetchFn = options.fetchFn ?? fetch;
|
|
22
|
-
const headers = {
|
|
23
|
-
Authorization: `Bearer ${options.apiKey}`,
|
|
24
|
-
};
|
|
25
|
-
if (options.knownHash) {
|
|
26
|
-
headers["If-None-Match"] = `"${options.knownHash}"`;
|
|
27
|
-
}
|
|
28
|
-
const response = await fetchFn(`${baseUrl}/api/v1/cli/skills`, { headers });
|
|
29
|
-
if (response.status === 304) {
|
|
30
|
-
if (!options.knownHash) {
|
|
31
|
-
throw new Error("Server returned 304 without a known hash to compare");
|
|
32
|
-
}
|
|
33
|
-
return { status: "not-modified", hash: options.knownHash };
|
|
34
|
-
}
|
|
35
|
-
if (!response.ok) {
|
|
36
|
-
const detail = (await safeReadText(response)).slice(0, 256);
|
|
37
|
-
throw new Error(`Failed to fetch default skills: ${response.status} ${response.statusText}${detail ? ` — ${detail}` : ""}`);
|
|
38
|
-
}
|
|
39
|
-
const etag = parseSkillHashEtag(response.headers.get("ETag"));
|
|
40
|
-
if (!etag) {
|
|
41
|
-
throw new Error("Skills response missing ETag header");
|
|
42
|
-
}
|
|
43
|
-
const body = (await response.json());
|
|
44
|
-
if (!Array.isArray(body?.skills)) {
|
|
45
|
-
throw new Error("Unexpected skills response shape");
|
|
46
|
-
}
|
|
47
|
-
const skills = body.skills;
|
|
48
|
-
if (hashSkills(skills) !== etag) {
|
|
49
|
-
throw new Error("Skill payload hash mismatch — refusing to write");
|
|
50
|
-
}
|
|
51
|
-
return { status: "modified", hash: etag, skills };
|
|
52
|
-
}
|
|
53
|
-
export function hashSkills(skills) {
|
|
54
|
-
const hash = createHash("sha256");
|
|
55
|
-
for (const skill of [...skills].sort((a, b) => a.path.localeCompare(b.path))) {
|
|
56
|
-
hash.update(skill.path);
|
|
57
|
-
hash.update("\0");
|
|
58
|
-
hash.update(skill.content);
|
|
59
|
-
hash.update("\0");
|
|
60
|
-
}
|
|
61
|
-
return hash.digest("hex");
|
|
62
|
-
}
|
|
63
|
-
function parseSkillHashEtag(etag) {
|
|
64
|
-
if (!etag)
|
|
65
|
-
return null;
|
|
66
|
-
const match = etag.trim().match(/^(?:W\/)?"([^"]+)"$/);
|
|
67
|
-
return match?.[1] ?? null;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Best-effort startup sync. Skips silently when there is no API key, when
|
|
71
|
-
* `~/.duet/.skills-hash` is absent (the user logged in without syncing), or
|
|
72
|
-
* when the network call fails — startup must never block on a sync error.
|
|
73
|
-
*
|
|
74
|
-
* Returns the sync result on success, `null` when skipped, or `null` after a
|
|
75
|
-
* caught error. Callers may inspect the return value to decide whether to
|
|
76
|
-
* surface anything to the user.
|
|
77
|
-
*/
|
|
78
|
-
export async function maybeAutoSyncDefaultSkills(options) {
|
|
79
|
-
if (!options.apiKey)
|
|
80
|
-
return null;
|
|
81
|
-
const hashFilePath = options.hashFilePath ?? DEFAULT_SKILLS_HASH_FILE;
|
|
82
|
-
if (!(await fileExists(hashFilePath)))
|
|
83
|
-
return null;
|
|
84
|
-
const log = options.logger ?? ((message) => process.stderr.write(`${message}\n`));
|
|
85
|
-
try {
|
|
86
|
-
return await syncDefaultSkills({ ...options, hashFilePath });
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
log(`Skill auto-sync failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
async function fileExists(path) {
|
|
94
|
-
try {
|
|
95
|
-
return (await stat(path)).isFile();
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
export async function syncDefaultSkills(options) {
|
|
102
|
-
const skillsDir = options.skillsDir ?? DEFAULT_SKILLS_DIR;
|
|
103
|
-
const hashFilePath = options.hashFilePath ?? DEFAULT_SKILLS_HASH_FILE;
|
|
104
|
-
const knownHash = await readExistingHash(hashFilePath);
|
|
105
|
-
const fetched = await fetchDefaultSkills({
|
|
106
|
-
apiKey: options.apiKey,
|
|
107
|
-
appBaseUrl: options.appBaseUrl,
|
|
108
|
-
fetchFn: options.fetchFn,
|
|
109
|
-
knownHash,
|
|
110
|
-
});
|
|
111
|
-
if (fetched.status === "not-modified") {
|
|
112
|
-
return { status: "unchanged", hash: fetched.hash };
|
|
113
|
-
}
|
|
114
|
-
// Stage the new tree in a sibling directory and swap it into place with a
|
|
115
|
-
// single rename, rather than rewriting `skillsDir` in place. A second `duet`
|
|
116
|
-
// process sharing this HOME can sync or read concurrently; an in-place
|
|
117
|
-
// rebuild lets it observe a half-written tree, or rm the directory out from
|
|
118
|
-
// under another sync's writes (`ENOENT ... open '.../<skill>'`). With staging
|
|
119
|
-
// + rename an observer only ever sees the complete old tree or the new one.
|
|
120
|
-
//
|
|
121
|
-
// The token is unique per call, not per process: two syncs in the same
|
|
122
|
-
// process and millisecond must not share scratch dirs or they stomp each
|
|
123
|
-
// other's writes.
|
|
124
|
-
const swapToken = randomUUID();
|
|
125
|
-
const stagingDir = `${skillsDir}.staging-${swapToken}`;
|
|
126
|
-
const retiredDir = `${skillsDir}.old-${swapToken}`;
|
|
127
|
-
await rm(stagingDir, { recursive: true, force: true });
|
|
128
|
-
await mkdir(stagingDir, { recursive: true });
|
|
129
|
-
try {
|
|
130
|
-
for (const skill of fetched.skills) {
|
|
131
|
-
const target = resolve(stagingDir, skill.path);
|
|
132
|
-
if (!isInsideDirectory(stagingDir, target)) {
|
|
133
|
-
throw new Error(`Refusing to write skill outside ${skillsDir}: ${skill.path}`);
|
|
134
|
-
}
|
|
135
|
-
await mkdir(dirname(target), { recursive: true });
|
|
136
|
-
await writeFile(target, skill.content);
|
|
137
|
-
}
|
|
138
|
-
await mkdir(dirname(skillsDir), { recursive: true });
|
|
139
|
-
await swapIntoPlace(stagingDir, skillsDir, retiredDir);
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
// Always clear scratch dirs: the retired tree on success, the staging tree
|
|
143
|
-
// if we threw before the swap. force:true keeps this a no-op when absent.
|
|
144
|
-
await rm(retiredDir, { recursive: true, force: true });
|
|
145
|
-
await rm(stagingDir, { recursive: true, force: true });
|
|
146
|
-
}
|
|
147
|
-
await mkdir(dirname(hashFilePath), { recursive: true });
|
|
148
|
-
await writeFile(hashFilePath, fetched.hash);
|
|
149
|
-
return { status: "synced", hash: fetched.hash, count: fetched.skills.length };
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Replace `skillsDir` with the freshly built `stagingDir`. rename cannot
|
|
153
|
-
* overwrite a non-empty directory, so the live tree is moved aside to
|
|
154
|
-
* `retiredDir` first and then the staging tree is moved into place.
|
|
155
|
-
*
|
|
156
|
-
* Without a cross-process lock two concurrent syncs can race on the final
|
|
157
|
-
* rename: the loser finds `skillsDir` already repopulated by the winner and
|
|
158
|
-
* gets EEXIST/ENOTEMPTY. Since every default-skill sync fetches the same
|
|
159
|
-
* payload, the winner's tree is a complete, correct result, so a lost race is
|
|
160
|
-
* success, not failure — we retry the move-aside/swap a few times and then
|
|
161
|
-
* accept a peer-installed tree rather than throwing. The destructive window is
|
|
162
|
-
* a single rename, so a reader at worst momentarily sees `skillsDir` absent
|
|
163
|
-
* (treated as "no skills") instead of a half-written tree.
|
|
164
|
-
*/
|
|
165
|
-
async function swapIntoPlace(stagingDir, skillsDir, retiredDir) {
|
|
166
|
-
const maxAttempts = 5;
|
|
167
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
168
|
-
// Each attempt reuses retiredDir, so clear whatever a prior attempt parked
|
|
169
|
-
// there before moving the live tree aside again.
|
|
170
|
-
await rm(retiredDir, { recursive: true, force: true });
|
|
171
|
-
try {
|
|
172
|
-
await rename(skillsDir, retiredDir);
|
|
173
|
-
}
|
|
174
|
-
catch (err) {
|
|
175
|
-
// ENOENT: no live tree to move aside (first sync, or a peer is mid-swap).
|
|
176
|
-
if (err.code !== "ENOENT")
|
|
177
|
-
throw err;
|
|
178
|
-
}
|
|
179
|
-
try {
|
|
180
|
-
await rename(stagingDir, skillsDir);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
catch (err) {
|
|
184
|
-
const code = err.code;
|
|
185
|
-
// A peer repopulated skillsDir between our move-aside and swap. Retry,
|
|
186
|
-
// and on the final attempt accept their complete tree as the result.
|
|
187
|
-
if (code !== "EEXIST" && code !== "ENOTEMPTY")
|
|
188
|
-
throw err;
|
|
189
|
-
if (attempt === maxAttempts - 1)
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
async function readExistingHash(path) {
|
|
195
|
-
try {
|
|
196
|
-
return (await readFile(path, "utf8")).trim() || null;
|
|
197
|
-
}
|
|
198
|
-
catch {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function isInsideDirectory(dir, candidate) {
|
|
203
|
-
const resolved = resolve(candidate);
|
|
204
|
-
const normalizedDir = resolve(dir) + (dir.endsWith("/") ? "" : "/");
|
|
205
|
-
return resolved === resolve(dir) || resolved.startsWith(normalizedDir);
|
|
206
|
-
}
|
|
207
|
-
async function safeReadText(response) {
|
|
208
|
-
try {
|
|
209
|
-
return await response.text();
|
|
210
|
-
}
|
|
211
|
-
catch {
|
|
212
|
-
return "";
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
//# sourceMappingURL=sync-skills.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sync-skills.js","sourceRoot":"","sources":["../../../src/lib/sync-skills.ts"],"names":[],"mappings":"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"}
|