@todoist/outline-cli 0.0.0-stage → 3.0.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/CHANGELOG.md +359 -0
- package/README.md +160 -2
- package/dist/commands/account.d.ts +2 -0
- package/dist/commands/account.js +107 -0
- package/dist/commands/account.js.map +1 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +169 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/changelog.d.ts +2 -0
- package/dist/commands/changelog.js +15 -0
- package/dist/commands/changelog.js.map +1 -0
- package/dist/commands/collection.d.ts +2 -0
- package/dist/commands/collection.js +106 -0
- package/dist/commands/collection.js.map +1 -0
- package/dist/commands/document.d.ts +2 -0
- package/dist/commands/document.js +291 -0
- package/dist/commands/document.js.map +1 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +49 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/skill.d.ts +2 -0
- package/dist/commands/skill.js +80 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/update/index.d.ts +2 -0
- package/dist/commands/update/index.js +14 -0
- package/dist/commands/update/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +18 -0
- package/dist/lib/api.js +107 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth-constants.d.ts +18 -0
- package/dist/lib/auth-constants.js +25 -0
- package/dist/lib/auth-constants.js.map +1 -0
- package/dist/lib/auth-output.d.ts +21 -0
- package/dist/lib/auth-output.js +38 -0
- package/dist/lib/auth-output.js.map +1 -0
- package/dist/lib/auth-pages.d.ts +2 -0
- package/dist/lib/auth-pages.js +101 -0
- package/dist/lib/auth-pages.js.map +1 -0
- package/dist/lib/auth-provider.d.ts +85 -0
- package/dist/lib/auth-provider.js +363 -0
- package/dist/lib/auth-provider.js.map +1 -0
- package/dist/lib/auth.d.ts +73 -0
- package/dist/lib/auth.js +188 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +45 -0
- package/dist/lib/config.js +20 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/errors.d.ts +8 -0
- package/dist/lib/errors.js +9 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/global-args.d.ts +30 -0
- package/dist/lib/global-args.js +66 -0
- package/dist/lib/global-args.js.map +1 -0
- package/dist/lib/markdown.d.ts +2 -0
- package/dist/lib/markdown.js +12 -0
- package/dist/lib/markdown.js.map +1 -0
- package/dist/lib/migrate-auth.d.ts +11 -0
- package/dist/lib/migrate-auth.js +92 -0
- package/dist/lib/migrate-auth.js.map +1 -0
- package/dist/lib/outline-account.d.ts +32 -0
- package/dist/lib/outline-account.js +22 -0
- package/dist/lib/outline-account.js.map +1 -0
- package/dist/lib/output.d.ts +15 -0
- package/dist/lib/output.js +85 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/refs.d.ts +33 -0
- package/dist/lib/refs.js +182 -0
- package/dist/lib/refs.js.map +1 -0
- package/dist/lib/skills/content.d.ts +3 -0
- package/dist/lib/skills/content.js +160 -0
- package/dist/lib/skills/content.js.map +1 -0
- package/dist/lib/skills/create-installer.d.ts +9 -0
- package/dist/lib/skills/create-installer.js +77 -0
- package/dist/lib/skills/create-installer.js.map +1 -0
- package/dist/lib/skills/index.d.ts +5 -0
- package/dist/lib/skills/index.js +40 -0
- package/dist/lib/skills/index.js.map +1 -0
- package/dist/lib/skills/types.d.ts +10 -0
- package/dist/lib/skills/types.js +2 -0
- package/dist/lib/skills/types.js.map +1 -0
- package/dist/lib/skills/update-installed.d.ts +6 -0
- package/dist/lib/skills/update-installed.js +23 -0
- package/dist/lib/skills/update-installed.js.map +1 -0
- package/dist/lib/spinner.d.ts +2 -0
- package/dist/lib/spinner.js +5 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/user-records.d.ts +21 -0
- package/dist/lib/user-records.js +126 -0
- package/dist/lib/user-records.js.map +1 -0
- package/dist/lib/user-ref-store.d.ts +16 -0
- package/dist/lib/user-ref-store.js +37 -0
- package/dist/lib/user-ref-store.js.map +1 -0
- package/dist/postinstall.d.ts +1 -0
- package/dist/postinstall.js +16 -0
- package/dist/postinstall.js.map +1 -0
- package/dist/transport/fetch-with-retry.d.ts +15 -0
- package/dist/transport/fetch-with-retry.js +144 -0
- package/dist/transport/fetch-with-retry.js.map +1 -0
- package/dist/transport/http-dispatcher.d.ts +37 -0
- package/dist/transport/http-dispatcher.js +95 -0
- package/dist/transport/http-dispatcher.js.map +1 -0
- package/package.json +72 -5
- package/scripts/check-skill-sync.js +40 -0
- package/scripts/postinstall.js +12 -0
- package/scripts/sync-skill.js +30 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { formatJson, formatNdjson, printEmpty } from '@todoist/cli-core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { BaseCliError } from './errors.js';
|
|
4
|
+
export function getOutputOptions(opts) {
|
|
5
|
+
return {
|
|
6
|
+
json: Boolean(opts.json),
|
|
7
|
+
ndjson: Boolean(opts.ndjson),
|
|
8
|
+
full: Boolean(opts.full),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function outputItem(item, humanFormatter, essentialKeys, opts = {}) {
|
|
12
|
+
if (opts.ndjson) {
|
|
13
|
+
const data = opts.full || !essentialKeys ? item : pick(item, essentialKeys);
|
|
14
|
+
console.log(formatNdjson([data]));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (opts.json) {
|
|
18
|
+
const data = opts.full || !essentialKeys ? item : pick(item, essentialKeys);
|
|
19
|
+
console.log(formatJson(data));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.log(humanFormatter(item));
|
|
23
|
+
}
|
|
24
|
+
export function outputList(items, humanFormatter, essentialKeys, opts = {}, pagination, emptyMessage) {
|
|
25
|
+
if (items.length === 0 && emptyMessage !== undefined) {
|
|
26
|
+
printEmpty({ options: opts, message: emptyMessage });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const project = (item) => (opts.full || !essentialKeys ? item : pick(item, essentialKeys));
|
|
30
|
+
if (opts.ndjson) {
|
|
31
|
+
// Stream item-by-item: avoids buffering the whole list and matches
|
|
32
|
+
// the canonical NDJSON contract (one record per write).
|
|
33
|
+
for (const item of items) {
|
|
34
|
+
console.log(formatNdjson([project(item)]));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (opts.json) {
|
|
38
|
+
console.log(formatJson(items.map(project)));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
for (const item of items) {
|
|
42
|
+
console.log(humanFormatter(item));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (pagination?.nextPath && !opts.ndjson) {
|
|
46
|
+
const hint = chalk.dim(`\n(more results available — use --offset ${pagination.offset + pagination.limit})`);
|
|
47
|
+
// In JSON mode stdout holds the JSON itself, so the hint goes to stderr to keep it parseable.
|
|
48
|
+
if (opts.json) {
|
|
49
|
+
console.error(hint);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log(hint);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function pick(obj, keys) {
|
|
57
|
+
const result = {};
|
|
58
|
+
for (const key of keys) {
|
|
59
|
+
if (key in obj)
|
|
60
|
+
result[key] = obj[key];
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
function toCliError(codeOrError, message, hints) {
|
|
65
|
+
if (typeof codeOrError === 'string') {
|
|
66
|
+
return new BaseCliError(codeOrError, message ?? '', { hints });
|
|
67
|
+
}
|
|
68
|
+
return codeOrError;
|
|
69
|
+
}
|
|
70
|
+
export function formatError(codeOrError, message, hints) {
|
|
71
|
+
const err = toCliError(codeOrError, message, hints);
|
|
72
|
+
const lines = [`Error: ${err.code}`, err.message];
|
|
73
|
+
if (err.hints && err.hints.length > 0) {
|
|
74
|
+
lines.push('');
|
|
75
|
+
for (const hint of err.hints) {
|
|
76
|
+
lines.push(` - ${hint}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return chalk.red(lines.join('\n'));
|
|
80
|
+
}
|
|
81
|
+
export function formatErrorJson(codeOrError, message, hints) {
|
|
82
|
+
const err = toCliError(codeOrError, message, hints);
|
|
83
|
+
return JSON.stringify({ error: { code: err.code, message: err.message, hints: err.hints } });
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface Document {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
url: string;
|
|
5
|
+
urlId: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface Collection {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
color?: string;
|
|
13
|
+
permission?: string;
|
|
14
|
+
createdAt?: string;
|
|
15
|
+
updatedAt?: string;
|
|
16
|
+
documentCount?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a document reference by ID, URL, or name
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveDocumentRef(ref: string): Promise<Document>;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a document reference and return just the ID
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveDocumentId(ref: string): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a collection reference by ID or name
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveCollectionRef(ref: string): Promise<Collection>;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a collection reference and return just the ID
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveCollectionId(ref: string): Promise<string>;
|
package/dist/lib/refs.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { apiRequest } from './api.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check if the input looks like a UUID
|
|
4
|
+
*/
|
|
5
|
+
function isUuid(input) {
|
|
6
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(input);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Check if the input looks like an Outline ID (UUID or URL ID format)
|
|
10
|
+
*/
|
|
11
|
+
function looksLikeId(input) {
|
|
12
|
+
// UUID format
|
|
13
|
+
if (isUuid(input)) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
// Short alphanumeric ID (like urlId) - must be 6+ chars and no spaces
|
|
17
|
+
if (/^[a-zA-Z0-9]{6,}$/.test(input) && !/\s/.test(input)) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extract document ID from URL or slug (document-only)
|
|
24
|
+
* Only extracts from slugs (e.g., "my-doc-abc123" -> "abc123")
|
|
25
|
+
* In URLs, the slug is the segment after `/doc/`; trailing paths
|
|
26
|
+
* (`/edit`, `/history/...`), `?query` and `#anchor` are ignored, and a
|
|
27
|
+
* slug without a title (`/doc/<urlId>`) is the ID itself
|
|
28
|
+
* Preserves full UUIDs and raw IDs
|
|
29
|
+
*/
|
|
30
|
+
function extractDocumentIdFromSlug(input) {
|
|
31
|
+
// Preserve UUIDs as-is
|
|
32
|
+
if (isUuid(input)) {
|
|
33
|
+
return input;
|
|
34
|
+
}
|
|
35
|
+
// If it looks like a URL, extract the slug suffix
|
|
36
|
+
const docSlug = input.match(/\/doc\/([^/?#]+)/)?.[1];
|
|
37
|
+
const parts = input.replace(/\/$/, '').split('/');
|
|
38
|
+
const last = docSlug ?? parts[parts.length - 1];
|
|
39
|
+
// Outline URL IDs are the part after the last hyphen in the slug
|
|
40
|
+
// Only extract if it's a slug with hyphen, not just a raw ID
|
|
41
|
+
const match = last.match(/-([a-zA-Z0-9]+)$/);
|
|
42
|
+
if (match)
|
|
43
|
+
return match[1];
|
|
44
|
+
return docSlug ?? input;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Format suggestions for error messages
|
|
48
|
+
*/
|
|
49
|
+
function formatSuggestions(items, getName, getDisplayId, max = 5) {
|
|
50
|
+
const suggestions = items.slice(0, max);
|
|
51
|
+
return suggestions.map((item) => ` - "${getName(item)}" (${getDisplayId(item)})`).join('\n');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Generic fuzzy reference resolver
|
|
55
|
+
*/
|
|
56
|
+
async function resolveRef(options) {
|
|
57
|
+
const { ref, fetchById, fetchAllPaginated, getName, getDisplayId, entityType, extractSlugId } = options;
|
|
58
|
+
// Try direct ID lookup first if it looks like an ID
|
|
59
|
+
// Only extract slug ID for documents, not collections
|
|
60
|
+
const extractedId = extractSlugId ? extractDocumentIdFromSlug(ref) : ref;
|
|
61
|
+
if (looksLikeId(extractedId)) {
|
|
62
|
+
try {
|
|
63
|
+
return await fetchById(extractedId);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// If direct ID lookup fails, fall through to name matching
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Fetch all items with pagination and search by name
|
|
70
|
+
const items = await fetchAllPaginated();
|
|
71
|
+
const refLower = ref.toLowerCase();
|
|
72
|
+
// Try exact match first (case-insensitive)
|
|
73
|
+
const exactMatches = items.filter((item) => getName(item).toLowerCase() === refLower);
|
|
74
|
+
if (exactMatches.length === 1) {
|
|
75
|
+
return exactMatches[0];
|
|
76
|
+
}
|
|
77
|
+
// Multiple exact matches are ambiguous
|
|
78
|
+
if (exactMatches.length > 1) {
|
|
79
|
+
const suggestions = formatSuggestions(exactMatches, getName, getDisplayId);
|
|
80
|
+
throw new Error(`Ambiguous ${entityType} reference "${ref}". Multiple items have this exact name:\n${suggestions}`);
|
|
81
|
+
}
|
|
82
|
+
// Try partial match
|
|
83
|
+
const partialMatches = items.filter((item) => getName(item).toLowerCase().includes(refLower));
|
|
84
|
+
if (partialMatches.length === 1) {
|
|
85
|
+
return partialMatches[0];
|
|
86
|
+
}
|
|
87
|
+
if (partialMatches.length > 1) {
|
|
88
|
+
const suggestions = formatSuggestions(partialMatches, getName, getDisplayId);
|
|
89
|
+
throw new Error(`Ambiguous ${entityType} reference "${ref}". Did you mean:\n${suggestions}`);
|
|
90
|
+
}
|
|
91
|
+
// No matches found
|
|
92
|
+
throw new Error(`${entityType} not found: "${ref}"`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Fetch all documents with pagination
|
|
96
|
+
*/
|
|
97
|
+
async function fetchAllDocuments() {
|
|
98
|
+
const allDocs = [];
|
|
99
|
+
const limit = 100;
|
|
100
|
+
let offset = 0;
|
|
101
|
+
while (true) {
|
|
102
|
+
const { data } = await apiRequest('documents.list', {
|
|
103
|
+
limit,
|
|
104
|
+
offset,
|
|
105
|
+
});
|
|
106
|
+
allDocs.push(...data);
|
|
107
|
+
if (data.length < limit) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
offset += limit;
|
|
111
|
+
}
|
|
112
|
+
return allDocs;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Fetch all collections with pagination
|
|
116
|
+
*/
|
|
117
|
+
async function fetchAllCollections() {
|
|
118
|
+
const allCollections = [];
|
|
119
|
+
const limit = 100;
|
|
120
|
+
let offset = 0;
|
|
121
|
+
while (true) {
|
|
122
|
+
const { data } = await apiRequest('collections.list', {
|
|
123
|
+
limit,
|
|
124
|
+
offset,
|
|
125
|
+
});
|
|
126
|
+
allCollections.push(...data);
|
|
127
|
+
if (data.length < limit) {
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
offset += limit;
|
|
131
|
+
}
|
|
132
|
+
return allCollections;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve a document reference by ID, URL, or name
|
|
136
|
+
*/
|
|
137
|
+
export async function resolveDocumentRef(ref) {
|
|
138
|
+
return resolveRef({
|
|
139
|
+
ref,
|
|
140
|
+
fetchById: async (id) => {
|
|
141
|
+
const { data } = await apiRequest('documents.info', { id });
|
|
142
|
+
return data;
|
|
143
|
+
},
|
|
144
|
+
fetchAllPaginated: fetchAllDocuments,
|
|
145
|
+
getName: (doc) => doc.title,
|
|
146
|
+
getDisplayId: (doc) => doc.urlId,
|
|
147
|
+
entityType: 'Document',
|
|
148
|
+
extractSlugId: true,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Resolve a document reference and return just the ID
|
|
153
|
+
*/
|
|
154
|
+
export async function resolveDocumentId(ref) {
|
|
155
|
+
const doc = await resolveDocumentRef(ref);
|
|
156
|
+
return doc.id;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Resolve a collection reference by ID or name
|
|
160
|
+
*/
|
|
161
|
+
export async function resolveCollectionRef(ref) {
|
|
162
|
+
return resolveRef({
|
|
163
|
+
ref,
|
|
164
|
+
fetchById: async (id) => {
|
|
165
|
+
const { data } = await apiRequest('collections.info', { id });
|
|
166
|
+
return data;
|
|
167
|
+
},
|
|
168
|
+
fetchAllPaginated: fetchAllCollections,
|
|
169
|
+
getName: (col) => col.name,
|
|
170
|
+
getDisplayId: (col) => col.id,
|
|
171
|
+
entityType: 'Collection',
|
|
172
|
+
extractSlugId: false,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Resolve a collection reference and return just the ID
|
|
177
|
+
*/
|
|
178
|
+
export async function resolveCollectionId(ref) {
|
|
179
|
+
const col = await resolveCollectionRef(ref);
|
|
180
|
+
return col.id;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=refs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.js","sourceRoot":"","sources":["../../src/lib/refs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const SKILL_NAME = "outline-cli";
|
|
2
|
+
export declare const SKILL_DESCRIPTION = "Search and manage Outline wiki documents and collections via the ol CLI";
|
|
3
|
+
export declare const SKILL_CONTENT = "# Outline CLI (ol)\n\nUse this skill when the user wants to interact with their Outline wiki/knowledge base.\n\n## Quick Reference\n\n- `ol search \"query\"` - Search documents\n- `ol doc list` - List documents\n- `ol doc get <id>` - Read a document\n- `ol doc open <id>` - Open document in browser\n- `ol doc create --title \"Title\" --collection <id>` - Create document\n- `ol col list` - List collections\n- `ol account` - List stored accounts; `ol account use <id|name>` sets the default\n\n## Output Formats\n\nAll list commands support:\n- `--json` - JSON output (essential fields)\n- `--ndjson` - Newline-delimited JSON (streaming)\n- `--full` - Include all fields in JSON\n\n## Global Options\n\n- `--user <id|name>` - Act as a specific stored account, matched by Outline user ID or display name. Each `ol auth login` stores an account (accounts can live on different Outline instances), and `--user` selects which one a command runs as; the token, base URL, and OAuth client ID all resolve from that account. Must be placed **before** the command, e.g. `ol --user scott@example.com doc list`. Omitted, commands use the default account. Overridden by `OUTLINE_API_TOKEN` when set.\n\n## Document References\n\nDocuments can be referenced by:\n- URL ID (the slug suffix after the last hyphen)\n- Full Outline URL (auto-extracted)\n- Document ID\n\n## Commands\n\n### Search\n```bash\nol search \"query\"\nol search \"query\" --limit 10\nol search \"query\" --offset 25 # next page of results\nol search \"query\" --collection <id>\nol search \"query\" --status published\nol search \"query\" --json\n```\n\n### Documents\n```bash\nol doc list --collection <id> --limit 25\nol doc list --sort title --direction ASC\nol doc get <id> # Rendered markdown\nol doc get <id> --raw # Raw markdown\nol doc get <id> --json\nol doc open <id> # Open in browser\nol doc create --title \"Title\" --collection <id> --text \"# Content\"\nol doc create --title \"Title\" --parent <ref> --text \"# Content\" # Nest under parent (collection inferred)\nol doc create --title \"Title\" --collection <id> --file ./doc.md\nol doc update <id> --title \"New Title\"\nol doc update <id> --file ./updated.md\ngenerate-notes | ol doc update <id> --stdin # Read markdown from stdin (create and update)\nol doc update <id> --publish # Publish a draft (create makes drafts unless --publish)\nol doc update <id> --publish --collection <ref> # Publish a draft that has no collection (web UI drafts)\nol doc update <id> --file ./doc.md --if-updated-at <updatedAt> # Fail if the doc was saved since <updatedAt> (see Examples)\nol doc move <id> --collection <target-id> # Move to collection root\nol doc move <id> --parent <ref> # Nest under parent (collection inferred)\nol doc archive <id>\nol doc unarchive <id>\nol doc delete <id> --confirm\nol doc restore <id> # Restore from trash (ID or URL; trashed docs aren't found by title)\nol doc restore <id> --collection <ref> # Restore into another collection (required if the original is gone)\n```\n\n### Collections\n```bash\nol col list\nol col get <id>\nol col create --name \"Name\" --description \"Desc\" --color \"#hex\"\nol col create --name \"Private\" --private\nol col update <id> --name \"New Name\"\nol col delete <id> --confirm\n```\n\n### Authentication\n```bash\nol auth login # OAuth login (opens browser); prompts for base URL + client ID if needed\nol auth login --base-url <url> # Specify Outline base URL for this login (saved for future use)\nol auth login --client-id <id> # Specify OAuth client ID for this login (saved for future use)\nol auth login --callback-port <port> # Override local OAuth callback port\nol auth login --read-only # Request read-only scopes (where supported by the Outline instance)\nol auth login --json | --ndjson # Machine-readable success envelope\nol auth status # Show current auth state\nol auth status --json | --ndjson # Machine-readable status envelope ({id, team, baseUrl, source})\nol auth logout # Clear saved credentials\nol auth logout --json | --ndjson # Machine-readable logout envelope ({ok: true}; --ndjson is silent)\nol auth token <token> # Save a personal API token (validates via auth.info, resolves identity)\nol auth token <token> --base-url <url> # Save a token for a specific Outline instance\nol auth token # Prompt for the token (hidden input; errors in non-interactive shells)\nol auth token view # Print the bare stored token to stdout for scripts (refreshes an expiring OAuth token first; no newline when piped; refuses when OUTLINE_API_TOKEN is set)\nol --user <id|name> auth token view # Print a specific stored account's token (--user is a root flag, before the command)\n```\n\n### Accounts\n```bash\nol account # List stored accounts (default subcommand)\nol account list # List stored accounts, default marked\nol account list --json | --ndjson # Machine-readable list ({accounts, default}; --ndjson streams one per line)\nol account current # Show the active account (honours --user and OUTLINE_API_TOKEN)\nol account current --json | --ndjson # Discriminated by source: {source:\"stored\", account:{id, label, teamName, baseUrl, isDefault}} | {source:\"env\"} | {source:\"legacy\"}\nol account use <id|name> # Set the default account used when --user is omitted\nol account use <id|name> --json # Machine-readable envelope ({ok: true, default: <id>}; --ndjson is silent)\nol account remove <id|name> # Remove a stored account (clears keyring + config entry)\nol account remove <id|name> --json # Machine-readable envelope ({ok: true, removed: <id>}; --ndjson is silent)\n```\n\n### Update & Changelog\n```bash\nol update # Update CLI to latest version\nol update --check # Check for updates without installing, show channel\nol update --check --json # Check for updates as a JSON envelope\nol update --check --ndjson # Check for updates as NDJSON output\nol update --channel # Show current update channel\nol update switch --stable # Switch to stable release channel\nol update switch --pre-release # Switch to pre-release (next) channel\nol changelog # Show recent changelog entries\nol changelog -n 3 # Show last 3 versions\n```\n\n## Examples\n\n### Find and read a document\n```bash\nol search \"onboarding\" --json | jq '.[0].document.urlId'\nol doc get <urlId>\n```\n\n### Create a document from a file\n```bash\nol doc create --title \"Meeting Notes\" --collection <id> --file ./notes.md --publish\n```\n\n### Edit a document without overwriting someone else's changes\n```bash\nts=$(ol doc get <id> --json | jq -r '.updatedAt')\nol doc get <id> --raw > doc.md # then edit doc.md\nol doc update <id> --file doc.md --if-updated-at \"$ts\"\n```\nIf the document was saved after `$ts`, the update fails with `DOCUMENT_CHANGED`, or with Outline's \"Document has been modified since the provided revision\" when the save lands during the update; re-read and retry. Edits not yet saved from an open editor are not detected.\n\n### List all collections and their documents\n```bash\nol col list --json\nol doc list --collection <id> --sort title --direction ASC\n```\n\n### Bulk export with ndjson\n```bash\nol doc list --ndjson --full | jq -r '.title'\n```\n";
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
export const SKILL_NAME = 'outline-cli';
|
|
2
|
+
export const SKILL_DESCRIPTION = 'Search and manage Outline wiki documents and collections via the ol CLI';
|
|
3
|
+
export const SKILL_CONTENT = `# Outline CLI (ol)
|
|
4
|
+
|
|
5
|
+
Use this skill when the user wants to interact with their Outline wiki/knowledge base.
|
|
6
|
+
|
|
7
|
+
## Quick Reference
|
|
8
|
+
|
|
9
|
+
- \`ol search "query"\` - Search documents
|
|
10
|
+
- \`ol doc list\` - List documents
|
|
11
|
+
- \`ol doc get <id>\` - Read a document
|
|
12
|
+
- \`ol doc open <id>\` - Open document in browser
|
|
13
|
+
- \`ol doc create --title "Title" --collection <id>\` - Create document
|
|
14
|
+
- \`ol col list\` - List collections
|
|
15
|
+
- \`ol account\` - List stored accounts; \`ol account use <id|name>\` sets the default
|
|
16
|
+
|
|
17
|
+
## Output Formats
|
|
18
|
+
|
|
19
|
+
All list commands support:
|
|
20
|
+
- \`--json\` - JSON output (essential fields)
|
|
21
|
+
- \`--ndjson\` - Newline-delimited JSON (streaming)
|
|
22
|
+
- \`--full\` - Include all fields in JSON
|
|
23
|
+
|
|
24
|
+
## Global Options
|
|
25
|
+
|
|
26
|
+
- \`--user <id|name>\` - Act as a specific stored account, matched by Outline user ID or display name. Each \`ol auth login\` stores an account (accounts can live on different Outline instances), and \`--user\` selects which one a command runs as; the token, base URL, and OAuth client ID all resolve from that account. Must be placed **before** the command, e.g. \`ol --user scott@example.com doc list\`. Omitted, commands use the default account. Overridden by \`OUTLINE_API_TOKEN\` when set.
|
|
27
|
+
|
|
28
|
+
## Document References
|
|
29
|
+
|
|
30
|
+
Documents can be referenced by:
|
|
31
|
+
- URL ID (the slug suffix after the last hyphen)
|
|
32
|
+
- Full Outline URL (auto-extracted)
|
|
33
|
+
- Document ID
|
|
34
|
+
|
|
35
|
+
## Commands
|
|
36
|
+
|
|
37
|
+
### Search
|
|
38
|
+
\`\`\`bash
|
|
39
|
+
ol search "query"
|
|
40
|
+
ol search "query" --limit 10
|
|
41
|
+
ol search "query" --offset 25 # next page of results
|
|
42
|
+
ol search "query" --collection <id>
|
|
43
|
+
ol search "query" --status published
|
|
44
|
+
ol search "query" --json
|
|
45
|
+
\`\`\`
|
|
46
|
+
|
|
47
|
+
### Documents
|
|
48
|
+
\`\`\`bash
|
|
49
|
+
ol doc list --collection <id> --limit 25
|
|
50
|
+
ol doc list --sort title --direction ASC
|
|
51
|
+
ol doc get <id> # Rendered markdown
|
|
52
|
+
ol doc get <id> --raw # Raw markdown
|
|
53
|
+
ol doc get <id> --json
|
|
54
|
+
ol doc open <id> # Open in browser
|
|
55
|
+
ol doc create --title "Title" --collection <id> --text "# Content"
|
|
56
|
+
ol doc create --title "Title" --parent <ref> --text "# Content" # Nest under parent (collection inferred)
|
|
57
|
+
ol doc create --title "Title" --collection <id> --file ./doc.md
|
|
58
|
+
ol doc update <id> --title "New Title"
|
|
59
|
+
ol doc update <id> --file ./updated.md
|
|
60
|
+
generate-notes | ol doc update <id> --stdin # Read markdown from stdin (create and update)
|
|
61
|
+
ol doc update <id> --publish # Publish a draft (create makes drafts unless --publish)
|
|
62
|
+
ol doc update <id> --publish --collection <ref> # Publish a draft that has no collection (web UI drafts)
|
|
63
|
+
ol doc update <id> --file ./doc.md --if-updated-at <updatedAt> # Fail if the doc was saved since <updatedAt> (see Examples)
|
|
64
|
+
ol doc move <id> --collection <target-id> # Move to collection root
|
|
65
|
+
ol doc move <id> --parent <ref> # Nest under parent (collection inferred)
|
|
66
|
+
ol doc archive <id>
|
|
67
|
+
ol doc unarchive <id>
|
|
68
|
+
ol doc delete <id> --confirm
|
|
69
|
+
ol doc restore <id> # Restore from trash (ID or URL; trashed docs aren't found by title)
|
|
70
|
+
ol doc restore <id> --collection <ref> # Restore into another collection (required if the original is gone)
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
### Collections
|
|
74
|
+
\`\`\`bash
|
|
75
|
+
ol col list
|
|
76
|
+
ol col get <id>
|
|
77
|
+
ol col create --name "Name" --description "Desc" --color "#hex"
|
|
78
|
+
ol col create --name "Private" --private
|
|
79
|
+
ol col update <id> --name "New Name"
|
|
80
|
+
ol col delete <id> --confirm
|
|
81
|
+
\`\`\`
|
|
82
|
+
|
|
83
|
+
### Authentication
|
|
84
|
+
\`\`\`bash
|
|
85
|
+
ol auth login # OAuth login (opens browser); prompts for base URL + client ID if needed
|
|
86
|
+
ol auth login --base-url <url> # Specify Outline base URL for this login (saved for future use)
|
|
87
|
+
ol auth login --client-id <id> # Specify OAuth client ID for this login (saved for future use)
|
|
88
|
+
ol auth login --callback-port <port> # Override local OAuth callback port
|
|
89
|
+
ol auth login --read-only # Request read-only scopes (where supported by the Outline instance)
|
|
90
|
+
ol auth login --json | --ndjson # Machine-readable success envelope
|
|
91
|
+
ol auth status # Show current auth state
|
|
92
|
+
ol auth status --json | --ndjson # Machine-readable status envelope ({id, team, baseUrl, source})
|
|
93
|
+
ol auth logout # Clear saved credentials
|
|
94
|
+
ol auth logout --json | --ndjson # Machine-readable logout envelope ({ok: true}; --ndjson is silent)
|
|
95
|
+
ol auth token <token> # Save a personal API token (validates via auth.info, resolves identity)
|
|
96
|
+
ol auth token <token> --base-url <url> # Save a token for a specific Outline instance
|
|
97
|
+
ol auth token # Prompt for the token (hidden input; errors in non-interactive shells)
|
|
98
|
+
ol auth token view # Print the bare stored token to stdout for scripts (refreshes an expiring OAuth token first; no newline when piped; refuses when OUTLINE_API_TOKEN is set)
|
|
99
|
+
ol --user <id|name> auth token view # Print a specific stored account's token (--user is a root flag, before the command)
|
|
100
|
+
\`\`\`
|
|
101
|
+
|
|
102
|
+
### Accounts
|
|
103
|
+
\`\`\`bash
|
|
104
|
+
ol account # List stored accounts (default subcommand)
|
|
105
|
+
ol account list # List stored accounts, default marked
|
|
106
|
+
ol account list --json | --ndjson # Machine-readable list ({accounts, default}; --ndjson streams one per line)
|
|
107
|
+
ol account current # Show the active account (honours --user and OUTLINE_API_TOKEN)
|
|
108
|
+
ol account current --json | --ndjson # Discriminated by source: {source:"stored", account:{id, label, teamName, baseUrl, isDefault}} | {source:"env"} | {source:"legacy"}
|
|
109
|
+
ol account use <id|name> # Set the default account used when --user is omitted
|
|
110
|
+
ol account use <id|name> --json # Machine-readable envelope ({ok: true, default: <id>}; --ndjson is silent)
|
|
111
|
+
ol account remove <id|name> # Remove a stored account (clears keyring + config entry)
|
|
112
|
+
ol account remove <id|name> --json # Machine-readable envelope ({ok: true, removed: <id>}; --ndjson is silent)
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
### Update & Changelog
|
|
116
|
+
\`\`\`bash
|
|
117
|
+
ol update # Update CLI to latest version
|
|
118
|
+
ol update --check # Check for updates without installing, show channel
|
|
119
|
+
ol update --check --json # Check for updates as a JSON envelope
|
|
120
|
+
ol update --check --ndjson # Check for updates as NDJSON output
|
|
121
|
+
ol update --channel # Show current update channel
|
|
122
|
+
ol update switch --stable # Switch to stable release channel
|
|
123
|
+
ol update switch --pre-release # Switch to pre-release (next) channel
|
|
124
|
+
ol changelog # Show recent changelog entries
|
|
125
|
+
ol changelog -n 3 # Show last 3 versions
|
|
126
|
+
\`\`\`
|
|
127
|
+
|
|
128
|
+
## Examples
|
|
129
|
+
|
|
130
|
+
### Find and read a document
|
|
131
|
+
\`\`\`bash
|
|
132
|
+
ol search "onboarding" --json | jq '.[0].document.urlId'
|
|
133
|
+
ol doc get <urlId>
|
|
134
|
+
\`\`\`
|
|
135
|
+
|
|
136
|
+
### Create a document from a file
|
|
137
|
+
\`\`\`bash
|
|
138
|
+
ol doc create --title "Meeting Notes" --collection <id> --file ./notes.md --publish
|
|
139
|
+
\`\`\`
|
|
140
|
+
|
|
141
|
+
### Edit a document without overwriting someone else's changes
|
|
142
|
+
\`\`\`bash
|
|
143
|
+
ts=$(ol doc get <id> --json | jq -r '.updatedAt')
|
|
144
|
+
ol doc get <id> --raw > doc.md # then edit doc.md
|
|
145
|
+
ol doc update <id> --file doc.md --if-updated-at "$ts"
|
|
146
|
+
\`\`\`
|
|
147
|
+
If the document was saved after \`$ts\`, the update fails with \`DOCUMENT_CHANGED\`, or with Outline's "Document has been modified since the provided revision" when the save lands during the update; re-read and retry. Edits not yet saved from an open editor are not detected.
|
|
148
|
+
|
|
149
|
+
### List all collections and their documents
|
|
150
|
+
\`\`\`bash
|
|
151
|
+
ol col list --json
|
|
152
|
+
ol doc list --collection <id> --sort title --direction ASC
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
### Bulk export with ndjson
|
|
156
|
+
\`\`\`bash
|
|
157
|
+
ol doc list --ndjson --full | jq -r '.title'
|
|
158
|
+
\`\`\`
|
|
159
|
+
`;
|
|
160
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAA;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAC1B,yEAAyE,CAAA;AAE7E,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4J5B,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SkillInstaller } from './types.js';
|
|
2
|
+
interface InstallerConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
dirName: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function generateSkillFile(): string;
|
|
8
|
+
export declare function createInstaller(config: InstallerConfig): SkillInstaller;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { access, mkdir, readdir, rmdir, unlink, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { SKILL_CONTENT, SKILL_DESCRIPTION, SKILL_NAME } from './content.js';
|
|
5
|
+
export function generateSkillFile() {
|
|
6
|
+
const frontmatter = `---
|
|
7
|
+
name: ${SKILL_NAME}
|
|
8
|
+
description: ${JSON.stringify(SKILL_DESCRIPTION)}
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
`;
|
|
12
|
+
return frontmatter + SKILL_CONTENT;
|
|
13
|
+
}
|
|
14
|
+
export function createInstaller(config) {
|
|
15
|
+
function getInstallPath(local) {
|
|
16
|
+
const base = local ? process.cwd() : homedir();
|
|
17
|
+
return join(base, config.dirName, 'skills', SKILL_NAME, 'SKILL.md');
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
name: config.name,
|
|
21
|
+
description: config.description,
|
|
22
|
+
getInstallPath,
|
|
23
|
+
generateContent() {
|
|
24
|
+
return generateSkillFile();
|
|
25
|
+
},
|
|
26
|
+
async isInstalled(local) {
|
|
27
|
+
try {
|
|
28
|
+
await access(getInstallPath(local));
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async install(local, force) {
|
|
36
|
+
if (!local && config.dirName !== '.agents') {
|
|
37
|
+
const agentDir = join(homedir(), config.dirName);
|
|
38
|
+
try {
|
|
39
|
+
await access(agentDir);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new Error(`${config.name} does not appear to be installed (${agentDir} not found)`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const filepath = getInstallPath(local);
|
|
46
|
+
const exists = await this.isInstalled(local);
|
|
47
|
+
if (exists && !force) {
|
|
48
|
+
throw new Error(`Skill file already exists at ${filepath}. Use --force to overwrite.`);
|
|
49
|
+
}
|
|
50
|
+
await mkdir(dirname(filepath), { recursive: true });
|
|
51
|
+
await writeFile(filepath, this.generateContent(), 'utf-8');
|
|
52
|
+
},
|
|
53
|
+
async update(local) {
|
|
54
|
+
const filepath = getInstallPath(local);
|
|
55
|
+
await writeFile(filepath, this.generateContent(), 'utf-8');
|
|
56
|
+
},
|
|
57
|
+
async uninstall(local) {
|
|
58
|
+
const filepath = getInstallPath(local);
|
|
59
|
+
const exists = await this.isInstalled(local);
|
|
60
|
+
if (!exists) {
|
|
61
|
+
throw new Error(`Skill file not found at ${filepath}`);
|
|
62
|
+
}
|
|
63
|
+
await unlink(filepath);
|
|
64
|
+
const dir = dirname(filepath);
|
|
65
|
+
try {
|
|
66
|
+
const files = await readdir(dir);
|
|
67
|
+
if (files.length === 0) {
|
|
68
|
+
await rmdir(dir);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// ignore errors when cleaning up empty directory
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=create-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-installer.js","sourceRoot":"","sources":["../../../src/lib/skills/create-installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SkillInstaller } from './types.js';
|
|
2
|
+
export declare const skillInstallers: Record<string, SkillInstaller>;
|
|
3
|
+
export declare function getInstaller(agent: string): SkillInstaller | undefined;
|
|
4
|
+
export declare function listAgents(): string[];
|
|
5
|
+
export type { SkillInstaller } from './types.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createInstaller } from './create-installer.js';
|
|
2
|
+
export const skillInstallers = {
|
|
3
|
+
'claude-code': createInstaller({
|
|
4
|
+
name: 'claude-code',
|
|
5
|
+
description: 'Claude Code skill for Outline CLI',
|
|
6
|
+
dirName: '.claude',
|
|
7
|
+
}),
|
|
8
|
+
codex: createInstaller({
|
|
9
|
+
name: 'codex',
|
|
10
|
+
description: 'Codex skill for Outline CLI',
|
|
11
|
+
dirName: '.codex',
|
|
12
|
+
}),
|
|
13
|
+
cursor: createInstaller({
|
|
14
|
+
name: 'cursor',
|
|
15
|
+
description: 'Cursor skill for Outline CLI',
|
|
16
|
+
dirName: '.cursor',
|
|
17
|
+
}),
|
|
18
|
+
gemini: createInstaller({
|
|
19
|
+
name: 'gemini',
|
|
20
|
+
description: 'Gemini CLI skill for Outline CLI',
|
|
21
|
+
dirName: '.gemini',
|
|
22
|
+
}),
|
|
23
|
+
pi: createInstaller({
|
|
24
|
+
name: 'pi',
|
|
25
|
+
description: 'Pi skill for Outline CLI',
|
|
26
|
+
dirName: '.pi',
|
|
27
|
+
}),
|
|
28
|
+
universal: createInstaller({
|
|
29
|
+
name: 'universal',
|
|
30
|
+
description: 'Universal agent skill for Outline CLI',
|
|
31
|
+
dirName: '.agents',
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
export function getInstaller(agent) {
|
|
35
|
+
return skillInstallers[agent];
|
|
36
|
+
}
|
|
37
|
+
export function listAgents() {
|
|
38
|
+
return Object.keys(skillInstallers);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/skills/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGvD,MAAM,CAAC,MAAM,eAAe,GAAmC;IAC3D,aAAa,EAAE,eAAe,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,mCAAmC;QAChD,OAAO,EAAE,SAAS;KACrB,CAAC;IACF,KAAK,EAAE,eAAe,CAAC;QACnB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,6BAA6B;QAC1C,OAAO,EAAE,QAAQ;KACpB,CAAC;IACF,MAAM,EAAE,eAAe,CAAC;QACpB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,8BAA8B;QAC3C,OAAO,EAAE,SAAS;KACrB,CAAC;IACF,MAAM,EAAE,eAAe,CAAC;QACpB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,kCAAkC;QAC/C,OAAO,EAAE,SAAS;KACrB,CAAC;IACF,EAAE,EAAE,eAAe,CAAC;QAChB,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,0BAA0B;QACvC,OAAO,EAAE,KAAK;KACjB,CAAC;IACF,SAAS,EAAE,eAAe,CAAC;QACvB,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,uCAAuC;QACpD,OAAO,EAAE,SAAS;KACrB,CAAC;CACL,CAAA;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACtC,OAAO,eAAe,CAAC,KAAK,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,UAAU;IACtB,OAAO,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;AACvC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface SkillInstaller {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
getInstallPath(local: boolean): string;
|
|
5
|
+
generateContent(): string;
|
|
6
|
+
isInstalled(local: boolean): Promise<boolean>;
|
|
7
|
+
install(local: boolean, force: boolean): Promise<void>;
|
|
8
|
+
update(local: boolean): Promise<void>;
|
|
9
|
+
uninstall(local: boolean): Promise<void>;
|
|
10
|
+
}
|