@felan-ai/ext-output-style 0.2.1 → 0.3.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 +1 -0
- package/NOTICE +7 -0
- package/README.md +30 -10
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -16
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/LICENSE
CHANGED
package/NOTICE
CHANGED
|
@@ -4,3 +4,10 @@ Copyright (c) 2026 Felan contributors
|
|
|
4
4
|
|
|
5
5
|
This package is original Felan code licensed under the MIT License included in
|
|
6
6
|
this package. It has no third-party runtime dependencies.
|
|
7
|
+
|
|
8
|
+
The built-in concise instructions adapt wording from Julius Brussee's Caveman
|
|
9
|
+
skill:
|
|
10
|
+
https://github.com/JuliusBrussee/caveman/blob/main/skills/caveman/SKILL.md
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 Julius Brussee. Used under the MIT License preserved in
|
|
13
|
+
LICENSE.
|
package/README.md
CHANGED
|
@@ -3,24 +3,42 @@
|
|
|
3
3
|
Portable output-style instructions for Felan sessions.
|
|
4
4
|
|
|
5
5
|
The extension appends one clearly bounded `## Output Style` section to the
|
|
6
|
-
system prompt before each model run. It
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
system prompt before each model run. It provides the built-in `concise`,
|
|
7
|
+
and `explanatory` styles plus a `custom` style for caller-provided instructions.
|
|
8
|
+
`concise` is the default. It minimizes prose while preserving clarity, exact
|
|
9
|
+
technical content, conditions, caveats, verification, and blockers, and it
|
|
10
|
+
expands for ambiguity, safety-sensitive actions, errors, and complex plans.
|
|
11
|
+
File-backed styles are not supported.
|
|
9
12
|
|
|
10
13
|
```ts
|
|
11
14
|
import { createOutputStyleExtension } from '@felan-ai/ext-output-style';
|
|
12
15
|
|
|
13
16
|
const extension = createOutputStyleExtension('explanatory');
|
|
14
|
-
const
|
|
17
|
+
const concise = createOutputStyleExtension('concise');
|
|
18
|
+
const experiment = createOutputStyleExtension('custom', 'Answer in one compact paragraph.');
|
|
15
19
|
```
|
|
16
20
|
|
|
17
|
-
Felan declares the style as `extensionConfig.outputStyle.style`.
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
Felan declares the style as `extensionConfig.outputStyle.style`. Custom
|
|
22
|
+
instructions use `extensionConfig.outputStyle.instructions`:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"extensionConfig": {
|
|
27
|
+
"outputStyle": {
|
|
28
|
+
"style": "custom",
|
|
29
|
+
"instructions": "Answer in one compact paragraph without omitting blockers."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The local TUI, CLI, `/settings`, and Agent Core consumers resolve these fields
|
|
36
|
+
before activating the extension for root and child sessions. A custom style
|
|
37
|
+
requires non-empty instructions.
|
|
20
38
|
|
|
21
39
|
## Package boundary and requirements
|
|
22
40
|
|
|
23
|
-
The package owns the supported style names,
|
|
41
|
+
The package owns the supported style names, built-in instructions, custom-text
|
|
24
42
|
validation, and prompt-section formatting. A host owns style selection,
|
|
25
43
|
built-in enablement, and session lifecycle. The package requires a compatible
|
|
26
44
|
`@felan-ai/agent-core` peer and does not read settings, prompt files, or ambient
|
|
@@ -46,5 +64,7 @@ pnpm --filter @felan-ai/ext-output-style test
|
|
|
46
64
|
|
|
47
65
|
## Attribution
|
|
48
66
|
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
The extension implementation is original Felan project code. The merged
|
|
68
|
+
concise instructions adapt wording from Julius Brussee's MIT-licensed
|
|
69
|
+
[Caveman skill](https://github.com/JuliusBrussee/caveman/blob/main/skills/caveman/SKILL.md).
|
|
70
|
+
See [NOTICE](NOTICE) and [LICENSE](LICENSE).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type FelanExtension } from '@felan-ai/agent-core';
|
|
2
|
-
export declare const OUTPUT_STYLES: readonly ["concise", "explanatory", "
|
|
2
|
+
export declare const OUTPUT_STYLES: readonly ["concise", "explanatory", "custom"];
|
|
3
3
|
export type OutputStyle = typeof OUTPUT_STYLES[number];
|
|
4
4
|
export declare const DEFAULT_OUTPUT_STYLE: OutputStyle;
|
|
5
5
|
export declare const OUTPUT_STYLE_CONFIG: import("@felan-ai/agent-core").ExtensionConfigDefinition<{
|
|
6
|
-
readonly style: import("@felan-ai/agent-core").ExtensionConfigField<"concise" | "explanatory" | "
|
|
6
|
+
readonly style: import("@felan-ai/agent-core").ExtensionConfigField<"concise" | "explanatory" | "custom">;
|
|
7
|
+
readonly instructions: import("@felan-ai/agent-core").ExtensionConfigField<string>;
|
|
7
8
|
}>;
|
|
8
9
|
export declare function parseOutputStyle(value?: unknown): OutputStyle;
|
|
9
|
-
export declare function formatOutputStyleSection(style: OutputStyle): string;
|
|
10
|
-
export declare function createOutputStyleExtension(value?: unknown): FelanExtension;
|
|
10
|
+
export declare function formatOutputStyleSection(style: OutputStyle, instructions?: unknown): string;
|
|
11
|
+
export declare function createOutputStyleExtension(value?: unknown, instructions?: unknown): FelanExtension;
|
|
11
12
|
declare const outputStyleExtension: FelanExtension;
|
|
12
13
|
export default outputStyleExtension;
|
|
13
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,KAAK,cAAc,EAA0B,MAAM,sBAAsB,CAAC;AAEjJ,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,KAAK,cAAc,EAA0B,MAAM,sBAAsB,CAAC;AAEjJ,eAAO,MAAM,aAAa,+CAAgD,CAAC;AAC3E,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,oBAAoB,EAAE,WAAuB,CAAC;AAC3D,eAAO,MAAM,mBAAmB;;;EAe9B,CAAC;AA0BH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,OAA8B,GAAG,WAAW,CAKnF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,CAW3F;AAED,wBAAgB,0BAA0B,CACxC,KAAK,GAAE,OAA8B,EACrC,YAAY,CAAC,EAAE,OAAO,GACrB,cAAc,CAShB;AAED,QAAA,MAAM,oBAAoB,EAAE,cAGtB,CAAC;AAGP,eAAe,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { associateExtensionConfig, configField, defineExtensionConfig } from '@felan-ai/agent-core';
|
|
2
|
-
export const OUTPUT_STYLES = ['concise', 'explanatory', '
|
|
2
|
+
export const OUTPUT_STYLES = ['concise', 'explanatory', 'custom'];
|
|
3
3
|
export const DEFAULT_OUTPUT_STYLE = 'concise';
|
|
4
4
|
export const OUTPUT_STYLE_CONFIG = defineExtensionConfig({
|
|
5
5
|
id: 'outputStyle',
|
|
@@ -10,28 +10,34 @@ export const OUTPUT_STYLE_CONFIG = defineExtensionConfig({
|
|
|
10
10
|
description: 'Response detail and explanation style',
|
|
11
11
|
cliName: 'output-style',
|
|
12
12
|
}),
|
|
13
|
+
instructions: configField.string({
|
|
14
|
+
default: '',
|
|
15
|
+
description: 'Custom system-prompt instructions used when output style is custom',
|
|
16
|
+
cliName: 'output-style-instructions',
|
|
17
|
+
}),
|
|
13
18
|
},
|
|
14
19
|
});
|
|
15
20
|
const OUTPUT_STYLE_START = '<output_style>';
|
|
16
21
|
const OUTPUT_STYLE_END = '</output_style>';
|
|
17
22
|
const STYLE_INSTRUCTIONS = {
|
|
18
23
|
concise: [
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
24
|
+
'Use the fewest words that preserve correctness, clarity, and all required technical substance. Lead with the outcome or next action.',
|
|
25
|
+
'Omit greetings, restatements, filler, decorative prose, emoji, redundant transitions, duplicate recaps, and filler closings.',
|
|
26
|
+
'Prefer short sentences, compact bullets, and concise paragraphs. Fragments and standard, widely understood abbreviations are acceptable only when they remain clear and professional; do not invent abbreviations or mangle grammar merely to shorten.',
|
|
27
|
+
'Use headings only when they improve scanability. State each fact once; do not provide both a normal answer and a terse duplicate.',
|
|
28
|
+
'Keep technical terms, code, commands, paths, identifiers, API names, numbers, units, and exact error messages unchanged.',
|
|
29
|
+
'Never omit or alter negation, conditions, scope, exceptions, caveats, verification results, or blockers merely to shorten the response.',
|
|
30
|
+
'Quote the shortest decisive exact error lines and summarize the rest accurately unless the full log is requested.',
|
|
31
|
+
'Expand into clear, complete prose whenever compression could cause ambiguity, especially for security warnings, destructive or irreversible actions, ordered procedures, errors, blockers, limitations, recovery instructions, complex plans, tradeoffs, or clarification requests.',
|
|
32
|
+
'Do not narrate ordinary tool calls or announce the next tool call. Before a tool call, write only what is needed to resolve ambiguity, explain a safety concern, or confirm an irreversible action.',
|
|
33
|
+
"Reply in the user's language. Do not translate code, commands, identifiers, API names, or exact error strings unless requested.",
|
|
34
|
+
'For documentation, comments, commits, issues, pull requests, tickets, and other durable artifacts, use clear conventional prose and preserve requested formats.',
|
|
22
35
|
],
|
|
23
36
|
explanatory: [
|
|
24
37
|
'Explain the reasoning and important tradeoffs behind recommendations and changes.',
|
|
25
38
|
'Provide enough context for the user to understand how the result works and how to verify it.',
|
|
26
39
|
'Keep explanations relevant to the request and avoid repeating the same point.',
|
|
27
40
|
],
|
|
28
|
-
caveman: [
|
|
29
|
-
'Use the fewest words that preserve correctness. Prefer short fragments, compact bullets, and standard abbreviations.',
|
|
30
|
-
'Omit greetings, restatements, transitions, and filler.',
|
|
31
|
-
'Expand enough to be clear for errors, security warnings, destructive actions, blockers, and complex plans.',
|
|
32
|
-
'Keep code, commands, paths, identifiers, numbers, and error messages exact.',
|
|
33
|
-
'Never omit required caveats, verification results, or blockers for brevity.',
|
|
34
|
-
],
|
|
35
41
|
};
|
|
36
42
|
export function parseOutputStyle(value = DEFAULT_OUTPUT_STYLE) {
|
|
37
43
|
if (typeof value === 'string' && OUTPUT_STYLES.includes(value)) {
|
|
@@ -39,25 +45,34 @@ export function parseOutputStyle(value = DEFAULT_OUTPUT_STYLE) {
|
|
|
39
45
|
}
|
|
40
46
|
throw new Error(`outputStyle must be one of: ${OUTPUT_STYLES.join(', ')}`);
|
|
41
47
|
}
|
|
42
|
-
export function formatOutputStyleSection(style) {
|
|
48
|
+
export function formatOutputStyleSection(style, instructions) {
|
|
49
|
+
const body = style === 'custom'
|
|
50
|
+
? parseCustomInstructions(instructions)
|
|
51
|
+
: STYLE_INSTRUCTIONS[style].map((instruction) => `- ${instruction}`).join('\n');
|
|
43
52
|
return [
|
|
44
53
|
'## Output Style',
|
|
45
54
|
'',
|
|
46
55
|
OUTPUT_STYLE_START,
|
|
47
|
-
|
|
56
|
+
body,
|
|
48
57
|
OUTPUT_STYLE_END,
|
|
49
58
|
].join('\n');
|
|
50
59
|
}
|
|
51
|
-
export function createOutputStyleExtension(value = DEFAULT_OUTPUT_STYLE) {
|
|
60
|
+
export function createOutputStyleExtension(value = DEFAULT_OUTPUT_STYLE, instructions) {
|
|
52
61
|
const style = parseOutputStyle(value);
|
|
53
|
-
const section = formatOutputStyleSection(style);
|
|
62
|
+
const section = formatOutputStyleSection(style, instructions);
|
|
54
63
|
return (pi) => {
|
|
55
64
|
pi.on('before_agent_start', (event) => {
|
|
56
65
|
return { systemPrompt: `${event.systemPrompt}\n\n${section}` };
|
|
57
66
|
});
|
|
58
67
|
};
|
|
59
68
|
}
|
|
60
|
-
const outputStyleExtension = ((pi) => createOutputStyleExtension(pi.config?.style ?? DEFAULT_OUTPUT_STYLE)(pi));
|
|
69
|
+
const outputStyleExtension = ((pi) => createOutputStyleExtension(pi.config?.style ?? DEFAULT_OUTPUT_STYLE, pi.config?.instructions)(pi));
|
|
61
70
|
associateExtensionConfig(outputStyleExtension, OUTPUT_STYLE_CONFIG);
|
|
62
71
|
export default outputStyleExtension;
|
|
72
|
+
function parseCustomInstructions(value) {
|
|
73
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
74
|
+
throw new Error('outputStyle.instructions must be a non-empty string when outputStyle is custom');
|
|
75
|
+
}
|
|
76
|
+
return value.trim();
|
|
77
|
+
}
|
|
63
78
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,qBAAqB,EAA+C,MAAM,sBAAsB,CAAC;AAEjJ,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,qBAAqB,EAA+C,MAAM,sBAAsB,CAAC;AAEjJ,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAU,CAAC;AAG3E,MAAM,CAAC,MAAM,oBAAoB,GAAgB,SAAS,CAAC;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;IACvD,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,cAAc;IACrB,MAAM,EAAE;QACN,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE;YACrC,OAAO,EAAE,oBAAoB;YAC7B,WAAW,EAAE,uCAAuC;YACpD,OAAO,EAAE,cAAc;SACxB,CAAC;QACF,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC;YAC/B,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,oEAAoE;YACjF,OAAO,EAAE,2BAA2B;SACrC,CAAC;KACH;CACF,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAC5C,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAE3C,MAAM,kBAAkB,GAAwE;IAC9F,OAAO,EAAE;QACP,sIAAsI;QACtI,8HAA8H;QAC9H,wPAAwP;QACxP,mIAAmI;QACnI,0HAA0H;QAC1H,yIAAyI;QACzI,mHAAmH;QACnH,qRAAqR;QACrR,qMAAqM;QACrM,iIAAiI;QACjI,iKAAiK;KAClK;IACD,WAAW,EAAE;QACX,mFAAmF;QACnF,8FAA8F;QAC9F,+EAA+E;KAChF;CACF,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,QAAiB,oBAAoB;IACpE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,KAAoB,CAAC,EAAE,CAAC;QAC9E,OAAO,KAAoB,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAkB,EAAE,YAAsB;IACjF,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ;QAC7B,CAAC,CAAC,uBAAuB,CAAC,YAAY,CAAC;QACvC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,KAAK,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClF,OAAO;QACL,iBAAiB;QACjB,EAAE;QACF,kBAAkB;QAClB,IAAI;QACJ,gBAAgB;KACjB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,QAAiB,oBAAoB,EACrC,YAAsB;IAEtB,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,wBAAwB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAE9D,OAAO,CAAC,EAAE,EAAE,EAAE;QACZ,EAAE,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;YACpC,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC,YAAY,OAAO,OAAO,EAAE,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,oBAAoB,GAAmB,CAAC,CAAC,EAAqB,EAAE,EAAE,CAAC,0BAA0B,CACjG,EAAE,CAAC,MAAM,EAAE,KAAK,IAAI,oBAAoB,EACxC,EAAE,CAAC,MAAM,EAAE,YAAY,CACxB,CAAC,EAAE,CAAC,CAAC,CAAC;AACP,wBAAwB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;AAEpE,eAAe,oBAAoB,CAAC;AAEpC,SAAS,uBAAuB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@felan-ai/ext-output-style",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Portable output-style system prompt extension for Felan",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@felan-ai/agent-core": "^0.5.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@felan-ai/agent-core": "0.5.
|
|
31
|
+
"@felan-ai/agent-core": "0.5.3"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public",
|