@agent-workshop/adoc-core 0.1.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/LICENSE +5 -0
- package/THIRD_PARTY_NOTICES.md +49 -0
- package/dist/claim.d.ts +17 -0
- package/dist/claim.js +35 -0
- package/dist/claim.js.map +1 -0
- package/dist/client.d.ts +14 -0
- package/dist/client.js +49 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.js +110 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/fetch.d.ts +19 -0
- package/dist/fetch.js +106 -0
- package/dist/fetch.js.map +1 -0
- package/dist/git.d.ts +1 -0
- package/dist/git.js +13 -0
- package/dist/git.js.map +1 -0
- package/dist/herdr.d.ts +44 -0
- package/dist/herdr.js +134 -0
- package/dist/herdr.js.map +1 -0
- package/dist/home.d.ts +12 -0
- package/dist/home.js +43 -0
- package/dist/home.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +76 -0
- package/dist/messages.js +119 -0
- package/dist/messages.js.map +1 -0
- package/dist/names.d.ts +14 -0
- package/dist/names.js +19 -0
- package/dist/names.js.map +1 -0
- package/dist/plugins.d.ts +43 -0
- package/dist/plugins.js +157 -0
- package/dist/plugins.js.map +1 -0
- package/dist/registry.d.ts +11 -0
- package/dist/registry.js +39 -0
- package/dist/registry.js.map +1 -0
- package/dist/report.d.ts +3 -0
- package/dist/report.js +9 -0
- package/dist/report.js.map +1 -0
- package/dist/scan.d.ts +35 -0
- package/dist/scan.js +163 -0
- package/dist/scan.js.map +1 -0
- package/dist/server.d.ts +80 -0
- package/dist/server.js +576 -0
- package/dist/server.js.map +1 -0
- package/dist/skills.d.ts +46 -0
- package/dist/skills.js +131 -0
- package/dist/skills.js.map +1 -0
- package/dist/terminal.d.ts +28 -0
- package/dist/terminal.js +110 -0
- package/dist/terminal.js.map +1 -0
- package/dist/transports.d.ts +21 -0
- package/dist/transports.js +69 -0
- package/dist/transports.js.map +1 -0
- package/dist/workspace.d.ts +182 -0
- package/dist/workspace.js +392 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +54 -0
- package/skill/SKILL.md +219 -0
package/dist/herdr.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import { createConnection } from 'node:net';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { AdocError } from './errors.js';
|
|
6
|
+
let requestId = 0;
|
|
7
|
+
/** Sends one request over a herdr session socket (NDJSON) and returns its result. */
|
|
8
|
+
export function herdrCall(socketPath, method, params = {}) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const socket = createConnection(socketPath);
|
|
11
|
+
let buffer = '';
|
|
12
|
+
const id = `adoc-${++requestId}`;
|
|
13
|
+
socket.setTimeout(10_000, () => socket.destroy(new Error(`herdr ${method} timed out`)));
|
|
14
|
+
socket.on('connect', () => socket.write(JSON.stringify({ id, method, params }) + '\n'));
|
|
15
|
+
socket.on('data', (chunk) => {
|
|
16
|
+
buffer += chunk.toString('utf8');
|
|
17
|
+
const end = buffer.indexOf('\n');
|
|
18
|
+
if (end < 0)
|
|
19
|
+
return;
|
|
20
|
+
socket.end();
|
|
21
|
+
const reply = JSON.parse(buffer.slice(0, end));
|
|
22
|
+
if (reply.error)
|
|
23
|
+
reject(new AdocError('herdr.error', `herdr ${method}: ${reply.error.message ?? reply.error.code}`));
|
|
24
|
+
else
|
|
25
|
+
resolve(reply.result);
|
|
26
|
+
});
|
|
27
|
+
socket.on('error', (error) => reject(new AdocError('herdr.unreachable', `herdr socket ${socketPath}: ${error.message}`)));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Subscribes to herdr events on a session socket; the connection stays open.
|
|
32
|
+
* Returns a function that closes the subscription.
|
|
33
|
+
*/
|
|
34
|
+
export function herdrSubscribe(socketPath, subscriptions, onEvent, onClose) {
|
|
35
|
+
const socket = createConnection(socketPath);
|
|
36
|
+
let buffer = '';
|
|
37
|
+
socket.on('connect', () => socket.write(JSON.stringify({ id: `adoc-sub-${++requestId}`, method: 'events.subscribe', params: { subscriptions } }) + '\n'));
|
|
38
|
+
socket.on('data', (chunk) => {
|
|
39
|
+
buffer += chunk.toString('utf8');
|
|
40
|
+
let end;
|
|
41
|
+
while ((end = buffer.indexOf('\n')) >= 0) {
|
|
42
|
+
const line = buffer.slice(0, end);
|
|
43
|
+
buffer = buffer.slice(end + 1);
|
|
44
|
+
try {
|
|
45
|
+
const message = JSON.parse(line);
|
|
46
|
+
if (message.event)
|
|
47
|
+
onEvent(message);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Ignore a malformed line.
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
socket.on('close', onClose);
|
|
55
|
+
socket.on('error', () => undefined);
|
|
56
|
+
return () => socket.destroy();
|
|
57
|
+
}
|
|
58
|
+
/** The socket of every herdr session on this computer, by session name. */
|
|
59
|
+
export async function herdrSessions(home = homedir()) {
|
|
60
|
+
const root = join(home, '.config', 'herdr', 'sessions');
|
|
61
|
+
try {
|
|
62
|
+
const names = await readdir(root);
|
|
63
|
+
return names.map((name) => ({ name, socket: join(root, name, 'herdr.sock') }));
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export async function herdrPanes(socketPath) {
|
|
70
|
+
const result = await herdrCall(socketPath, 'session.snapshot');
|
|
71
|
+
return result.snapshot.panes;
|
|
72
|
+
}
|
|
73
|
+
/** Whether this process runs under a shared agent daemon such as the Codex app-server, whose HERDR_PANE_ID is not the agent's. */
|
|
74
|
+
export async function underSharedDaemon(pid = process.ppid) {
|
|
75
|
+
for (let current = pid, depth = 0; current > 1 && depth < 64; depth++) {
|
|
76
|
+
try {
|
|
77
|
+
const args = (await readFile(`/proc/${current}/cmdline`, 'utf8')).split('\0').join(' ');
|
|
78
|
+
if (args.includes('codex') && args.split(/\s+/).includes('app-server'))
|
|
79
|
+
return true;
|
|
80
|
+
const stat = await readFile(`/proc/${current}/stat`, 'utf8');
|
|
81
|
+
current = Number(stat.slice(stat.lastIndexOf(')') + 2).split(' ')[1]);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
/** The session-id variables that agent runtimes export to their tool processes. */
|
|
90
|
+
const SESSION_VARIABLES = [
|
|
91
|
+
['claude', 'CLAUDE_CODE_SESSION_ID'],
|
|
92
|
+
['codex', 'CODEX_SESSION_ID'],
|
|
93
|
+
];
|
|
94
|
+
/**
|
|
95
|
+
* Finds the caller's herdr pane, in the order of _Agent_Claim_Command_: `--pane`, then the pane whose
|
|
96
|
+
* recorded agent session is the caller's session id, then HERDR_PANE_ID unless under a shared daemon.
|
|
97
|
+
*/
|
|
98
|
+
export async function resolveAgentPane(env, options = {}) {
|
|
99
|
+
const sessions = (await herdrSessions(env.HOME)).filter((s) => !options.herdrSession || s.name === options.herdrSession);
|
|
100
|
+
if (!sessions.length)
|
|
101
|
+
throw new AdocError('claim.herdr', 'No herdr session found on this computer; adoc agent claim needs herdr.');
|
|
102
|
+
const inSession = async (paneId, preferred) => {
|
|
103
|
+
const ordered = preferred ? [...sessions.filter((s) => s.socket === preferred), ...sessions.filter((s) => s.socket !== preferred)] : sessions;
|
|
104
|
+
for (const session of ordered) {
|
|
105
|
+
const pane = (await herdrPanes(session.socket).catch(() => [])).find((p) => p.pane_id === paneId);
|
|
106
|
+
if (pane)
|
|
107
|
+
return { session, pane };
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
};
|
|
111
|
+
if (options.pane) {
|
|
112
|
+
const found = await inSession(options.pane, env.HERDR_SOCKET_PATH);
|
|
113
|
+
if (!found)
|
|
114
|
+
throw new AdocError('claim.pane', `No herdr pane ${options.pane}.`);
|
|
115
|
+
return { herdrSession: found.session.name, socket: found.session.socket, pane: found.pane, via: 'option' };
|
|
116
|
+
}
|
|
117
|
+
for (const [, variable] of SESSION_VARIABLES) {
|
|
118
|
+
const id = env[variable];
|
|
119
|
+
if (!id)
|
|
120
|
+
continue;
|
|
121
|
+
for (const session of sessions) {
|
|
122
|
+
const pane = (await herdrPanes(session.socket).catch(() => [])).find((p) => p.agent_session?.value === id);
|
|
123
|
+
if (pane)
|
|
124
|
+
return { herdrSession: session.name, socket: session.socket, pane, via: 'session-id' };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (env.HERDR_PANE_ID && !(await underSharedDaemon())) {
|
|
128
|
+
const found = await inSession(env.HERDR_PANE_ID, env.HERDR_SOCKET_PATH);
|
|
129
|
+
if (found)
|
|
130
|
+
return { herdrSession: found.session.name, socket: found.session.socket, pane: found.pane, via: 'environment' };
|
|
131
|
+
}
|
|
132
|
+
throw new AdocError('claim.unknown', 'Cannot tell which herdr pane this agent runs in; run adoc agent claim --pane <pane id> (see herdr pane list).');
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=herdr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr.js","sourceRoot":"","sources":["../src/herdr.ts"],"names":[],"mappings":"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"}
|
package/dist/home.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const HOME_DIRECTORY = ".adoc";
|
|
2
|
+
export declare const HOME_VARIABLE = "ADOC_HOME";
|
|
3
|
+
export declare const CONFIG_FILE = "adoc.yaml";
|
|
4
|
+
/** A selected _Adoc_Home_ and the _Adoc_Workspace_ that holds it. */
|
|
5
|
+
export interface AdocHome {
|
|
6
|
+
readonly home: string;
|
|
7
|
+
readonly workspace: string;
|
|
8
|
+
readonly configPath: string;
|
|
9
|
+
readonly origin: 'option' | 'environment' | 'ancestor';
|
|
10
|
+
}
|
|
11
|
+
/** Selects the _Adoc_Home_: `--home`, then `ADOC_HOME`, then the nearest `.adoc` from `cwd` upward. */
|
|
12
|
+
export declare function discoverHome(cwd: string, explicit?: string, env?: NodeJS.ProcessEnv): Promise<AdocHome>;
|
package/dist/home.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { stat } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { AdocError } from './errors.js';
|
|
4
|
+
export const HOME_DIRECTORY = '.adoc';
|
|
5
|
+
export const HOME_VARIABLE = 'ADOC_HOME';
|
|
6
|
+
export const CONFIG_FILE = 'adoc.yaml';
|
|
7
|
+
async function isDirectory(path) {
|
|
8
|
+
try {
|
|
9
|
+
return (await stat(path)).isDirectory();
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function select(path, origin, cwd) {
|
|
16
|
+
const home = resolve(cwd, path);
|
|
17
|
+
return { home, workspace: dirname(home), configPath: join(home, CONFIG_FILE), origin };
|
|
18
|
+
}
|
|
19
|
+
/** Selects the _Adoc_Home_: `--home`, then `ADOC_HOME`, then the nearest `.adoc` from `cwd` upward. */
|
|
20
|
+
export async function discoverHome(cwd, explicit, env = process.env) {
|
|
21
|
+
if (explicit !== undefined) {
|
|
22
|
+
const selected = select(explicit, 'option', cwd);
|
|
23
|
+
if (!(await isDirectory(selected.home)))
|
|
24
|
+
throw new AdocError('home.missing', `--home ${explicit} is not a directory.`);
|
|
25
|
+
return selected;
|
|
26
|
+
}
|
|
27
|
+
const variable = env[HOME_VARIABLE];
|
|
28
|
+
if (variable !== undefined && variable.trim() !== '') {
|
|
29
|
+
const selected = select(variable, 'environment', cwd);
|
|
30
|
+
if (!(await isDirectory(selected.home)))
|
|
31
|
+
throw new AdocError('home.missing', `${HOME_VARIABLE}=${variable} is not a directory.`);
|
|
32
|
+
return selected;
|
|
33
|
+
}
|
|
34
|
+
for (let directory = resolve(cwd);; directory = dirname(directory)) {
|
|
35
|
+
const candidate = join(directory, HOME_DIRECTORY);
|
|
36
|
+
if (await isDirectory(candidate))
|
|
37
|
+
return select(candidate, 'ancestor', cwd);
|
|
38
|
+
if (dirname(directory) === directory)
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
throw new AdocError('home.missing', `No ${HOME_DIRECTORY} directory from ${cwd} upward; run adoc init.`);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=home.js.map
|
package/dist/home.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"home.js","sourceRoot":"","sources":["../src/home.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AAUvC,KAAK,UAAU,WAAW,CAAC,IAAY;IACrC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,MAA0B,EAAE,GAAW;IACnE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;AACzF,CAAC;AAED,uGAAuG;AACvG,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,QAAiB,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG;IACrG,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,cAAc,EAAE,UAAU,QAAQ,sBAAsB,CAAC,CAAC;QACvH,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,cAAc,EAAE,GAAG,aAAa,IAAI,QAAQ,sBAAsB,CAAC,CAAC;QACjI,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,KAAK,IAAI,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,GAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACpE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAClD,IAAI,MAAM,WAAW,CAAC,SAAS,CAAC;YAAE,OAAO,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAC5E,IAAI,OAAO,CAAC,SAAS,CAAC,KAAK,SAAS;YAAE,MAAM;IAC9C,CAAC;IACD,MAAM,IAAI,SAAS,CAAC,cAAc,EAAE,MAAM,cAAc,mBAAmB,GAAG,yBAAyB,CAAC,CAAC;AAC3G,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { AdocError, errorMessage } from './errors.js';
|
|
2
|
+
export { discoverHome, HOME_DIRECTORY, HOME_VARIABLE, CONFIG_FILE, type AdocHome } from './home.js';
|
|
3
|
+
export { readConfig, userConfigPath, CONFIG_TEMPLATE, type AdocConfig, type DeclaredPlugin, type TransportConfig } from './config.js';
|
|
4
|
+
export { PLUGIN_KEY_PATTERN, LOCAL_ID_PATTERN, parseDocumentTarget } from './names.js';
|
|
5
|
+
export { loadPlugins, pluginDirectory, parseGithubSource, fetchedFolder, readSkillSource, scopeOf, type GithubSource, type LoadedPlugin, type Scope, type SkillSource } from './plugins.js';
|
|
6
|
+
export { fetchGithubPlugins, folderHash, type FetchOutcome } from './fetch.js';
|
|
7
|
+
export { scanDocuments, readDocument, type DocumentRecord, type ScanProblem } from './scan.js';
|
|
8
|
+
export { Workspace, type SummaryEntry, type DocumentView, type CheckEntry, type PluginInfo, type ActionOutcome, type DocumentChanges, type StoredVersion } from './workspace.js';
|
|
9
|
+
export { MessageQueue, formatMessage, formatMessages, formatTarget, messageFields, type UserMessage, type UserComment, type MessageTarget } from './messages.js';
|
|
10
|
+
export { createTransport, attachTransport, type MessageTransport, type ClaimSource } from './transports.js';
|
|
11
|
+
export { readClaim, writeClaim, removeClaim, claimPath, CLAIM_FILE, type AgentClaim } from './claim.js';
|
|
12
|
+
export { herdrCall, herdrSubscribe, herdrSessions, herdrPanes, resolveAgentPane, underSharedDaemon, type HerdrPane, type ResolvedPane } from './herdr.js';
|
|
13
|
+
export { AdocServer, PROTOCOL, publicMessage, type BrowserSession, type ServerExtension, type ServerOptions } from './server.js';
|
|
14
|
+
export { readServerRecord, type ServerRecord } from './registry.js';
|
|
15
|
+
export { ServerClient } from './client.js';
|
|
16
|
+
export { formatCheck } from './report.js';
|
|
17
|
+
export { isGitRepository } from './git.js';
|
|
18
|
+
export { listSkills, viewSkill, installSkills, uninstallSkills, checkSkills, readSkillFile, editSkillFile, type SkillEntry, type SkillInstallOptions } from './skills.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { AdocError, errorMessage } from './errors.js';
|
|
2
|
+
export { discoverHome, HOME_DIRECTORY, HOME_VARIABLE, CONFIG_FILE } from './home.js';
|
|
3
|
+
export { readConfig, userConfigPath, CONFIG_TEMPLATE } from './config.js';
|
|
4
|
+
export { PLUGIN_KEY_PATTERN, LOCAL_ID_PATTERN, parseDocumentTarget } from './names.js';
|
|
5
|
+
export { loadPlugins, pluginDirectory, parseGithubSource, fetchedFolder, readSkillSource, scopeOf } from './plugins.js';
|
|
6
|
+
export { fetchGithubPlugins, folderHash } from './fetch.js';
|
|
7
|
+
export { scanDocuments, readDocument } from './scan.js';
|
|
8
|
+
export { Workspace } from './workspace.js';
|
|
9
|
+
export { MessageQueue, formatMessage, formatMessages, formatTarget, messageFields } from './messages.js';
|
|
10
|
+
export { createTransport, attachTransport } from './transports.js';
|
|
11
|
+
export { readClaim, writeClaim, removeClaim, claimPath, CLAIM_FILE } from './claim.js';
|
|
12
|
+
export { herdrCall, herdrSubscribe, herdrSessions, herdrPanes, resolveAgentPane, underSharedDaemon } from './herdr.js';
|
|
13
|
+
export { AdocServer, PROTOCOL, publicMessage } from './server.js';
|
|
14
|
+
export { readServerRecord } from './registry.js';
|
|
15
|
+
export { ServerClient } from './client.js';
|
|
16
|
+
export { formatCheck } from './report.js';
|
|
17
|
+
export { isGitRepository } from './git.js';
|
|
18
|
+
export { listSkills, viewSkill, installSkills, uninstallSkills, checkSkills, readSkillFile, editSkillFile } from './skills.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAiB,MAAM,WAAW,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAA8D,MAAM,aAAa,CAAC;AACtI,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO,EAAsE,MAAM,cAAc,CAAC;AAC5L,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAqB,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAyC,MAAM,WAAW,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAwI,MAAM,gBAAgB,CAAC;AACjL,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAA0D,MAAM,eAAe,CAAC;AACjK,OAAO,EAAE,eAAe,EAAE,eAAe,EAA2C,MAAM,iBAAiB,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAC;AACxG,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAqC,MAAM,YAAY,CAAC;AAC1J,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAiE,MAAM,aAAa,CAAC;AACjI,OAAO,EAAE,gBAAgB,EAAqB,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAA6C,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
/** _User_Message_Target_: one of five levels. */
|
|
3
|
+
export type MessageTarget = {
|
|
4
|
+
level: 'workspace';
|
|
5
|
+
} | {
|
|
6
|
+
level: 'plugin';
|
|
7
|
+
pluginKey: string;
|
|
8
|
+
} | {
|
|
9
|
+
level: 'document';
|
|
10
|
+
key: string;
|
|
11
|
+
} | {
|
|
12
|
+
level: 'anchor';
|
|
13
|
+
key: string;
|
|
14
|
+
anchor: string;
|
|
15
|
+
} | {
|
|
16
|
+
level: 'skill';
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
19
|
+
/** One _User_Comment_ inside a comment message. */
|
|
20
|
+
export interface UserComment {
|
|
21
|
+
target: MessageTarget;
|
|
22
|
+
text: string;
|
|
23
|
+
quote?: string;
|
|
24
|
+
source?: string;
|
|
25
|
+
}
|
|
26
|
+
/** A _User_Comment_Message_: the composer text with its target, and the draft comments, in the order added. */
|
|
27
|
+
export interface CommentInput {
|
|
28
|
+
target?: MessageTarget;
|
|
29
|
+
text?: string;
|
|
30
|
+
comments: UserComment[];
|
|
31
|
+
}
|
|
32
|
+
export interface ActionMessageInput {
|
|
33
|
+
target: MessageTarget;
|
|
34
|
+
action: string;
|
|
35
|
+
value: string;
|
|
36
|
+
to?: string;
|
|
37
|
+
applied: boolean;
|
|
38
|
+
text: string;
|
|
39
|
+
}
|
|
40
|
+
/** A held _User_Message_. */
|
|
41
|
+
export type UserMessage = ({
|
|
42
|
+
number: number;
|
|
43
|
+
kind: 'comment';
|
|
44
|
+
createdAt: string;
|
|
45
|
+
} & CommentInput) | ({
|
|
46
|
+
number: number;
|
|
47
|
+
kind: 'action';
|
|
48
|
+
createdAt: string;
|
|
49
|
+
} & ActionMessageInput);
|
|
50
|
+
export declare function formatTarget(target: MessageTarget): string;
|
|
51
|
+
/** The structured fields of a message, in _User_Message_Format_ order. */
|
|
52
|
+
export declare function messageFields(message: UserMessage): Record<string, unknown>;
|
|
53
|
+
/** Renders one message in _User_Message_Format_: the header line, the main text, then attached YAML fields after `--`. */
|
|
54
|
+
export declare function formatMessage(message: UserMessage): string;
|
|
55
|
+
export declare function formatMessages(messages: readonly UserMessage[]): string;
|
|
56
|
+
/**
|
|
57
|
+
* Holds every _User_Message_ until it is delivered, in creation order.
|
|
58
|
+
* Emits `change` whenever the held set changes.
|
|
59
|
+
*/
|
|
60
|
+
export declare class MessageQueue extends EventEmitter {
|
|
61
|
+
private next;
|
|
62
|
+
private held;
|
|
63
|
+
private waiters;
|
|
64
|
+
add(input: ({
|
|
65
|
+
kind: 'comment';
|
|
66
|
+
} & CommentInput) | ({
|
|
67
|
+
kind: 'action';
|
|
68
|
+
} & ActionMessageInput)): UserMessage;
|
|
69
|
+
list(): UserMessage[];
|
|
70
|
+
/** Removes and returns every held message. */
|
|
71
|
+
takeAll(): UserMessage[];
|
|
72
|
+
/** Removes the given messages after a push transport delivered them. */
|
|
73
|
+
markDelivered(numbers: readonly number[]): void;
|
|
74
|
+
/** Waits until at least one message is held, then takes all of them; resolves with [] after `timeoutMs`. */
|
|
75
|
+
wait(timeoutMs?: number, signal?: AbortSignal): Promise<UserMessage[]>;
|
|
76
|
+
}
|
package/dist/messages.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { stringify } from 'yaml';
|
|
3
|
+
export function formatTarget(target) {
|
|
4
|
+
switch (target.level) {
|
|
5
|
+
case 'workspace':
|
|
6
|
+
return 'workspace';
|
|
7
|
+
case 'plugin':
|
|
8
|
+
return target.pluginKey;
|
|
9
|
+
case 'document':
|
|
10
|
+
return target.key;
|
|
11
|
+
case 'anchor':
|
|
12
|
+
return `${target.key}#${target.anchor}`;
|
|
13
|
+
case 'skill':
|
|
14
|
+
return `skill ${target.name}`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** The structured fields of a message, in _User_Message_Format_ order. */
|
|
18
|
+
export function messageFields(message) {
|
|
19
|
+
const fields = { number: message.number, kind: message.kind };
|
|
20
|
+
if (message.kind === 'comment') {
|
|
21
|
+
if (message.target)
|
|
22
|
+
fields.target = formatTarget(message.target);
|
|
23
|
+
if (message.text)
|
|
24
|
+
fields.text = message.text;
|
|
25
|
+
if (message.comments.length)
|
|
26
|
+
fields.comments = message.comments.map((comment) => {
|
|
27
|
+
const entry = { target: formatTarget(comment.target) };
|
|
28
|
+
if (comment.source)
|
|
29
|
+
entry.source = comment.source;
|
|
30
|
+
if (comment.quote)
|
|
31
|
+
entry.quote = comment.quote;
|
|
32
|
+
entry.text = comment.text;
|
|
33
|
+
return entry;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
fields.target = formatTarget(message.target);
|
|
38
|
+
fields.action = message.action;
|
|
39
|
+
fields.value = message.value;
|
|
40
|
+
if (message.to !== undefined)
|
|
41
|
+
fields.to = message.to;
|
|
42
|
+
fields.applied = message.applied;
|
|
43
|
+
fields.text = message.text;
|
|
44
|
+
}
|
|
45
|
+
return fields;
|
|
46
|
+
}
|
|
47
|
+
/** Renders one message in _User_Message_Format_: the header line, the main text, then attached YAML fields after `--`. */
|
|
48
|
+
export function formatMessage(message) {
|
|
49
|
+
const { number, kind, target, text, ...attached } = messageFields(message);
|
|
50
|
+
const header = `[adoc message ${number}] ${kind}${target ? ` · ${target}` : ''}`;
|
|
51
|
+
const body = typeof text === 'string' && text ? `${text.replace(/\s+$/, '')}\n` : '';
|
|
52
|
+
const attachments = Object.keys(attached).length ? `--\n${stringify(attached, { lineWidth: 0, blockQuote: 'literal' })}` : '';
|
|
53
|
+
return `${header}\n${body}${attachments}`;
|
|
54
|
+
}
|
|
55
|
+
export function formatMessages(messages) {
|
|
56
|
+
return messages.map(formatMessage).join('\n');
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Holds every _User_Message_ until it is delivered, in creation order.
|
|
60
|
+
* Emits `change` whenever the held set changes.
|
|
61
|
+
*/
|
|
62
|
+
export class MessageQueue extends EventEmitter {
|
|
63
|
+
next = 1;
|
|
64
|
+
held = [];
|
|
65
|
+
waiters = [];
|
|
66
|
+
add(input) {
|
|
67
|
+
const message = { ...input, number: this.next++, createdAt: new Date().toISOString() };
|
|
68
|
+
this.held.push(message);
|
|
69
|
+
this.emit('change');
|
|
70
|
+
this.emit('added', message);
|
|
71
|
+
for (const wake of this.waiters.splice(0))
|
|
72
|
+
wake();
|
|
73
|
+
return message;
|
|
74
|
+
}
|
|
75
|
+
list() {
|
|
76
|
+
return [...this.held];
|
|
77
|
+
}
|
|
78
|
+
/** Removes and returns every held message. */
|
|
79
|
+
takeAll() {
|
|
80
|
+
const taken = this.held;
|
|
81
|
+
this.held = [];
|
|
82
|
+
if (taken.length)
|
|
83
|
+
this.emit('change');
|
|
84
|
+
return taken;
|
|
85
|
+
}
|
|
86
|
+
/** Removes the given messages after a push transport delivered them. */
|
|
87
|
+
markDelivered(numbers) {
|
|
88
|
+
const before = this.held.length;
|
|
89
|
+
this.held = this.held.filter((m) => !numbers.includes(m.number));
|
|
90
|
+
if (this.held.length !== before)
|
|
91
|
+
this.emit('change');
|
|
92
|
+
}
|
|
93
|
+
/** Waits until at least one message is held, then takes all of them; resolves with [] after `timeoutMs`. */
|
|
94
|
+
async wait(timeoutMs, signal) {
|
|
95
|
+
if (this.held.length)
|
|
96
|
+
return this.takeAll();
|
|
97
|
+
return new Promise((resolve) => {
|
|
98
|
+
let timer;
|
|
99
|
+
const finish = () => {
|
|
100
|
+
clearTimeout(timer);
|
|
101
|
+
this.waiters = this.waiters.filter((w) => w !== wake);
|
|
102
|
+
signal?.removeEventListener('abort', abort);
|
|
103
|
+
};
|
|
104
|
+
const wake = () => {
|
|
105
|
+
finish();
|
|
106
|
+
resolve(this.takeAll());
|
|
107
|
+
};
|
|
108
|
+
const abort = () => {
|
|
109
|
+
finish();
|
|
110
|
+
resolve([]);
|
|
111
|
+
};
|
|
112
|
+
this.waiters.push(wake);
|
|
113
|
+
signal?.addEventListener('abort', abort);
|
|
114
|
+
if (timeoutMs !== undefined)
|
|
115
|
+
timer = setTimeout(abort, timeoutMs);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}
|
package/dist/names.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** _Plugin_Key_: uppercase letters only. */
|
|
2
|
+
export declare const PLUGIN_KEY_PATTERN: RegExp;
|
|
3
|
+
/** _Document_Local_ID_: lowercase letters, digits, hyphens, underscores and dots. */
|
|
4
|
+
export declare const LOCAL_ID_PATTERN: RegExp;
|
|
5
|
+
/** A file or folder name that starts like a _Document_Key_. */
|
|
6
|
+
export declare const KEY_PREFIX_PATTERN: RegExp;
|
|
7
|
+
export interface ParsedTarget {
|
|
8
|
+
key: string;
|
|
9
|
+
pluginKey: string;
|
|
10
|
+
localId: string;
|
|
11
|
+
anchor?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Parses `TASK-1231` or `TASK-1231#method`. Returns undefined when the text is not a document key. */
|
|
14
|
+
export declare function parseDocumentTarget(text: string): ParsedTarget | undefined;
|
package/dist/names.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** _Plugin_Key_: uppercase letters only. */
|
|
2
|
+
export const PLUGIN_KEY_PATTERN = /^[A-Z]+$/;
|
|
3
|
+
/** _Document_Local_ID_: lowercase letters, digits, hyphens, underscores and dots. */
|
|
4
|
+
export const LOCAL_ID_PATTERN = /^[a-z0-9._-]+$/;
|
|
5
|
+
/** A file or folder name that starts like a _Document_Key_. */
|
|
6
|
+
export const KEY_PREFIX_PATTERN = /^([A-Z]+)-(.+)$/;
|
|
7
|
+
/** Parses `TASK-1231` or `TASK-1231#method`. Returns undefined when the text is not a document key. */
|
|
8
|
+
export function parseDocumentTarget(text) {
|
|
9
|
+
const hash = text.indexOf('#');
|
|
10
|
+
const key = hash < 0 ? text : text.slice(0, hash);
|
|
11
|
+
const match = KEY_PREFIX_PATTERN.exec(key);
|
|
12
|
+
if (!match || !LOCAL_ID_PATTERN.test(match[2]))
|
|
13
|
+
return undefined;
|
|
14
|
+
const parsed = { key, pluginKey: match[1], localId: match[2] };
|
|
15
|
+
if (hash >= 0)
|
|
16
|
+
parsed.anchor = text.slice(hash + 1);
|
|
17
|
+
return parsed;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAC7C,qFAAqF;AACrF,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AACjD,+DAA+D;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AASpD,uGAAuG;AACvG,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,MAAM,GAAiB,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC;IAC/E,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IACpD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { PluginDefinition } from '@agent-workshop/adoc-plugin-kit';
|
|
2
|
+
import type { AdocConfig, DeclaredPlugin } from './config.js';
|
|
3
|
+
import type { AdocHome } from './home.js';
|
|
4
|
+
/** Project scope: inside the _Adoc_Workspace_; user scope: anywhere else, such as the user _Plugin_Directory_ or adoc's installation. */
|
|
5
|
+
export type Scope = 'project' | 'user';
|
|
6
|
+
/** An _Agent_Skill_ folder: `skill/` with a `SKILL.md` whose front matter names it. */
|
|
7
|
+
export interface SkillSource {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly description: string;
|
|
10
|
+
readonly directory: string;
|
|
11
|
+
readonly scope: Scope;
|
|
12
|
+
}
|
|
13
|
+
/** One declared _Plugin_, loaded or failed. */
|
|
14
|
+
export interface LoadedPlugin {
|
|
15
|
+
readonly key: string;
|
|
16
|
+
/** The _Plugin_Source_ as declared. */
|
|
17
|
+
readonly source: string;
|
|
18
|
+
/** The plugin folder, when its entry was found. */
|
|
19
|
+
readonly directory?: string;
|
|
20
|
+
readonly definition?: PluginDefinition;
|
|
21
|
+
/** The _Plugin_Skill_. */
|
|
22
|
+
readonly skill?: SkillSource;
|
|
23
|
+
readonly error?: string;
|
|
24
|
+
}
|
|
25
|
+
/** The _Plugin_Directory_ next to the config file whose folder is `base`. */
|
|
26
|
+
export declare function pluginDirectory(base: string): string;
|
|
27
|
+
/** A parsed GitHub _Plugin_Source_. */
|
|
28
|
+
export interface GithubSource {
|
|
29
|
+
readonly owner: string;
|
|
30
|
+
readonly repo: string;
|
|
31
|
+
/** The folder inside the repository; empty for its root. */
|
|
32
|
+
readonly folder: string;
|
|
33
|
+
readonly ref?: string;
|
|
34
|
+
}
|
|
35
|
+
/** `github:<owner>/<repo>[/<folder>][#<ref>]`, or undefined for any other source. */
|
|
36
|
+
export declare function parseGithubSource(source: string): GithubSource | undefined;
|
|
37
|
+
/** The folder a GitHub _Plugin_Source_ is fetched to: the plugin key in lowercase, in the _Plugin_Directory_. */
|
|
38
|
+
export declare function fetchedFolder(plugin: DeclaredPlugin): string;
|
|
39
|
+
export declare function scopeOf(home: AdocHome, path: string): Scope;
|
|
40
|
+
/** Reads the `skill/SKILL.md` of an owner folder; throws when it is missing or has no name and description. */
|
|
41
|
+
export declare function readSkillSource(owner: string, scope: Scope): Promise<SkillSource>;
|
|
42
|
+
/** Loads every plugin declared in the _Adoc_Config_. A failure is kept as the plugin's error, never thrown. */
|
|
43
|
+
export declare function loadPlugins(home: AdocHome, config: AdocConfig, fresh?: boolean): Promise<Map<string, LoadedPlugin>>;
|