dsh-tacit 0.4.0 → 0.5.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 -1
- package/client/client.js +292 -45
- package/docs/README.zh.md +2 -1
- package/lib/analyze.js +144 -40
- package/lib/fold.js +11 -5
- package/lib/redact.js +53 -0
- package/lib/routes.js +1 -0
- package/lib/schema.js +71 -12
- package/lib/service.js +210 -51
- package/lib/store.js +2 -2
- package/lib/usage.js +57 -14
- package/lib/workspace.js +62 -0
- package/package.json +1 -1
package/lib/workspace.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The identity of a workspace: the absolute directory with `..` resolved, a
|
|
6
|
+
* trailing separator stripped and symlinks followed when it exists on disk.
|
|
7
|
+
* Case is left alone. '' when there is no directory.
|
|
8
|
+
*/
|
|
9
|
+
export function normalizeWorkspace(raw) {
|
|
10
|
+
if (typeof raw !== 'string' || raw.length === 0) return ''
|
|
11
|
+
const resolved = path.resolve(raw)
|
|
12
|
+
try {
|
|
13
|
+
return fs.realpathSync(resolved)
|
|
14
|
+
} catch {
|
|
15
|
+
return resolved
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Whether `cwd` is `scope` itself or a directory inside it — by path segment, never by string prefix. */
|
|
20
|
+
export function workspaceContains(scope, cwd) {
|
|
21
|
+
if (typeof scope !== 'string' || scope.length === 0 || typeof cwd !== 'string') return false
|
|
22
|
+
if (cwd === scope) return true
|
|
23
|
+
const base = /[\\/]$/.test(scope) ? scope.slice(0, -1) : scope
|
|
24
|
+
return cwd.startsWith(base + '/') || cwd.startsWith(base + '\\')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** The last path segment of a workspace directory — what a person calls the project. */
|
|
28
|
+
export function workspaceLabel(cwd) {
|
|
29
|
+
if (typeof cwd !== 'string' || cwd.length === 0) return ''
|
|
30
|
+
const parts = cwd.split(/[\\/]+/).filter((part) => part.length > 0)
|
|
31
|
+
return parts.length > 0 ? parts[parts.length - 1] : ''
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A distinct label per workspace, in insertion order: the basename, extended by
|
|
36
|
+
* one more parent segment at a time (`a/web`, `b/web`) while two of them would
|
|
37
|
+
* read the same, up to the full path.
|
|
38
|
+
*/
|
|
39
|
+
export function workspaceLabels(cwds) {
|
|
40
|
+
const distinct = [...new Set((Array.isArray(cwds) ? cwds : []).filter((cwd) => typeof cwd === 'string' && cwd.length > 0))]
|
|
41
|
+
const segments = new Map(distinct.map((cwd) => [cwd, cwd.split(/[\\/]+/).filter((part) => part.length > 0)]))
|
|
42
|
+
const depth = new Map(distinct.map((cwd) => [cwd, 1]))
|
|
43
|
+
const labelOf = (cwd) => segments.get(cwd).slice(-depth.get(cwd)).join('/')
|
|
44
|
+
for (;;) {
|
|
45
|
+
const groups = new Map()
|
|
46
|
+
for (const cwd of distinct) {
|
|
47
|
+
const label = labelOf(cwd)
|
|
48
|
+
if (groups.has(label)) groups.get(label).push(cwd)
|
|
49
|
+
else groups.set(label, [cwd])
|
|
50
|
+
}
|
|
51
|
+
let grew = false
|
|
52
|
+
for (const group of groups.values()) {
|
|
53
|
+
if (group.length < 2) continue
|
|
54
|
+
for (const cwd of group) {
|
|
55
|
+
if (depth.get(cwd) >= segments.get(cwd).length) continue
|
|
56
|
+
depth.set(cwd, depth.get(cwd) + 1)
|
|
57
|
+
grew = true
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!grew) return new Map(distinct.map((cwd) => [cwd, labelOf(cwd)]))
|
|
61
|
+
}
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-tacit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Tacit learns what you leave unsaid in your prompts — from messy turns and your own corrections, with zero clicks — and tells the agent how to compensate, on every turn, via a system-prompt section you can read and edit.",
|
|
5
5
|
"author": "hackernotfound",
|
|
6
6
|
"license": "MIT",
|