document360-writer 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 +21 -0
- package/README.md +66 -0
- package/dist/agent.d.ts +6 -0
- package/dist/agent.js +92 -0
- package/dist/agent.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/audit.d.ts +2 -0
- package/dist/commands/audit.js +12 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/clear.d.ts +2 -0
- package/dist/commands/clear.js +6 -0
- package/dist/commands/clear.js.map +1 -0
- package/dist/commands/exit.d.ts +2 -0
- package/dist/commands/exit.js +4 -0
- package/dist/commands/exit.js.map +1 -0
- package/dist/commands/help.d.ts +2 -0
- package/dist/commands/help.js +27 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/index.d.ts +18 -0
- package/dist/commands/index.js +38 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +85 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/load.d.ts +2 -0
- package/dist/commands/load.js +20 -0
- package/dist/commands/load.js.map +1 -0
- package/dist/commands/mcp.d.ts +2 -0
- package/dist/commands/mcp.js +83 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/publish.d.ts +2 -0
- package/dist/commands/publish.js +19 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/save.d.ts +2 -0
- package/dist/commands/save.js +29 -0
- package/dist/commands/save.js.map +1 -0
- package/dist/commands/screenshot.d.ts +2 -0
- package/dist/commands/screenshot.js +20 -0
- package/dist/commands/screenshot.js.map +1 -0
- package/dist/config.d.ts +40 -0
- package/dist/config.js +42 -0
- package/dist/config.js.map +1 -0
- package/dist/lib/colors.d.ts +8 -0
- package/dist/lib/colors.js +10 -0
- package/dist/lib/colors.js.map +1 -0
- package/dist/lib/messageQueue.d.ts +9 -0
- package/dist/lib/messageQueue.js +40 -0
- package/dist/lib/messageQueue.js.map +1 -0
- package/dist/lib/paths.d.ts +10 -0
- package/dist/lib/paths.js +38 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/repl.d.ts +5 -0
- package/dist/repl.js +132 -0
- package/dist/repl.js.map +1 -0
- package/package.json +54 -0
- package/skills/CLAUDE.md +92 -0
- package/skills/analyze-codebase/SKILL.md +35 -0
- package/skills/audit-docs/SKILL.md +48 -0
- package/skills/emit-screenshot-spec/SKILL.md +82 -0
- package/skills/gather-context-from-mcp/SKILL.md +29 -0
- package/skills/propose-structure/SKILL.md +51 -0
- package/skills/publish-to-d360/SKILL.md +39 -0
- package/skills/write-article/SKILL.md +93 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Saravana Kumar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# document360-writer
|
|
2
|
+
|
|
3
|
+
Standalone documentation agent CLI. Reads your code, writes your docs, dual-publishes to Document360.
|
|
4
|
+
|
|
5
|
+
Built atop Anthropic's [Claude Agent SDK](https://docs.claude.com/en/docs/claude-code/agent-sdk). Modeled after Claude Code's UX (REPL + slash commands + MCP) but specialized for technical writing.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g document360-writer
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Aliases: the canonical binary is `document360-writer`; `d360-writer` is registered as a short alias.
|
|
14
|
+
|
|
15
|
+
## Setup
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
19
|
+
cd <your-repo>
|
|
20
|
+
d360-writer /init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`/init` writes a `.d360-writer.json` project config (D360 project ID, captureDir, outputDir, terminology) at the repo root.
|
|
24
|
+
|
|
25
|
+
## Use
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
d360-writer # start interactive REPL
|
|
29
|
+
> analyze this repo and propose a docs structure
|
|
30
|
+
> write the install guide
|
|
31
|
+
> /publish 01-getting-started/01-install.md
|
|
32
|
+
> /audit
|
|
33
|
+
> /screenshot variables-page-with-profiles
|
|
34
|
+
> /save my-feature-docs
|
|
35
|
+
> /exit
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Slash commands
|
|
39
|
+
|
|
40
|
+
| Command | Description |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `/help` | List available commands |
|
|
43
|
+
| `/init` | Scaffold `.d360-writer.json` in the current repo |
|
|
44
|
+
| `/mcp add <name> <transport> <command-or-url>` | Register an MCP server (D360, Notion, GitHub, etc.) |
|
|
45
|
+
| `/mcp list` | Show registered MCP servers |
|
|
46
|
+
| `/mcp remove <name>` | Remove an MCP server |
|
|
47
|
+
| `/publish <article-path>` | Publish one article to Document360 |
|
|
48
|
+
| `/audit` | Diff code vs existing docs, flag gaps |
|
|
49
|
+
| `/screenshot <id>` | Emit a [`document360-capture`](../capture/)-compatible spec |
|
|
50
|
+
| `/save <name>` | Checkpoint current session |
|
|
51
|
+
| `/load <name>` | Resume a saved session |
|
|
52
|
+
| `/clear` | Reset conversation |
|
|
53
|
+
| `/exit` | Quit |
|
|
54
|
+
|
|
55
|
+
## Storage
|
|
56
|
+
|
|
57
|
+
- `<repo>/.d360-writer.json` — project config (committed)
|
|
58
|
+
- `<repo>/.d360-writer/` — optional per-repo skill overrides
|
|
59
|
+
- `<repo>/d360-category-map.json` — D360 article ID round-trip (committed)
|
|
60
|
+
- `~/.document360-writer/config.json` — global preferences
|
|
61
|
+
- `~/.document360-writer/mcp.json` — user-wide MCP server registrations
|
|
62
|
+
- `~/.document360-writer/sessions/<id>.jsonl` — session history
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT
|
package/dist/agent.d.ts
ADDED
package/dist/agent.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
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
|
+
const MASTER_PROMPT_FILE = 'CLAUDE.md';
|
|
8
|
+
function readSkillFiles(dir) {
|
|
9
|
+
if (!existsSync(dir))
|
|
10
|
+
return [];
|
|
11
|
+
const out = [];
|
|
12
|
+
for (const entry of readdirSync(dir)) {
|
|
13
|
+
const sub = join(dir, entry);
|
|
14
|
+
if (entry === MASTER_PROMPT_FILE)
|
|
15
|
+
continue;
|
|
16
|
+
if (!statSync(sub).isDirectory())
|
|
17
|
+
continue;
|
|
18
|
+
const skillFile = join(sub, 'SKILL.md');
|
|
19
|
+
if (!existsSync(skillFile))
|
|
20
|
+
continue;
|
|
21
|
+
out.push({ name: entry, body: readFileSync(skillFile, 'utf8') });
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
function readMasterPrompt(dir) {
|
|
26
|
+
const path = join(dir, MASTER_PROMPT_FILE);
|
|
27
|
+
return existsSync(path) ? readFileSync(path, 'utf8') : null;
|
|
28
|
+
}
|
|
29
|
+
function buildSystemPrompt(cwd, cfg) {
|
|
30
|
+
const packageDir = packageSkillsDir();
|
|
31
|
+
const projectDir = projectSkillsDir(cwd);
|
|
32
|
+
const masterPackage = readMasterPrompt(packageDir);
|
|
33
|
+
const masterProject = readMasterPrompt(projectDir);
|
|
34
|
+
const packageSkills = readSkillFiles(packageDir);
|
|
35
|
+
const projectSkills = readSkillFiles(projectDir);
|
|
36
|
+
const projectSkillNames = new Set(projectSkills.map(s => s.name));
|
|
37
|
+
const merged = [...packageSkills.filter(s => !projectSkillNames.has(s.name)), ...projectSkills];
|
|
38
|
+
const parts = [];
|
|
39
|
+
if (masterPackage)
|
|
40
|
+
parts.push(masterPackage);
|
|
41
|
+
if (masterProject)
|
|
42
|
+
parts.push(`# Project addendum\n\n${masterProject}`);
|
|
43
|
+
if (cfg) {
|
|
44
|
+
parts.push('# Project configuration');
|
|
45
|
+
parts.push('```json');
|
|
46
|
+
parts.push(JSON.stringify(cfg, null, 2));
|
|
47
|
+
parts.push('```');
|
|
48
|
+
}
|
|
49
|
+
if (merged.length > 0) {
|
|
50
|
+
parts.push('# Capabilities');
|
|
51
|
+
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.');
|
|
52
|
+
for (const s of merged) {
|
|
53
|
+
parts.push(`## Skill: ${s.name}`);
|
|
54
|
+
parts.push(s.body);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return parts.join('\n\n');
|
|
58
|
+
}
|
|
59
|
+
function toSdkMcpServers() {
|
|
60
|
+
const mcp = readMcpConfig();
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const [name, entry] of Object.entries(mcp.servers)) {
|
|
63
|
+
if (entry.type === 'stdio') {
|
|
64
|
+
out[name] = { type: 'stdio', command: entry.command, args: entry.args, env: entry.env };
|
|
65
|
+
}
|
|
66
|
+
else if (entry.type === 'http') {
|
|
67
|
+
out[name] = { type: 'http', url: entry.url, headers: entry.headers };
|
|
68
|
+
}
|
|
69
|
+
else if (entry.type === 'sse') {
|
|
70
|
+
out[name] = { type: 'sse', url: entry.url, headers: entry.headers };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
export function startAgent(cwd = process.cwd()) {
|
|
76
|
+
const cfg = readProjectConfig(cwd);
|
|
77
|
+
const systemPrompt = buildSystemPrompt(cwd, cfg);
|
|
78
|
+
const mcpServers = toSdkMcpServers();
|
|
79
|
+
const queue = new UserMessageQueue();
|
|
80
|
+
const options = {
|
|
81
|
+
cwd,
|
|
82
|
+
systemPrompt,
|
|
83
|
+
mcpServers,
|
|
84
|
+
permissionMode: 'bypassPermissions',
|
|
85
|
+
allowDangerouslySkipPermissions: true,
|
|
86
|
+
settingSources: [],
|
|
87
|
+
model: cfg?.defaultModel,
|
|
88
|
+
};
|
|
89
|
+
const q = query({ prompt: queue, options });
|
|
90
|
+
return { queue, iterator: q[Symbol.asyncIterator]() };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { runRepl } from './repl.js';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const pkg = require('../package.json');
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name('d360-writer')
|
|
10
|
+
.description('Standalone documentation agent CLI. Reads your code, writes your docs.')
|
|
11
|
+
.version(pkg.version, '-v, --version')
|
|
12
|
+
.option('-p, --prompt <text>', 'One-shot prompt mode (non-interactive)')
|
|
13
|
+
.option('-C, --cwd <dir>', 'Working directory', process.cwd())
|
|
14
|
+
.action(async (opts) => {
|
|
15
|
+
if (opts.prompt) {
|
|
16
|
+
console.error('One-shot --prompt mode not yet implemented (v1.1). Run without --prompt for interactive REPL.');
|
|
17
|
+
process.exit(2);
|
|
18
|
+
}
|
|
19
|
+
await runRepl(opts.cwd);
|
|
20
|
+
});
|
|
21
|
+
program.parseAsync(process.argv).catch(err => {
|
|
22
|
+
console.error('');
|
|
23
|
+
console.error(`✗ ${err.message}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAE9D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,wEAAwE,CAAC;KACrF,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC;KACrC,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC7D,MAAM,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;IACnB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,+FAA+F,CAAC,CAAC;QAC/G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IAC3C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export async function auditCommand() {
|
|
2
|
+
const prompt = [
|
|
3
|
+
'Run the audit-docs skill against this repo.',
|
|
4
|
+
'',
|
|
5
|
+
'Produce a table with one row per article that needs attention:',
|
|
6
|
+
'| Article path | Action (create | update | delete) | Reason | Scope (small | medium | full) |',
|
|
7
|
+
'',
|
|
8
|
+
'Cross-reference recent commits (last 30 days or since the d360-category-map.json mtime) with the existing articles and the authoritativeSourceFiles list from .d360-writer.json. Do not start writing anything yet — just produce the audit.',
|
|
9
|
+
].join('\n');
|
|
10
|
+
return { kind: 'forward-to-agent', prompt };
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG;QACb,6CAA6C;QAC7C,EAAE;QACF,gEAAgE;QAChE,+FAA+F;QAC/F,EAAE;QACF,8OAA8O;KAC/O,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../src/commands/clear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC,CAAC;IACzF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit.js","sourceRoot":"","sources":["../../src/commands/exit.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { accent, bold, dim } from '../lib/colors.js';
|
|
2
|
+
export async function helpCommand() {
|
|
3
|
+
const lines = [
|
|
4
|
+
'',
|
|
5
|
+
bold('document360-writer — slash commands'),
|
|
6
|
+
'',
|
|
7
|
+
` ${accent('/help')} ${dim('Show this help')}`,
|
|
8
|
+
` ${accent('/init')} ${dim('Scaffold .d360-writer.json in this repo')}`,
|
|
9
|
+
` ${accent('/mcp add <name> <type> <ref>')} ${dim('Register an MCP server (stdio|http|sse)')}`,
|
|
10
|
+
` ${accent('/mcp list')} ${dim('Show registered MCP servers')}`,
|
|
11
|
+
` ${accent('/mcp remove <name>')} ${dim('Unregister an MCP server')}`,
|
|
12
|
+
` ${accent('/publish <article-path>')} ${dim('Publish one article to Document360')}`,
|
|
13
|
+
` ${accent('/audit')} ${dim('Diff code vs existing docs, flag gaps')}`,
|
|
14
|
+
` ${accent('/screenshot <id>')} ${dim('Emit a document360-capture-compatible spec')}`,
|
|
15
|
+
` ${accent('/save <name>')} ${dim('Checkpoint current session')}`,
|
|
16
|
+
` ${accent('/load <name>')} ${dim('Resume a saved session')}`,
|
|
17
|
+
` ${accent('/clear')} ${dim('Reset conversation')}`,
|
|
18
|
+
` ${accent('/exit')} ${dim('Quit')}`,
|
|
19
|
+
'',
|
|
20
|
+
dim('Anything not starting with / is sent to the agent.'),
|
|
21
|
+
'',
|
|
22
|
+
];
|
|
23
|
+
for (const l of lines)
|
|
24
|
+
console.log(l);
|
|
25
|
+
return { kind: 'continue' };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAGrD,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,KAAK,GAAG;QACZ,EAAE;QACF,IAAI,CAAC,qCAAqC,CAAC;QAC3C,EAAE;QACF,KAAK,MAAM,CAAC,OAAO,CAAC,iCAAiC,GAAG,CAAC,gBAAgB,CAAC,EAAE;QAC5E,KAAK,MAAM,CAAC,OAAO,CAAC,iCAAiC,GAAG,CAAC,yCAAyC,CAAC,EAAE;QACrG,KAAK,MAAM,CAAC,8BAA8B,CAAC,UAAU,GAAG,CAAC,yCAAyC,CAAC,EAAE;QACrG,KAAK,MAAM,CAAC,WAAW,CAAC,6BAA6B,GAAG,CAAC,6BAA6B,CAAC,EAAE;QACzF,KAAK,MAAM,CAAC,oBAAoB,CAAC,oBAAoB,GAAG,CAAC,0BAA0B,CAAC,EAAE;QACtF,KAAK,MAAM,CAAC,yBAAyB,CAAC,eAAe,GAAG,CAAC,oCAAoC,CAAC,EAAE;QAChG,KAAK,MAAM,CAAC,QAAQ,CAAC,gCAAgC,GAAG,CAAC,uCAAuC,CAAC,EAAE;QACnG,KAAK,MAAM,CAAC,kBAAkB,CAAC,sBAAsB,GAAG,CAAC,4CAA4C,CAAC,EAAE;QACxG,KAAK,MAAM,CAAC,cAAc,CAAC,0BAA0B,GAAG,CAAC,4BAA4B,CAAC,EAAE;QACxF,KAAK,MAAM,CAAC,cAAc,CAAC,0BAA0B,GAAG,CAAC,wBAAwB,CAAC,EAAE;QACpF,KAAK,MAAM,CAAC,QAAQ,CAAC,gCAAgC,GAAG,CAAC,oBAAoB,CAAC,EAAE;QAChF,KAAK,MAAM,CAAC,OAAO,CAAC,iCAAiC,GAAG,CAAC,MAAM,CAAC,EAAE;QAClE,EAAE;QACF,GAAG,CAAC,oDAAoD,CAAC;QACzD,EAAE;KACH,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReplContext } from '../repl.js';
|
|
2
|
+
export type SlashCommandResult = {
|
|
3
|
+
kind: 'continue';
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'exit';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'clear';
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'forward-to-agent';
|
|
10
|
+
prompt: string;
|
|
11
|
+
};
|
|
12
|
+
export type SlashCommand = (args: string[], ctx: ReplContext) => Promise<SlashCommandResult>;
|
|
13
|
+
export declare const slashCommands: Record<string, SlashCommand>;
|
|
14
|
+
export declare function isSlashCommand(line: string): boolean;
|
|
15
|
+
export declare function parseSlash(line: string): {
|
|
16
|
+
name: string;
|
|
17
|
+
args: string[];
|
|
18
|
+
} | null;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { helpCommand } from './help.js';
|
|
2
|
+
import { clearCommand } from './clear.js';
|
|
3
|
+
import { exitCommand } from './exit.js';
|
|
4
|
+
import { initCommand } from './init.js';
|
|
5
|
+
import { mcpCommand } from './mcp.js';
|
|
6
|
+
import { publishCommand } from './publish.js';
|
|
7
|
+
import { auditCommand } from './audit.js';
|
|
8
|
+
import { saveCommand } from './save.js';
|
|
9
|
+
import { loadCommand } from './load.js';
|
|
10
|
+
import { screenshotCommand } from './screenshot.js';
|
|
11
|
+
export const slashCommands = {
|
|
12
|
+
help: helpCommand,
|
|
13
|
+
'?': helpCommand,
|
|
14
|
+
clear: clearCommand,
|
|
15
|
+
exit: exitCommand,
|
|
16
|
+
quit: exitCommand,
|
|
17
|
+
init: initCommand,
|
|
18
|
+
mcp: mcpCommand,
|
|
19
|
+
publish: publishCommand,
|
|
20
|
+
audit: auditCommand,
|
|
21
|
+
save: saveCommand,
|
|
22
|
+
load: loadCommand,
|
|
23
|
+
screenshot: screenshotCommand,
|
|
24
|
+
};
|
|
25
|
+
export function isSlashCommand(line) {
|
|
26
|
+
return line.trim().startsWith('/');
|
|
27
|
+
}
|
|
28
|
+
export function parseSlash(line) {
|
|
29
|
+
const trimmed = line.trim();
|
|
30
|
+
if (!trimmed.startsWith('/'))
|
|
31
|
+
return null;
|
|
32
|
+
const parts = trimmed.slice(1).split(/\s+/);
|
|
33
|
+
const name = (parts[0] ?? '').toLowerCase();
|
|
34
|
+
if (!name)
|
|
35
|
+
return null;
|
|
36
|
+
return { name, args: parts.slice(1) };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAWpD,MAAM,CAAC,MAAM,aAAa,GAAiC;IACzD,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,WAAW;IAChB,KAAK,EAAE,YAAY;IACnB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,UAAU;IACf,OAAO,EAAE,cAAc;IACvB,KAAK,EAAE,YAAY;IACnB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,WAAW;IACjB,UAAU,EAAE,iBAAiB;CAC9B,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { input, confirm } from '@inquirer/prompts';
|
|
2
|
+
import { basename, join } from 'node:path';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { writeProjectConfig, readProjectConfig } from '../config.js';
|
|
5
|
+
import { projectConfigPath } from '../lib/paths.js';
|
|
6
|
+
import { ok, dim, accent } from '../lib/colors.js';
|
|
7
|
+
export async function initCommand() {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
const path = projectConfigPath(cwd);
|
|
10
|
+
if (existsSync(path)) {
|
|
11
|
+
const overwrite = await confirm({
|
|
12
|
+
message: `${path} already exists. Overwrite?`,
|
|
13
|
+
default: false,
|
|
14
|
+
});
|
|
15
|
+
if (!overwrite) {
|
|
16
|
+
console.log(dim('init cancelled.'));
|
|
17
|
+
return { kind: 'continue' };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const defaultProjectId = readPackageName(cwd) ?? basename(cwd);
|
|
21
|
+
const projectId = await input({
|
|
22
|
+
message: 'Project ID (used to scope sessions, screenshots, etc.):',
|
|
23
|
+
default: defaultProjectId,
|
|
24
|
+
});
|
|
25
|
+
const captureDir = await input({
|
|
26
|
+
message: 'Capture directory (where document360-capture .spec.ts files live):',
|
|
27
|
+
default: 'user-docs/_capture',
|
|
28
|
+
});
|
|
29
|
+
const outputDir = await input({
|
|
30
|
+
message: 'Screenshot output directory:',
|
|
31
|
+
default: 'user-docs/_screenshots',
|
|
32
|
+
});
|
|
33
|
+
const d360ProjectId = await input({
|
|
34
|
+
message: 'Document360 project ID (UUID; leave blank to set later):',
|
|
35
|
+
default: '',
|
|
36
|
+
});
|
|
37
|
+
const d360VersionId = await input({
|
|
38
|
+
message: 'Document360 project version ID (UUID; leave blank to set later):',
|
|
39
|
+
default: '',
|
|
40
|
+
});
|
|
41
|
+
const helpCenterBaseUrl = await input({
|
|
42
|
+
message: 'Document360 help-center base URL (e.g. https://<tenant>.document360.io/docs/):',
|
|
43
|
+
default: '',
|
|
44
|
+
});
|
|
45
|
+
const cfg = {
|
|
46
|
+
projectId,
|
|
47
|
+
captureDir,
|
|
48
|
+
outputDir,
|
|
49
|
+
d360: {
|
|
50
|
+
projectId: d360ProjectId || undefined,
|
|
51
|
+
projectVersionId: d360VersionId || undefined,
|
|
52
|
+
helpCenterBaseUrl: helpCenterBaseUrl || undefined,
|
|
53
|
+
},
|
|
54
|
+
authoritativeSourceFiles: defaultSourceFiles(cwd),
|
|
55
|
+
};
|
|
56
|
+
const existing = readProjectConfig(cwd);
|
|
57
|
+
if (existing?.terminologyGlossary)
|
|
58
|
+
cfg.terminologyGlossary = existing.terminologyGlossary;
|
|
59
|
+
writeProjectConfig(cfg, cwd);
|
|
60
|
+
console.log('');
|
|
61
|
+
console.log(ok(`✓ Wrote ${path}`));
|
|
62
|
+
console.log('');
|
|
63
|
+
console.log('Next:');
|
|
64
|
+
console.log(` ${accent('/mcp add document360 http <your-d360-mcp-url>')}`);
|
|
65
|
+
console.log(` Then ask the agent: "analyze this repo and propose a docs structure"`);
|
|
66
|
+
console.log('');
|
|
67
|
+
return { kind: 'continue' };
|
|
68
|
+
}
|
|
69
|
+
function readPackageName(cwd) {
|
|
70
|
+
const path = join(cwd, 'package.json');
|
|
71
|
+
if (!existsSync(path))
|
|
72
|
+
return null;
|
|
73
|
+
try {
|
|
74
|
+
const pkg = JSON.parse(readFileSync(path, 'utf8'));
|
|
75
|
+
return pkg.name ?? null;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function defaultSourceFiles(cwd) {
|
|
82
|
+
const candidates = ['README.md', 'ARCHITECTURE.md', 'CLAUDE.md', 'src', 'api', 'docs'];
|
|
83
|
+
return candidates.filter(c => existsSync(join(cwd, c)));
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { error, warn, dim } from '../lib/colors.js';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { sessionPath } from '../lib/paths.js';
|
|
4
|
+
export async function loadCommand(args) {
|
|
5
|
+
const name = args[0];
|
|
6
|
+
if (!name) {
|
|
7
|
+
console.log(error('Usage: /load <name>'));
|
|
8
|
+
return { kind: 'continue' };
|
|
9
|
+
}
|
|
10
|
+
const path = sessionPath(name);
|
|
11
|
+
if (!existsSync(path)) {
|
|
12
|
+
console.log(error(`No saved session at ${path}`));
|
|
13
|
+
return { kind: 'continue' };
|
|
14
|
+
}
|
|
15
|
+
console.log(warn(`/load is a v1.1 capability — the Agent SDK's resume flow requires a session UUID, which v1 does not capture yet.`));
|
|
16
|
+
console.log(dim(`Saved transcript at: ${path}`));
|
|
17
|
+
console.log(dim('Open it manually to inspect the conversation history.'));
|
|
18
|
+
return { kind: 'continue' };
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/commands/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAc;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,kHAAkH,CAAC,CAAC,CAAC;IACtI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC,CAAC;IAC1E,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readMcpConfig, writeMcpConfig } from '../config.js';
|
|
2
|
+
import { accent, dim, error, ok, warn } from '../lib/colors.js';
|
|
3
|
+
export async function mcpCommand(args) {
|
|
4
|
+
const sub = (args[0] ?? '').toLowerCase();
|
|
5
|
+
if (sub === 'list' || !sub) {
|
|
6
|
+
listServers();
|
|
7
|
+
return { kind: 'continue' };
|
|
8
|
+
}
|
|
9
|
+
if (sub === 'add') {
|
|
10
|
+
addServer(args.slice(1));
|
|
11
|
+
return { kind: 'continue' };
|
|
12
|
+
}
|
|
13
|
+
if (sub === 'remove' || sub === 'rm') {
|
|
14
|
+
removeServer(args.slice(1));
|
|
15
|
+
return { kind: 'continue' };
|
|
16
|
+
}
|
|
17
|
+
console.log(error(`Unknown /mcp subcommand: ${sub}`));
|
|
18
|
+
console.log(dim('Try: /mcp add <name> <stdio|http|sse> <command-or-url>, /mcp list, /mcp remove <name>'));
|
|
19
|
+
return { kind: 'continue' };
|
|
20
|
+
}
|
|
21
|
+
function listServers() {
|
|
22
|
+
const cfg = readMcpConfig();
|
|
23
|
+
const names = Object.keys(cfg.servers);
|
|
24
|
+
if (names.length === 0) {
|
|
25
|
+
console.log(dim('\nNo MCP servers registered. Add one with /mcp add <name> <type> <ref>\n'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
console.log('');
|
|
29
|
+
console.log('Registered MCP servers (~/.document360-writer/mcp.json):');
|
|
30
|
+
for (const name of names) {
|
|
31
|
+
const e = cfg.servers[name];
|
|
32
|
+
if (e.type === 'stdio') {
|
|
33
|
+
console.log(` ${accent(name)} ${dim('(stdio)')} ${e.command} ${(e.args ?? []).join(' ')}`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log(` ${accent(name)} ${dim(`(${e.type})`)} ${e.url}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
console.log('');
|
|
40
|
+
}
|
|
41
|
+
function addServer(args) {
|
|
42
|
+
const [name, type, ...rest] = args;
|
|
43
|
+
if (!name || !type || rest.length === 0) {
|
|
44
|
+
console.log(error('Usage: /mcp add <name> <stdio|http|sse> <command-or-url> [args...]'));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (type !== 'stdio' && type !== 'http' && type !== 'sse') {
|
|
48
|
+
console.log(error(`Unknown transport: ${type}. Use stdio, http, or sse.`));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const cfg = readMcpConfig();
|
|
52
|
+
let entry;
|
|
53
|
+
if (type === 'stdio') {
|
|
54
|
+
entry = { type: 'stdio', command: rest[0], args: rest.slice(1) };
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
entry = { type, url: rest[0] };
|
|
58
|
+
}
|
|
59
|
+
cfg.servers[name] = entry;
|
|
60
|
+
writeMcpConfig(cfg);
|
|
61
|
+
console.log('');
|
|
62
|
+
console.log(ok(`✓ Registered "${name}" (${type})`));
|
|
63
|
+
console.log(warn(' This server loads on your next prompt. The current agent session reads MCP config at startup.'));
|
|
64
|
+
console.log(dim(' Run /clear if you want the next turn to reload immediately.'));
|
|
65
|
+
console.log('');
|
|
66
|
+
}
|
|
67
|
+
function removeServer(args) {
|
|
68
|
+
const name = args[0];
|
|
69
|
+
if (!name) {
|
|
70
|
+
console.log(error('Usage: /mcp remove <name>'));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const cfg = readMcpConfig();
|
|
74
|
+
if (!cfg.servers[name]) {
|
|
75
|
+
console.log(error(`No server named "${name}".`));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
delete cfg.servers[name];
|
|
79
|
+
writeMcpConfig(cfg);
|
|
80
|
+
console.log(ok(`✓ Removed "${name}".`));
|
|
81
|
+
console.log(dim(' Run /clear to drop it from the current session immediately.'));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { error } from '../lib/colors.js';
|
|
2
|
+
export async function publishCommand(args) {
|
|
3
|
+
const path = args[0];
|
|
4
|
+
if (!path) {
|
|
5
|
+
console.log(error('Usage: /publish <article-path>'));
|
|
6
|
+
return { kind: 'continue' };
|
|
7
|
+
}
|
|
8
|
+
const prompt = [
|
|
9
|
+
`Run the publish-to-d360 skill for the article at: ${path}`,
|
|
10
|
+
'',
|
|
11
|
+
'Steps you must follow:',
|
|
12
|
+
'1. Read the article markdown.',
|
|
13
|
+
'2. Compute the D360 publish form (strip the H1 title, strip every <!-- SCREENSHOT ... --> block while keeping the visible [Screenshot: ...] line, normalize cross-article links).',
|
|
14
|
+
'3. Look up the article ID in <repo>/d360-category-map.json. If present, call the document360 MCP update-article tool. If absent, call create-article and write the new ID back to the category map.',
|
|
15
|
+
'4. Report what changed and remind me to publish the draft manually in the Document360 portal.',
|
|
16
|
+
].join('\n');
|
|
17
|
+
return { kind: 'forward-to-agent', prompt };
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;QACrD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC9B,CAAC;IACD,MAAM,MAAM,GAAG;QACb,qDAAqD,IAAI,EAAE;QAC3D,EAAE;QACF,wBAAwB;QACxB,+BAA+B;QAC/B,mLAAmL;QACnL,qMAAqM;QACrM,+FAA+F;KAChG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC;AAC9C,CAAC"}
|