document360-engine 0.2.0 → 0.2.2
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/LICENSE +10 -16
- package/README.md +1 -1
- package/dist/config.d.ts +20 -0
- package/dist/d360/tools.d.ts +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +28 -18
- package/dist/lib/writerMode.d.ts +18 -0
- package/dist/scope/inventory.d.ts +19 -0
- package/dist/session.d.ts +12 -1
- package/dist/sync/categoryMap.d.ts +42 -0
- package/dist/sync/crossLinks.d.ts +9 -0
- package/dist/sync/docsRoot.d.ts +8 -0
- package/dist/sync/frontmatter.d.ts +10 -0
- package/dist/sync/hash.d.ts +7 -0
- package/dist/sync/index.d.ts +9 -0
- package/dist/sync/pull.d.ts +41 -0
- package/dist/sync/remote.d.ts +37 -0
- package/dist/sync/status.d.ts +27 -0
- package/dist/sync/types.d.ts +22 -0
- package/package.json +3 -3
- package/skills/CLAUDE.md +39 -3
- package/skills/analyze-codebase/SKILL.md +35 -17
- package/skills/d360-markdown/SKILL.md +99 -0
- package/skills/gap-analysis/SKILL.md +75 -0
- package/skills/publish-to-d360/SKILL.md +4 -3
- package/skills/write-article/SKILL.md +7 -0
- package/dist/config.js +0 -62
- package/dist/config.js.map +0 -1
- package/dist/d360/apiLog.js +0 -68
- package/dist/d360/apiLog.js.map +0 -1
- package/dist/d360/client.js +0 -192
- package/dist/d360/client.js.map +0 -1
- package/dist/d360/environments.js +0 -56
- package/dist/d360/environments.js.map +0 -1
- package/dist/d360/oauth.js +0 -162
- package/dist/d360/oauth.js.map +0 -1
- package/dist/d360/profile.js +0 -31
- package/dist/d360/profile.js.map +0 -1
- package/dist/d360/tokenStore.js +0 -50
- package/dist/d360/tokenStore.js.map +0 -1
- package/dist/d360/tools.js +0 -337
- package/dist/d360/tools.js.map +0 -1
- package/dist/d360/wire.js +0 -83
- package/dist/d360/wire.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/auth.js +0 -25
- package/dist/lib/auth.js.map +0 -1
- package/dist/lib/messageQueue.js +0 -40
- package/dist/lib/messageQueue.js.map +0 -1
- package/dist/lib/paths.js +0 -35
- package/dist/lib/paths.js.map +0 -1
- package/dist/lib/sessionStore.js +0 -100
- package/dist/lib/sessionStore.js.map +0 -1
- package/dist/lib/suggestGen.js +0 -61
- package/dist/lib/suggestGen.js.map +0 -1
- package/dist/lib/titleGen.js +0 -64
- package/dist/lib/titleGen.js.map +0 -1
- package/dist/session.js +0 -220
- package/dist/session.js.map +0 -1
- package/skills/audit-docs/SKILL.md +0 -48
package/dist/lib/sessionStore.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { sessionsFilePath, userDir, ensureDir } from './paths.js';
|
|
3
|
-
const MAX_RECORDS = 100;
|
|
4
|
-
export function loadSessions() {
|
|
5
|
-
const path = sessionsFilePath();
|
|
6
|
-
if (!existsSync(path))
|
|
7
|
-
return [];
|
|
8
|
-
try {
|
|
9
|
-
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
10
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return [];
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function saveSessions(records) {
|
|
17
|
-
ensureDir(userDir());
|
|
18
|
-
const sorted = [...records].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)).slice(0, MAX_RECORDS);
|
|
19
|
-
writeFileSync(sessionsFilePath(), JSON.stringify(sorted, null, 2));
|
|
20
|
-
}
|
|
21
|
-
export function upsertSession(rec) {
|
|
22
|
-
const records = loadSessions().filter(r => r.uuid !== rec.uuid);
|
|
23
|
-
records.push(rec);
|
|
24
|
-
saveSessions(records);
|
|
25
|
-
}
|
|
26
|
-
export function getSession(uuid) {
|
|
27
|
-
return loadSessions().find(r => r.uuid === uuid);
|
|
28
|
-
}
|
|
29
|
-
export function listSessions(cwd) {
|
|
30
|
-
return loadSessions()
|
|
31
|
-
.filter(r => r.cwd === cwd)
|
|
32
|
-
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
33
|
-
}
|
|
34
|
-
/** Exact name match first, then unique name-prefix, then unique uuid-prefix. */
|
|
35
|
-
export function findByName(cwd, name) {
|
|
36
|
-
const sessions = listSessions(cwd);
|
|
37
|
-
const lower = name.toLowerCase();
|
|
38
|
-
const exact = sessions.find(r => r.name.toLowerCase() === lower);
|
|
39
|
-
if (exact)
|
|
40
|
-
return exact;
|
|
41
|
-
const prefix = sessions.filter(r => r.name.toLowerCase().startsWith(lower));
|
|
42
|
-
if (prefix.length === 1)
|
|
43
|
-
return prefix[0];
|
|
44
|
-
const byUuid = sessions.filter(r => r.uuid.startsWith(name));
|
|
45
|
-
if (byUuid.length === 1)
|
|
46
|
-
return byUuid[0];
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
export function touchSession(uuid) {
|
|
50
|
-
const records = loadSessions();
|
|
51
|
-
const rec = records.find(r => r.uuid === uuid);
|
|
52
|
-
if (!rec)
|
|
53
|
-
return;
|
|
54
|
-
rec.updatedAt = new Date().toISOString();
|
|
55
|
-
saveSessions(records);
|
|
56
|
-
}
|
|
57
|
-
export function renameSession(uuid, name) {
|
|
58
|
-
const records = loadSessions();
|
|
59
|
-
const rec = records.find(r => r.uuid === uuid);
|
|
60
|
-
if (!rec)
|
|
61
|
-
return false;
|
|
62
|
-
rec.name = name;
|
|
63
|
-
rec.renamed = true;
|
|
64
|
-
rec.updatedAt = new Date().toISOString();
|
|
65
|
-
saveSessions(records);
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
/** Apply an auto-generated title. No-op if the user already renamed the session. */
|
|
69
|
-
export function setTitle(uuid, title) {
|
|
70
|
-
const records = loadSessions();
|
|
71
|
-
const rec = records.find(r => r.uuid === uuid);
|
|
72
|
-
if (!rec || rec.renamed)
|
|
73
|
-
return;
|
|
74
|
-
rec.name = title;
|
|
75
|
-
rec.titled = true;
|
|
76
|
-
saveSessions(records);
|
|
77
|
-
}
|
|
78
|
-
export function slugify(text, maxWords = 6) {
|
|
79
|
-
const words = text
|
|
80
|
-
.toLowerCase()
|
|
81
|
-
.replace(/[^a-z0-9\s-]/g, '')
|
|
82
|
-
.split(/\s+/)
|
|
83
|
-
.filter(Boolean)
|
|
84
|
-
.slice(0, maxWords);
|
|
85
|
-
return words.join('-') || 'session';
|
|
86
|
-
}
|
|
87
|
-
export function relativeTime(iso) {
|
|
88
|
-
const ms = Date.now() - new Date(iso).getTime();
|
|
89
|
-
const min = Math.floor(ms / 60_000);
|
|
90
|
-
if (min < 1)
|
|
91
|
-
return 'just now';
|
|
92
|
-
if (min < 60)
|
|
93
|
-
return `${min}m ago`;
|
|
94
|
-
const hr = Math.floor(min / 60);
|
|
95
|
-
if (hr < 24)
|
|
96
|
-
return `${hr}h ago`;
|
|
97
|
-
const day = Math.floor(hr / 24);
|
|
98
|
-
return `${day}d ago`;
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=sessionStore.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sessionStore.js","sourceRoot":"","sources":["../../src/lib/sessionStore.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/suggestGen.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
2
|
-
const TIMEOUT_MS = 30_000;
|
|
3
|
-
/**
|
|
4
|
-
* One-shot background Haiku call proposing the user's likely next prompt after a
|
|
5
|
-
* completed turn — Claude Code-style ghost text (tab to accept). Goes through the
|
|
6
|
-
* Agent SDK (works in API-key and subscription auth modes). Returns null when there
|
|
7
|
-
* is no obvious next action or on any failure — callers just show no suggestion.
|
|
8
|
-
*/
|
|
9
|
-
export async function suggestNextAction(userPrompt, assistantReply, cwd) {
|
|
10
|
-
try {
|
|
11
|
-
return await Promise.race([run(userPrompt, assistantReply, cwd), timeout()]);
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
async function run(userPrompt, assistantReply, cwd) {
|
|
18
|
-
const q = query({
|
|
19
|
-
prompt: [
|
|
20
|
-
'In a documentation-writing session, the user asked:',
|
|
21
|
-
'',
|
|
22
|
-
userPrompt.slice(0, 400),
|
|
23
|
-
'',
|
|
24
|
-
'The assistant\'s reply ended with:',
|
|
25
|
-
'',
|
|
26
|
-
assistantReply.slice(-1200),
|
|
27
|
-
'',
|
|
28
|
-
'Suggest the user\'s most likely next prompt. Reply with ONLY that prompt:',
|
|
29
|
-
'imperative, specific, at most 12 words, no quotes. If the assistant asked a',
|
|
30
|
-
'question, the suggestion should answer it (e.g. "yes, apply the fixes").',
|
|
31
|
-
'If there is no clear next action, reply with exactly: NONE',
|
|
32
|
-
].join('\n'),
|
|
33
|
-
options: {
|
|
34
|
-
cwd,
|
|
35
|
-
model: 'haiku',
|
|
36
|
-
maxTurns: 1,
|
|
37
|
-
settingSources: [],
|
|
38
|
-
systemPrompt: 'You propose the next user prompt for a docs-writing CLI. Output only the prompt, or NONE.',
|
|
39
|
-
allowedTools: [],
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
for await (const msg of q) {
|
|
43
|
-
const m = msg;
|
|
44
|
-
if (m.type === 'result') {
|
|
45
|
-
if (m.subtype === 'success' && typeof m.result === 'string')
|
|
46
|
-
return sanitize(m.result);
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
function timeout() {
|
|
53
|
-
return new Promise(resolve => setTimeout(() => resolve(null), TIMEOUT_MS).unref());
|
|
54
|
-
}
|
|
55
|
-
function sanitize(raw) {
|
|
56
|
-
const s = raw.trim().split('\n')[0].replace(/^["'`]+|["'`]+$/g, '').trim();
|
|
57
|
-
if (!s || /^none\b/i.test(s) || s.length < 4 || s.length > 100)
|
|
58
|
-
return null;
|
|
59
|
-
return s;
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=suggestGen.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"suggestGen.js","sourceRoot":"","sources":["../../src/lib/suggestGen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAEvD,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAkB,EAAE,cAAsB,EAAE,GAAW;IAC7F,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,GAAG,CAAC,UAAkB,EAAE,cAAsB,EAAE,GAAW;IACxE,MAAM,CAAC,GAAG,KAAK,CAAC;QACd,MAAM,EAAE;YACN,qDAAqD;YACrD,EAAE;YACF,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YACxB,EAAE;YACF,oCAAoC;YACpC,EAAE;YACF,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;YAC3B,EAAE;YACF,2EAA2E;YAC3E,6EAA6E;YAC7E,0EAA0E;YAC1E,4DAA4D;SAC7D,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE;YACP,GAAG;YACH,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,CAAC;YACX,cAAc,EAAE,EAAE;YAClB,YAAY,EAAE,2FAA2F;YACzG,YAAY,EAAE,EAAE;SACjB;KACF,CAAC,CAAC;IACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,GAA2D,CAAC;QACtE,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;gBAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACvF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,OAAO;IACd,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5E,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,IAAI,CAAC;IAC5E,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/lib/titleGen.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
2
|
-
const TIMEOUT_MS = 60_000;
|
|
3
|
-
/**
|
|
4
|
-
* One-shot background Haiku call to title a session, Claude Code-style.
|
|
5
|
-
* Goes through the Agent SDK (not the raw API) so it works in both API-key
|
|
6
|
-
* and subscription auth modes. Returns null on any failure — callers keep
|
|
7
|
-
* the slug fallback.
|
|
8
|
-
*/
|
|
9
|
-
export async function generateTitle(firstPrompt, cwd) {
|
|
10
|
-
try {
|
|
11
|
-
const result = await Promise.race([run(firstPrompt, cwd), timeout()]);
|
|
12
|
-
return result;
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
async function run(firstPrompt, cwd) {
|
|
19
|
-
const q = query({
|
|
20
|
-
prompt: [
|
|
21
|
-
'Generate a short session title for a documentation-writing session that started with this request:',
|
|
22
|
-
'',
|
|
23
|
-
firstPrompt.slice(0, 500),
|
|
24
|
-
'',
|
|
25
|
-
'Reply with ONLY the title: 3-6 words, lowercase, kebab-case, no quotes, no punctuation.',
|
|
26
|
-
].join('\n'),
|
|
27
|
-
options: {
|
|
28
|
-
cwd,
|
|
29
|
-
model: 'haiku',
|
|
30
|
-
maxTurns: 1,
|
|
31
|
-
settingSources: [],
|
|
32
|
-
systemPrompt: 'You generate terse kebab-case session titles. Output only the title, nothing else.',
|
|
33
|
-
allowedTools: [],
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
for await (const msg of q) {
|
|
37
|
-
const m = msg;
|
|
38
|
-
if (m.type === 'result') {
|
|
39
|
-
if (m.subtype === 'success' && typeof m.result === 'string') {
|
|
40
|
-
return sanitize(m.result);
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
function timeout() {
|
|
48
|
-
return new Promise(resolve => setTimeout(() => resolve(null), TIMEOUT_MS).unref());
|
|
49
|
-
}
|
|
50
|
-
function sanitize(raw) {
|
|
51
|
-
const title = raw
|
|
52
|
-
.trim()
|
|
53
|
-
.toLowerCase()
|
|
54
|
-
.replace(/[^a-z0-9\s-]/g, '')
|
|
55
|
-
.replace(/\s+/g, '-')
|
|
56
|
-
.replace(/-+/g, '-')
|
|
57
|
-
.replace(/^-|-$/g, '')
|
|
58
|
-
.split('-')
|
|
59
|
-
.slice(0, 8)
|
|
60
|
-
.join('-')
|
|
61
|
-
.slice(0, 60);
|
|
62
|
-
return title.length >= 3 ? title : null;
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=titleGen.js.map
|
package/dist/lib/titleGen.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"titleGen.js","sourceRoot":"","sources":["../../src/lib/titleGen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAEvD,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,GAAW;IAClE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACtE,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,GAAG,CAAC,WAAmB,EAAE,GAAW;IACjD,MAAM,CAAC,GAAG,KAAK,CAAC;QACd,MAAM,EAAE;YACN,oGAAoG;YACpG,EAAE;YACF,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YACzB,EAAE;YACF,yFAAyF;SAC1F,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE;YACP,GAAG;YACH,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,CAAC;YACX,cAAc,EAAE,EAAE;YAClB,YAAY,EAAE,oFAAoF;YAClG,YAAY,EAAE,EAAE;SACjB;KACF,CAAC,CAAC;IACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,GAA2D,CAAC;QACtE,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC5D,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,OAAO;IACd,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,KAAK,GAAG,GAAG;SACd,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,GAAG,CAAC;SACV,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,IAAI,CAAC,GAAG,CAAC;SACT,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC"}
|
package/dist/session.js
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { readdirSync, readFileSync, existsSync, statSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
4
|
-
import { packageSkillsDir, projectSkillsDir } from './lib/paths.js';
|
|
5
|
-
import { readMcpConfig, readProjectConfig } from './config.js';
|
|
6
|
-
import { UserMessageQueue } from './lib/messageQueue.js';
|
|
7
|
-
import { buildD360ToolServer } from './d360/tools.js';
|
|
8
|
-
import { resolveActiveProfile } from './d360/profile.js';
|
|
9
|
-
const MASTER_PROMPT_FILE = 'CLAUDE.md';
|
|
10
|
-
function readSkillFiles(dir) {
|
|
11
|
-
if (!existsSync(dir))
|
|
12
|
-
return [];
|
|
13
|
-
const out = [];
|
|
14
|
-
for (const entry of readdirSync(dir)) {
|
|
15
|
-
const sub = join(dir, entry);
|
|
16
|
-
if (entry === MASTER_PROMPT_FILE)
|
|
17
|
-
continue;
|
|
18
|
-
if (!statSync(sub).isDirectory())
|
|
19
|
-
continue;
|
|
20
|
-
const skillFile = join(sub, 'SKILL.md');
|
|
21
|
-
if (!existsSync(skillFile))
|
|
22
|
-
continue;
|
|
23
|
-
out.push({ name: entry, body: readFileSync(skillFile, 'utf8') });
|
|
24
|
-
}
|
|
25
|
-
return out;
|
|
26
|
-
}
|
|
27
|
-
function readMasterPrompt(dir) {
|
|
28
|
-
const path = join(dir, MASTER_PROMPT_FILE);
|
|
29
|
-
return existsSync(path) ? readFileSync(path, 'utf8') : null;
|
|
30
|
-
}
|
|
31
|
-
function buildSystemPrompt(cwd, cfg) {
|
|
32
|
-
const packageDir = packageSkillsDir();
|
|
33
|
-
const projectDir = projectSkillsDir(cwd);
|
|
34
|
-
const masterPackage = readMasterPrompt(packageDir);
|
|
35
|
-
const masterProject = readMasterPrompt(projectDir);
|
|
36
|
-
const packageSkills = readSkillFiles(packageDir);
|
|
37
|
-
const projectSkills = readSkillFiles(projectDir);
|
|
38
|
-
const projectSkillNames = new Set(projectSkills.map(s => s.name));
|
|
39
|
-
const merged = [...packageSkills.filter(s => !projectSkillNames.has(s.name)), ...projectSkills];
|
|
40
|
-
const parts = [];
|
|
41
|
-
if (masterPackage)
|
|
42
|
-
parts.push(masterPackage);
|
|
43
|
-
if (masterProject)
|
|
44
|
-
parts.push(`# Project addendum\n\n${masterProject}`);
|
|
45
|
-
if (cfg) {
|
|
46
|
-
parts.push('# Project configuration');
|
|
47
|
-
parts.push('```json');
|
|
48
|
-
parts.push(JSON.stringify(cfg, null, 2));
|
|
49
|
-
parts.push('```');
|
|
50
|
-
}
|
|
51
|
-
if (merged.length > 0) {
|
|
52
|
-
parts.push('# Capabilities');
|
|
53
|
-
parts.push('You have the following specialized documentation skills. Activate the one whose preconditions match the user request. If multiple match, run them in order.');
|
|
54
|
-
for (const s of merged) {
|
|
55
|
-
parts.push(`## Skill: ${s.name}`);
|
|
56
|
-
parts.push(s.body);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return parts.join('\n\n');
|
|
60
|
-
}
|
|
61
|
-
function toSdkMcpServers() {
|
|
62
|
-
const mcp = readMcpConfig();
|
|
63
|
-
const out = {};
|
|
64
|
-
for (const [name, entry] of Object.entries(mcp.servers)) {
|
|
65
|
-
if (entry.type === 'stdio') {
|
|
66
|
-
out[name] = { type: 'stdio', command: entry.command, args: entry.args, env: entry.env };
|
|
67
|
-
}
|
|
68
|
-
else if (entry.type === 'http') {
|
|
69
|
-
out[name] = { type: 'http', url: entry.url, headers: entry.headers };
|
|
70
|
-
}
|
|
71
|
-
else if (entry.type === 'sse') {
|
|
72
|
-
out[name] = { type: 'sse', url: entry.url, headers: entry.headers };
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return out;
|
|
76
|
-
}
|
|
77
|
-
const AUTH_ERROR_PATTERN = /auth|api key|login|credential|401|forbidden/i;
|
|
78
|
-
/**
|
|
79
|
-
* A persistent conversation with the documentation agent. `send()` streams typed
|
|
80
|
-
* EngineEvents for one user turn; the session stays open for further turns until close().
|
|
81
|
-
*/
|
|
82
|
-
export class EngineSession {
|
|
83
|
-
queue;
|
|
84
|
-
iterator;
|
|
85
|
-
/** The engine's own session UUID, once revealed (for resume/persistence). */
|
|
86
|
-
sessionId = null;
|
|
87
|
-
constructor(opts = {}) {
|
|
88
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
89
|
-
const cfg = readProjectConfig(cwd);
|
|
90
|
-
const systemPrompt = buildSystemPrompt(cwd, cfg);
|
|
91
|
-
const mcpServers = toSdkMcpServers();
|
|
92
|
-
// First-party Document360 tools, hosted in-process for the active profile. Tools
|
|
93
|
-
// surface "run login" if the token is missing/expired. Skipped only when the config
|
|
94
|
-
// is old-shape/invalid (resolveActiveProfile throws). Write tools are gated on
|
|
95
|
-
// production profiles until authorized (allowProdWrites).
|
|
96
|
-
try {
|
|
97
|
-
const active = resolveActiveProfile(cwd, opts.profileName);
|
|
98
|
-
const writesAllowed = !active.production || opts.allowProdWrites === true;
|
|
99
|
-
mcpServers.document360 = buildD360ToolServer(active, { writesAllowed });
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
/* no/invalid profile config — D360 tools unavailable until init/login */
|
|
103
|
-
}
|
|
104
|
-
this.queue = new UserMessageQueue();
|
|
105
|
-
const options = {
|
|
106
|
-
cwd,
|
|
107
|
-
systemPrompt,
|
|
108
|
-
mcpServers,
|
|
109
|
-
permissionMode: 'bypassPermissions',
|
|
110
|
-
allowDangerouslySkipPermissions: true,
|
|
111
|
-
includePartialMessages: true,
|
|
112
|
-
settingSources: [],
|
|
113
|
-
model: cfg?.defaultModel,
|
|
114
|
-
resume: opts.resume,
|
|
115
|
-
};
|
|
116
|
-
const q = query({ prompt: this.queue, options });
|
|
117
|
-
this.iterator = q[Symbol.asyncIterator]();
|
|
118
|
-
}
|
|
119
|
-
/** Send one user turn; yields EngineEvents until the agent produces its result. */
|
|
120
|
-
async *send(text) {
|
|
121
|
-
this.queue.push(text);
|
|
122
|
-
while (true) {
|
|
123
|
-
let next;
|
|
124
|
-
try {
|
|
125
|
-
next = await this.iterator.next();
|
|
126
|
-
}
|
|
127
|
-
catch (err) {
|
|
128
|
-
const message = err.message;
|
|
129
|
-
yield { type: 'error', kind: AUTH_ERROR_PATTERN.test(message) ? 'auth' : 'agent', message };
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (next.done)
|
|
133
|
-
return;
|
|
134
|
-
const sessionId = next.value?.session_id;
|
|
135
|
-
if (sessionId && !this.sessionId) {
|
|
136
|
-
this.sessionId = sessionId;
|
|
137
|
-
yield { type: 'session', sessionId };
|
|
138
|
-
}
|
|
139
|
-
const ev = translate(next.value);
|
|
140
|
-
if (ev) {
|
|
141
|
-
for (const e of ev)
|
|
142
|
-
yield e;
|
|
143
|
-
if (ev.some(e => e.type === 'result'))
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
close() {
|
|
149
|
-
this.queue.close();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
export function createSession(opts = {}) {
|
|
153
|
-
return new EngineSession(opts);
|
|
154
|
-
}
|
|
155
|
-
/** Flatten a tool_result block's content (string or text-block array) to plain text. */
|
|
156
|
-
function flattenToolResult(content) {
|
|
157
|
-
if (typeof content === 'string')
|
|
158
|
-
return content;
|
|
159
|
-
if (!Array.isArray(content))
|
|
160
|
-
return '';
|
|
161
|
-
return content
|
|
162
|
-
.map(c => {
|
|
163
|
-
const b = c;
|
|
164
|
-
return b.type === 'text' && typeof b.text === 'string' ? b.text : '';
|
|
165
|
-
})
|
|
166
|
-
.filter(Boolean)
|
|
167
|
-
.join('\n');
|
|
168
|
-
}
|
|
169
|
-
/** Translate one raw Agent-SDK message into zero or more EngineEvents. */
|
|
170
|
-
function translate(raw) {
|
|
171
|
-
if (!raw || typeof raw !== 'object')
|
|
172
|
-
return null;
|
|
173
|
-
const msg = raw;
|
|
174
|
-
if (msg.type === 'stream_event') {
|
|
175
|
-
const event = msg.event;
|
|
176
|
-
if (event?.delta && typeof event.delta.text === 'string') {
|
|
177
|
-
return [{ type: 'text', delta: event.delta.text }];
|
|
178
|
-
}
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
if (msg.type === 'assistant') {
|
|
182
|
-
const message = msg.message;
|
|
183
|
-
const out = [];
|
|
184
|
-
for (const block of message?.content ?? []) {
|
|
185
|
-
const b = block;
|
|
186
|
-
if (b.type === 'tool_use') {
|
|
187
|
-
out.push({ type: 'tool', id: b.id ?? '', name: b.name ?? 'tool', input: b.input ?? {} });
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return out.length > 0 ? out : null;
|
|
191
|
-
}
|
|
192
|
-
// Tool results come back as user messages carrying tool_result blocks. A user
|
|
193
|
-
// message with plain string content (the prompt echo) has none → null.
|
|
194
|
-
if (msg.type === 'user') {
|
|
195
|
-
const message = msg.message;
|
|
196
|
-
if (!Array.isArray(message?.content))
|
|
197
|
-
return null;
|
|
198
|
-
const out = [];
|
|
199
|
-
for (const block of message.content) {
|
|
200
|
-
const b = block;
|
|
201
|
-
if (b.type === 'tool_result') {
|
|
202
|
-
out.push({ type: 'tool_result', id: b.tool_use_id ?? '', output: flattenToolResult(b.content), isError: b.is_error === true });
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return out.length > 0 ? out : null;
|
|
206
|
-
}
|
|
207
|
-
if (msg.type === 'result') {
|
|
208
|
-
const r = msg;
|
|
209
|
-
return [
|
|
210
|
-
{
|
|
211
|
-
type: 'result',
|
|
212
|
-
inputTokens: r.usage?.input_tokens ?? 0,
|
|
213
|
-
outputTokens: r.usage?.output_tokens ?? 0,
|
|
214
|
-
ok: r.subtype === 'success',
|
|
215
|
-
},
|
|
216
|
-
];
|
|
217
|
-
}
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
//# sourceMappingURL=session.js.map
|
package/dist/session.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# Skill: audit-docs
|
|
2
|
-
|
|
3
|
-
**Activate when** the user runs `/audit` or asks "what's stale", "what's missing", "where are the gaps".
|
|
4
|
-
|
|
5
|
-
**Goal:** produce a table of articles that need attention, with a concrete reason per row.
|
|
6
|
-
|
|
7
|
-
## What to do
|
|
8
|
-
|
|
9
|
-
1. Read `.d360-writer.json` for the `captureDir`, `outputDir`, and `authoritativeSourceFiles` list.
|
|
10
|
-
2. Read every existing article under the docs root (typically `user-docs/`).
|
|
11
|
-
3. Read recent git history: `git log --since="30 days ago" --name-only --pretty=format:"%h %s"`. If `d360-category-map.json` exists, prefer commits since its mtime.
|
|
12
|
-
4. For each commit, identify which articles describe the affected code paths. Cross-reference using the authoritative source files list and the article-to-code links you can infer.
|
|
13
|
-
5. For each existing article, check whether its claims still match the source code. Look for: renamed components, changed UI strings, removed features, added features.
|
|
14
|
-
|
|
15
|
-
## Output format
|
|
16
|
-
|
|
17
|
-
A single markdown table. Nothing else.
|
|
18
|
-
|
|
19
|
-
| Article path | Action | Reason | Scope |
|
|
20
|
-
|---|---|---|---|
|
|
21
|
-
| `03-foo/02-bar.md` | update | commit `abc123` renamed the "Bar" dialog to "Settings" | small |
|
|
22
|
-
| `04-baz/06-new-feature.md` | create | commit `def456` shipped a feature with no doc | full article |
|
|
23
|
-
| `02-spec/04-old-thing.md` | delete | commit `ghi789` removed the feature; no replacement | full deletion |
|
|
24
|
-
|
|
25
|
-
## Action values
|
|
26
|
-
|
|
27
|
-
- `create` — article doesn't exist, but the feature it would describe is real and shipped.
|
|
28
|
-
- `update` — article exists but disagrees with current code.
|
|
29
|
-
- `delete` — article describes a removed feature.
|
|
30
|
-
- `keep` — explicitly noted as up-to-date and intentional. Don't include `keep` rows unless the user asked for them.
|
|
31
|
-
|
|
32
|
-
## Scope values
|
|
33
|
-
|
|
34
|
-
- `small` — a UI string, a step renumbering, a one-line clarification.
|
|
35
|
-
- `medium` — a section rewrite or a new screenshot.
|
|
36
|
-
- `full article` — net-new article or near-complete rewrite.
|
|
37
|
-
- `full deletion` — remove from disk and from D360.
|
|
38
|
-
|
|
39
|
-
## Rules
|
|
40
|
-
|
|
41
|
-
- Quote the commit hash for every claim. No vague "the code changed."
|
|
42
|
-
- Do not start fixing anything. The audit is the deliverable.
|
|
43
|
-
- If the codebase has zero existing articles, redirect the user to `propose-structure` instead and emit nothing.
|
|
44
|
-
- If the audit has zero rows, say so plainly: "All articles are in sync with the codebase as of `<HEAD-sha>`."
|
|
45
|
-
|
|
46
|
-
End your output with:
|
|
47
|
-
|
|
48
|
-
> Want me to start working through these? Reply with `yes` or strike rows you want to defer.
|