faceted-prompting 0.1.0 → 0.2.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/README.md +155 -16
- package/bin/facet +2 -0
- package/dist/cli/compose-context.d.ts +8 -0
- package/dist/cli/compose-context.d.ts.map +1 -0
- package/dist/cli/compose-context.js +194 -0
- package/dist/cli/compose-context.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +144 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/install-skill/facets.d.ts +28 -0
- package/dist/cli/install-skill/facets.d.ts.map +1 -0
- package/dist/cli/install-skill/facets.js +160 -0
- package/dist/cli/install-skill/facets.js.map +1 -0
- package/dist/cli/install-skill/flow.d.ts +13 -0
- package/dist/cli/install-skill/flow.d.ts.map +1 -0
- package/dist/cli/install-skill/flow.js +63 -0
- package/dist/cli/install-skill/flow.js.map +1 -0
- package/dist/cli/install-skill/modes.d.ts +27 -0
- package/dist/cli/install-skill/modes.d.ts.map +1 -0
- package/dist/cli/install-skill/modes.js +130 -0
- package/dist/cli/install-skill/modes.js.map +1 -0
- package/dist/cli/install-skill/targets.d.ts +10 -0
- package/dist/cli/install-skill/targets.d.ts.map +1 -0
- package/dist/cli/install-skill/targets.js +27 -0
- package/dist/cli/install-skill/targets.js.map +1 -0
- package/dist/cli/path-guard.d.ts +12 -0
- package/dist/cli/path-guard.d.ts.map +1 -0
- package/dist/cli/path-guard.js +81 -0
- package/dist/cli/path-guard.js.map +1 -0
- package/dist/cli/runner.d.ts +10 -0
- package/dist/cli/runner.d.ts.map +1 -0
- package/dist/cli/runner.js +66 -0
- package/dist/cli/runner.js.map +1 -0
- package/dist/cli/select.d.ts +7 -0
- package/dist/cli/select.d.ts.map +1 -0
- package/dist/cli/select.js +70 -0
- package/dist/cli/select.js.map +1 -0
- package/dist/cli/skill-commands.d.ts +8 -0
- package/dist/cli/skill-commands.d.ts.map +1 -0
- package/dist/cli/skill-commands.js +44 -0
- package/dist/cli/skill-commands.js.map +1 -0
- package/dist/cli/skill-file-ops.d.ts +3 -0
- package/dist/cli/skill-file-ops.d.ts.map +1 -0
- package/dist/cli/skill-file-ops.js +89 -0
- package/dist/cli/skill-file-ops.js.map +1 -0
- package/dist/cli/skill-renderer.d.ts +24 -0
- package/dist/cli/skill-renderer.d.ts.map +1 -0
- package/dist/cli/skill-renderer.js +194 -0
- package/dist/cli/skill-renderer.js.map +1 -0
- package/dist/cli/skill-types.d.ts +31 -0
- package/dist/cli/skill-types.d.ts.map +1 -0
- package/dist/cli/skill-types.js +2 -0
- package/dist/cli/skill-types.js.map +1 -0
- package/dist/cli/types.d.ts +17 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/compose-definition.d.ts +3 -0
- package/dist/compose-definition.d.ts.map +1 -0
- package/dist/compose-definition.js +99 -0
- package/dist/compose-definition.js.map +1 -0
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +25 -19
- package/dist/compose.js.map +1 -1
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +82 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init/index.d.ts +17 -0
- package/dist/init/index.d.ts.map +1 -0
- package/dist/init/index.js +197 -0
- package/dist/init/index.js.map +1 -0
- package/dist/output/index.d.ts +10 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +67 -0
- package/dist/output/index.js.map +1 -0
- package/dist/prompt-payload.d.ts +8 -0
- package/dist/prompt-payload.d.ts.map +1 -0
- package/dist/prompt-payload.js +24 -0
- package/dist/prompt-payload.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +18 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose-definition.d.ts","sourceRoot":"","sources":["../src/compose-definition.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAqB,MAAM,YAAY,CAAC;AA+EvE,wBAAsB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAyB9F"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { parse } from 'yaml';
|
|
3
|
+
const ALLOWED_COMPOSE_KEYS = new Set([
|
|
4
|
+
'name',
|
|
5
|
+
'description',
|
|
6
|
+
'persona',
|
|
7
|
+
'template',
|
|
8
|
+
'knowledge',
|
|
9
|
+
'policies',
|
|
10
|
+
'instruction',
|
|
11
|
+
'order',
|
|
12
|
+
]);
|
|
13
|
+
const ORDER_VALUES = new Set(['persona', 'knowledge', 'policies', 'instruction']);
|
|
14
|
+
function normalizeOrder(rawOrder) {
|
|
15
|
+
if (!rawOrder)
|
|
16
|
+
return undefined;
|
|
17
|
+
const normalized = [];
|
|
18
|
+
const seen = new Set();
|
|
19
|
+
for (const entry of rawOrder) {
|
|
20
|
+
if (!ORDER_VALUES.has(entry)) {
|
|
21
|
+
throw new Error(`Invalid compose order entry: ${entry}`);
|
|
22
|
+
}
|
|
23
|
+
if (entry === 'persona')
|
|
24
|
+
continue;
|
|
25
|
+
const typedEntry = entry;
|
|
26
|
+
if (seen.has(typedEntry))
|
|
27
|
+
continue;
|
|
28
|
+
seen.add(typedEntry);
|
|
29
|
+
normalized.push(typedEntry);
|
|
30
|
+
}
|
|
31
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
32
|
+
}
|
|
33
|
+
function ensureStringList(value, field) {
|
|
34
|
+
if (value === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (!Array.isArray(value)) {
|
|
37
|
+
throw new Error(`${field} must be a YAML list`);
|
|
38
|
+
}
|
|
39
|
+
if (!value.every(entry => typeof entry === 'string')) {
|
|
40
|
+
throw new Error(`${field} must contain only strings`);
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
function ensureOptionalString(value, field) {
|
|
45
|
+
if (value === undefined)
|
|
46
|
+
return undefined;
|
|
47
|
+
if (typeof value !== 'string') {
|
|
48
|
+
throw new Error(`${field} must be a scalar string`);
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
function ensureRequiredString(value, field) {
|
|
53
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
54
|
+
throw new Error(`Compose definition must include required field: ${field}`);
|
|
55
|
+
}
|
|
56
|
+
return value.trim();
|
|
57
|
+
}
|
|
58
|
+
function parseComposeDefinitionYaml(rawYaml) {
|
|
59
|
+
const parsed = parse(rawYaml);
|
|
60
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
61
|
+
throw new Error('Compose definition must be a YAML object');
|
|
62
|
+
}
|
|
63
|
+
for (const key of Object.keys(parsed)) {
|
|
64
|
+
if (!ALLOWED_COMPOSE_KEYS.has(key)) {
|
|
65
|
+
throw new Error(`Unknown compose definition key: ${key}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
function toOptionalNonEmpty(value) {
|
|
71
|
+
if (!value)
|
|
72
|
+
return undefined;
|
|
73
|
+
const trimmed = value.trim();
|
|
74
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
75
|
+
}
|
|
76
|
+
export async function loadComposeDefinition(definitionPath) {
|
|
77
|
+
const rawYaml = readFileSync(definitionPath, 'utf-8');
|
|
78
|
+
const parsed = parseComposeDefinitionYaml(rawYaml);
|
|
79
|
+
const name = ensureRequiredString(parsed.name, 'name');
|
|
80
|
+
const persona = ensureRequiredString(parsed.persona, 'persona');
|
|
81
|
+
const description = ensureOptionalString(parsed.description, 'description');
|
|
82
|
+
const template = ensureOptionalString(parsed.template, 'template');
|
|
83
|
+
const instruction = ensureOptionalString(parsed.instruction, 'instruction');
|
|
84
|
+
const knowledge = ensureStringList(parsed.knowledge, 'knowledge');
|
|
85
|
+
const policies = ensureStringList(parsed.policies, 'policies');
|
|
86
|
+
const rawOrder = ensureStringList(parsed.order, 'order');
|
|
87
|
+
const order = normalizeOrder(rawOrder);
|
|
88
|
+
return {
|
|
89
|
+
name,
|
|
90
|
+
description: toOptionalNonEmpty(description),
|
|
91
|
+
persona,
|
|
92
|
+
template: toOptionalNonEmpty(template),
|
|
93
|
+
knowledge: knowledge && knowledge.length > 0 ? knowledge : undefined,
|
|
94
|
+
policies: policies && policies.length > 0 ? policies : undefined,
|
|
95
|
+
instruction: toOptionalNonEmpty(instruction),
|
|
96
|
+
order,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=compose-definition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose-definition.js","sourceRoot":"","sources":["../src/compose-definition.ts"],"names":[],"mappings":"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"}
|
package/dist/compose.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG3E;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG3E;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,GAAG,cAAc,CAwCjF"}
|
package/dist/compose.js
CHANGED
|
@@ -17,25 +17,31 @@ import { prepareKnowledgeContent, preparePolicyContent } from './truncation.js';
|
|
|
17
17
|
export function compose(facets, options) {
|
|
18
18
|
const systemPrompt = facets.persona?.body ?? '';
|
|
19
19
|
const userParts = [];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
20
|
+
const order = options.userMessageOrder ?? ['policies', 'knowledge', 'instruction'];
|
|
21
|
+
for (const entry of order) {
|
|
22
|
+
if (entry === 'policies') {
|
|
23
|
+
if (!facets.policies || facets.policies.length === 0)
|
|
24
|
+
continue;
|
|
25
|
+
const joined = facets.policies.map(p => p.body).join('\n\n---\n\n');
|
|
26
|
+
const sourcePath = facets.policies.length === 1
|
|
27
|
+
? facets.policies[0].sourcePath
|
|
28
|
+
: undefined;
|
|
29
|
+
userParts.push(preparePolicyContent(joined, options.contextMaxChars, sourcePath));
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (entry === 'knowledge') {
|
|
33
|
+
if (!facets.knowledge || facets.knowledge.length === 0)
|
|
34
|
+
continue;
|
|
35
|
+
const joined = facets.knowledge.map(k => k.body).join('\n\n---\n\n');
|
|
36
|
+
const sourcePath = facets.knowledge.length === 1
|
|
37
|
+
? facets.knowledge[0].sourcePath
|
|
38
|
+
: undefined;
|
|
39
|
+
userParts.push(prepareKnowledgeContent(joined, options.contextMaxChars, sourcePath));
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (entry === 'instruction' && facets.instruction) {
|
|
43
|
+
userParts.push(facets.instruction.body);
|
|
44
|
+
}
|
|
39
45
|
}
|
|
40
46
|
return {
|
|
41
47
|
systemPrompt,
|
package/dist/compose.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,MAAgB,EAAE,OAAuB;IAC/D,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;IAEhD,MAAM,SAAS,GAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,MAAgB,EAAE,OAAuB;IAC/D,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;IAEhD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IAEnF,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpE,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAC7C,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,UAAU;gBAChC,CAAC,CAAC,SAAS,CAAC;YACd,SAAS,CAAC,IAAI,CACZ,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,UAAU,CAAC,CAClE,CAAC;YACF,SAAS;QACX,CAAC;QAED,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACjE,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACrE,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;gBAC9C,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,UAAU;gBACjC,CAAC,CAAC,SAAS,CAAC;YACd,SAAS,CAAC,IAAI,CACZ,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,UAAU,CAAC,CACrE,CAAC;YACF,SAAS;QACX,CAAC;QAED,IAAI,KAAK,KAAK,aAAa,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAClD,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO;QACL,YAAY;QACZ,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;KACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface FacetedConfig {
|
|
2
|
+
readonly version: number;
|
|
3
|
+
readonly skillPaths?: readonly string[];
|
|
4
|
+
}
|
|
5
|
+
export declare function getFacetedRoot(homeDir: string): string;
|
|
6
|
+
export declare function getConfigPath(homeDir: string): string;
|
|
7
|
+
export declare function ensureConfigFile(homeDir: string): void;
|
|
8
|
+
export declare function readFacetedConfig(homeDir: string): Promise<FacetedConfig>;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAID,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQtD;AAkBD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmD/E"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { tracedConfig } from 'traced-config';
|
|
4
|
+
import { parse } from 'yaml';
|
|
5
|
+
const DEFAULT_CONFIG = ['version: 1', 'skillPaths: []'].join('\n');
|
|
6
|
+
export function getFacetedRoot(homeDir) {
|
|
7
|
+
return join(homeDir, '.faceted');
|
|
8
|
+
}
|
|
9
|
+
export function getConfigPath(homeDir) {
|
|
10
|
+
return join(getFacetedRoot(homeDir), 'config.yaml');
|
|
11
|
+
}
|
|
12
|
+
export function ensureConfigFile(homeDir) {
|
|
13
|
+
const root = getFacetedRoot(homeDir);
|
|
14
|
+
mkdirSync(root, { recursive: true });
|
|
15
|
+
const configPath = getConfigPath(homeDir);
|
|
16
|
+
if (!existsSync(configPath)) {
|
|
17
|
+
writeFileSync(configPath, `${DEFAULT_CONFIG}\n`, 'utf-8');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function parseConfigRootAsObject(content) {
|
|
21
|
+
const parsed = parse(content);
|
|
22
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
23
|
+
throw new Error('Config root must be an object');
|
|
24
|
+
}
|
|
25
|
+
return parsed;
|
|
26
|
+
}
|
|
27
|
+
function hasErrorCode(error) {
|
|
28
|
+
if (typeof error !== 'object' || error === null) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const withCode = error;
|
|
32
|
+
return typeof withCode.code === 'string';
|
|
33
|
+
}
|
|
34
|
+
export async function readFacetedConfig(homeDir) {
|
|
35
|
+
const configPath = getConfigPath(homeDir);
|
|
36
|
+
if (!existsSync(configPath)) {
|
|
37
|
+
throw new Error(`Missing faceted config: ${configPath}`);
|
|
38
|
+
}
|
|
39
|
+
const resolver = tracedConfig({
|
|
40
|
+
schema: {
|
|
41
|
+
version: {
|
|
42
|
+
default: 1,
|
|
43
|
+
doc: 'config schema version',
|
|
44
|
+
format: Number,
|
|
45
|
+
sources: { global: false, local: true, env: false, cli: false },
|
|
46
|
+
},
|
|
47
|
+
skillPaths: {
|
|
48
|
+
default: [],
|
|
49
|
+
doc: 'skill path list',
|
|
50
|
+
format: 'string-list',
|
|
51
|
+
sources: { global: false, local: true, env: false, cli: false },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
resolver.addFormat('string-list', value => {
|
|
56
|
+
return Array.isArray(value) && value.every(item => typeof item === 'string');
|
|
57
|
+
});
|
|
58
|
+
resolver.addParser('yaml', parseConfigRootAsObject);
|
|
59
|
+
resolver.addParser('yml', parseConfigRootAsObject);
|
|
60
|
+
try {
|
|
61
|
+
await resolver.loadFile([{ path: configPath, label: 'local' }]);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (hasErrorCode(error)) {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Invalid faceted config file: ${configPath}`);
|
|
68
|
+
}
|
|
69
|
+
const validationIssues = resolver.validate();
|
|
70
|
+
if (validationIssues.length > 0) {
|
|
71
|
+
const invalidField = validationIssues[0]?.key;
|
|
72
|
+
if (invalidField) {
|
|
73
|
+
throw new Error(`Invalid faceted config field: ${invalidField}`);
|
|
74
|
+
}
|
|
75
|
+
throw new Error('Invalid faceted config field');
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
version: resolver.get('version'),
|
|
79
|
+
skillPaths: resolver.get('skillPaths'),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* Re-exports all public types, interfaces, and functions.
|
|
5
5
|
* Consumers should import from this module only.
|
|
6
6
|
*/
|
|
7
|
-
export type { FacetKind, FacetContent, FacetSet, ComposedPrompt, ComposeOptions, } from './types.js';
|
|
7
|
+
export type { FacetKind, FacetContent, FacetSet, ComposedPrompt, ComposedPromptPayload, ComposeOptions, CopyFiles, } from './types.js';
|
|
8
8
|
export { compose } from './compose.js';
|
|
9
|
+
export { composePromptPayload } from './prompt-payload.js';
|
|
9
10
|
export type { DataEngine } from './data-engine.js';
|
|
10
11
|
export { FileDataEngine, CompositeDataEngine } from './data-engine.js';
|
|
11
12
|
export { trimContextContent, renderConflictNotice, prepareKnowledgeContent, preparePolicyContent, } from './truncation.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,SAAS,GACV,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvE,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,yBAAyB,EACzB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
// Compose
|
|
8
8
|
export { compose } from './compose.js';
|
|
9
|
+
export { composePromptPayload } from './prompt-payload.js';
|
|
9
10
|
export { FileDataEngine, CompositeDataEngine } from './data-engine.js';
|
|
10
11
|
// Truncation
|
|
11
12
|
export { trimContextContent, renderConflictNotice, prepareKnowledgeContent, preparePolicyContent, } from './truncation.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,UAAU;AACV,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAI3D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,aAAa;AACb,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAEzB,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,SAAS;AACT,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIlD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,yBAAyB,EACzB,cAAc,GACf,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type FetchResponseLike = {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
status: number;
|
|
4
|
+
text(): Promise<string>;
|
|
5
|
+
};
|
|
6
|
+
type FetchLike = (input: string) => Promise<FetchResponseLike>;
|
|
7
|
+
export declare function listPullSampleTargetPaths(homeDir: string): string[];
|
|
8
|
+
export declare function initializeFacetedHome(options: {
|
|
9
|
+
homeDir: string;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
export declare function pullSampleFacets(options: {
|
|
12
|
+
homeDir: string;
|
|
13
|
+
fetchImpl?: FetchLike;
|
|
14
|
+
overwrite?: boolean;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"AAqJA,KAAK,iBAAiB,GAAG;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB,CAAC;AAEF,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAuB/D,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAGnE;AAcD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBvF;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9H"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { ensureConfigFile, getFacetedRoot } from '../config/index.js';
|
|
4
|
+
const REQUIRED_FACET_DIRS = ['persona', 'knowledge', 'policies', 'output-contracts'];
|
|
5
|
+
const TAKT_BOOTSTRAP_BASE_URL = 'https://raw.githubusercontent.com/nrslib/takt/main/builtins/ja/facets';
|
|
6
|
+
function makeComposition(name, description, knowledge) {
|
|
7
|
+
const lines = [
|
|
8
|
+
`name: ${name}`,
|
|
9
|
+
`description: ${description}`,
|
|
10
|
+
'persona: coder',
|
|
11
|
+
'policies:',
|
|
12
|
+
' - coding',
|
|
13
|
+
' - ai-antipattern',
|
|
14
|
+
'knowledge:',
|
|
15
|
+
...knowledge.map(k => ` - ${k}`),
|
|
16
|
+
];
|
|
17
|
+
return lines.join('\n') + '\n';
|
|
18
|
+
}
|
|
19
|
+
const DEFAULT_COMPOSITIONS = [
|
|
20
|
+
{
|
|
21
|
+
relativePath: 'compositions/coding.yaml',
|
|
22
|
+
content: makeComposition('coding', 'General coding with architecture knowledge', ['architecture']),
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
relativePath: 'compositions/frontend.yaml',
|
|
26
|
+
content: makeComposition('frontend', 'Frontend coding with architecture + frontend knowledge', ['architecture', 'frontend']),
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
relativePath: 'compositions/backend.yaml',
|
|
30
|
+
content: makeComposition('backend', 'Backend coding with architecture + backend knowledge', ['architecture', 'backend']),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
relativePath: 'compositions/issue-worktree.yaml',
|
|
34
|
+
content: [
|
|
35
|
+
'name: issue-worktree',
|
|
36
|
+
'description: Issue-oriented coding skill deployed from a multi-file template',
|
|
37
|
+
'persona: coder',
|
|
38
|
+
'policies:',
|
|
39
|
+
' - coding',
|
|
40
|
+
' - ai-antipattern',
|
|
41
|
+
'knowledge:',
|
|
42
|
+
' - architecture',
|
|
43
|
+
'instruction: |',
|
|
44
|
+
' Confirm the issue scope before editing, keep the change minimal, and report build/test results.',
|
|
45
|
+
'template: issue-worktree',
|
|
46
|
+
'',
|
|
47
|
+
].join('\n'),
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
const DEFAULT_TEMPLATES = [
|
|
51
|
+
{
|
|
52
|
+
relativePath: 'templates/issue-worktree/SKILL.md',
|
|
53
|
+
content: [
|
|
54
|
+
'# Issue Worker',
|
|
55
|
+
'',
|
|
56
|
+
'## Persona',
|
|
57
|
+
'{{facet:persona}}',
|
|
58
|
+
'',
|
|
59
|
+
'## Policies',
|
|
60
|
+
'{{facet:policies}}',
|
|
61
|
+
'',
|
|
62
|
+
'## Knowledge',
|
|
63
|
+
'{{facet:knowledges}}',
|
|
64
|
+
'',
|
|
65
|
+
'## Instructions',
|
|
66
|
+
'{{facet:instructions}}',
|
|
67
|
+
'',
|
|
68
|
+
'## Workflow',
|
|
69
|
+
'- Confirm the issue scope before editing.',
|
|
70
|
+
'- Keep changes minimal and explicit.',
|
|
71
|
+
'- Run build/test and report the outcome.',
|
|
72
|
+
'',
|
|
73
|
+
].join('\n'),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
relativePath: 'templates/issue-worktree/README.md',
|
|
77
|
+
content: [
|
|
78
|
+
'# Issue Worker Template',
|
|
79
|
+
'',
|
|
80
|
+
'This sample template shows how a multi-file skill workspace can be structured for issue-oriented coding tasks.',
|
|
81
|
+
'',
|
|
82
|
+
'Included files:',
|
|
83
|
+
'- `SKILL.md`',
|
|
84
|
+
'- `templates/instructions/fix.md`',
|
|
85
|
+
'- `templates/instructions/review.md`',
|
|
86
|
+
'',
|
|
87
|
+
'Facet placeholders in `SKILL.md` are replaced during `facet install skill`.',
|
|
88
|
+
'',
|
|
89
|
+
].join('\n'),
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
relativePath: 'templates/issue-worktree/templates/instructions/fix.md',
|
|
93
|
+
content: [
|
|
94
|
+
'# Fix Checklist',
|
|
95
|
+
'',
|
|
96
|
+
'- Reproduce the issue first.',
|
|
97
|
+
'- Verify the smallest safe fix.',
|
|
98
|
+
'- Record build/test evidence after the change.',
|
|
99
|
+
'',
|
|
100
|
+
].join('\n'),
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
relativePath: 'templates/issue-worktree/templates/instructions/review.md',
|
|
104
|
+
content: [
|
|
105
|
+
'# Review Checklist',
|
|
106
|
+
'',
|
|
107
|
+
'- Check for scope creep.',
|
|
108
|
+
'- Check for missing tests or validation.',
|
|
109
|
+
'- Check for hidden fallback logic.',
|
|
110
|
+
'',
|
|
111
|
+
].join('\n'),
|
|
112
|
+
},
|
|
113
|
+
...DEFAULT_COMPOSITIONS,
|
|
114
|
+
];
|
|
115
|
+
const BOOTSTRAP_TARGETS = [
|
|
116
|
+
{
|
|
117
|
+
localRelativePath: 'facets/persona/coder.md',
|
|
118
|
+
remoteRelativePath: 'personas/coder.md',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
localRelativePath: 'facets/knowledge/architecture.md',
|
|
122
|
+
remoteRelativePath: 'knowledge/architecture.md',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
localRelativePath: 'facets/knowledge/frontend.md',
|
|
126
|
+
remoteRelativePath: 'knowledge/frontend.md',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
localRelativePath: 'facets/knowledge/backend.md',
|
|
130
|
+
remoteRelativePath: 'knowledge/backend.md',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
localRelativePath: 'facets/policies/coding.md',
|
|
134
|
+
remoteRelativePath: 'policies/coding.md',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
localRelativePath: 'facets/policies/ai-antipattern.md',
|
|
138
|
+
remoteRelativePath: 'policies/ai-antipattern.md',
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
function resolveFetchImpl(fetchImpl) {
|
|
142
|
+
if (fetchImpl) {
|
|
143
|
+
return fetchImpl;
|
|
144
|
+
}
|
|
145
|
+
if (typeof globalThis.fetch !== 'function') {
|
|
146
|
+
throw new Error('Global fetch is not available');
|
|
147
|
+
}
|
|
148
|
+
return globalThis.fetch.bind(globalThis);
|
|
149
|
+
}
|
|
150
|
+
async function fetchBootstrapContent(remoteRelativePath, fetchImpl) {
|
|
151
|
+
const response = await fetchImpl(`${TAKT_BOOTSTRAP_BASE_URL}/${remoteRelativePath}`);
|
|
152
|
+
if (!response.ok) {
|
|
153
|
+
throw new Error(`Failed to fetch bootstrap facet: ${remoteRelativePath} (status: ${response.status})`);
|
|
154
|
+
}
|
|
155
|
+
return response.text();
|
|
156
|
+
}
|
|
157
|
+
export function listPullSampleTargetPaths(homeDir) {
|
|
158
|
+
const facetedRoot = getFacetedRoot(homeDir);
|
|
159
|
+
return BOOTSTRAP_TARGETS.map(target => join(facetedRoot, target.localRelativePath));
|
|
160
|
+
}
|
|
161
|
+
async function bootstrapDefaultFacets(facetedRoot, fetchImpl, overwrite) {
|
|
162
|
+
for (const target of BOOTSTRAP_TARGETS) {
|
|
163
|
+
const targetPath = join(facetedRoot, target.localRelativePath);
|
|
164
|
+
if (existsSync(targetPath) && !overwrite) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const content = await fetchBootstrapContent(target.remoteRelativePath, fetchImpl);
|
|
168
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
169
|
+
writeFileSync(targetPath, content, 'utf-8');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
export async function initializeFacetedHome(options) {
|
|
173
|
+
const facetedRoot = getFacetedRoot(options.homeDir);
|
|
174
|
+
ensureConfigFile(options.homeDir);
|
|
175
|
+
const facetsRoot = join(facetedRoot, 'facets');
|
|
176
|
+
const compositionsRoot = join(facetedRoot, 'compositions');
|
|
177
|
+
const templatesRoot = join(facetedRoot, 'templates');
|
|
178
|
+
mkdirSync(facetsRoot, { recursive: true });
|
|
179
|
+
mkdirSync(compositionsRoot, { recursive: true });
|
|
180
|
+
mkdirSync(templatesRoot, { recursive: true });
|
|
181
|
+
for (const dirName of REQUIRED_FACET_DIRS) {
|
|
182
|
+
mkdirSync(join(facetsRoot, dirName), { recursive: true });
|
|
183
|
+
}
|
|
184
|
+
for (const template of DEFAULT_TEMPLATES) {
|
|
185
|
+
const targetPath = join(facetedRoot, template.relativePath);
|
|
186
|
+
if (!existsSync(targetPath)) {
|
|
187
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
188
|
+
writeFileSync(targetPath, template.content, 'utf-8');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export async function pullSampleFacets(options) {
|
|
193
|
+
await initializeFacetedHome({ homeDir: options.homeDir });
|
|
194
|
+
const facetedRoot = getFacetedRoot(options.homeDir);
|
|
195
|
+
await bootstrapDefaultFacets(facetedRoot, resolveFetchImpl(options.fetchImpl), options.overwrite ?? false);
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ComposedPrompt } from '../types.js';
|
|
2
|
+
export declare function resolveOutputDirectory(inputValue: string, defaultDirectory: string): string;
|
|
3
|
+
export declare function formatCombinedOutput(composed: ComposedPrompt): string;
|
|
4
|
+
export declare function writeComposeOutput(options: {
|
|
5
|
+
outputDir: string;
|
|
6
|
+
fileName: string;
|
|
7
|
+
content: string;
|
|
8
|
+
overwrite: boolean;
|
|
9
|
+
}): Promise<string>;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/output/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAM3F;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CASrE;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDlB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { closeSync, constants, mkdirSync, openSync, realpathSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename, dirname, resolve, sep } from 'node:path';
|
|
3
|
+
export function resolveOutputDirectory(inputValue, defaultDirectory) {
|
|
4
|
+
const trimmed = inputValue.trim();
|
|
5
|
+
if (trimmed.length === 0) {
|
|
6
|
+
return defaultDirectory;
|
|
7
|
+
}
|
|
8
|
+
return resolve(defaultDirectory, trimmed);
|
|
9
|
+
}
|
|
10
|
+
export function formatCombinedOutput(composed) {
|
|
11
|
+
const parts = [];
|
|
12
|
+
if (composed.systemPrompt.length > 0) {
|
|
13
|
+
parts.push(composed.systemPrompt);
|
|
14
|
+
}
|
|
15
|
+
if (composed.userMessage.length > 0) {
|
|
16
|
+
parts.push(composed.userMessage);
|
|
17
|
+
}
|
|
18
|
+
return parts.join('\n\n') + '\n';
|
|
19
|
+
}
|
|
20
|
+
export async function writeComposeOutput(options) {
|
|
21
|
+
const outputDir = resolve(options.outputDir);
|
|
22
|
+
mkdirSync(outputDir, { recursive: true });
|
|
23
|
+
const outputDirRealPath = realpathSync(outputDir);
|
|
24
|
+
if (basename(options.fileName) !== options.fileName) {
|
|
25
|
+
throw new Error(`Output file name must not include path segments: ${options.fileName}`);
|
|
26
|
+
}
|
|
27
|
+
const outputPath = resolve(outputDir, options.fileName);
|
|
28
|
+
if (!(outputPath === outputDir || outputPath.startsWith(`${outputDir}${sep}`))) {
|
|
29
|
+
throw new Error(`Output path escapes target directory: ${options.fileName}`);
|
|
30
|
+
}
|
|
31
|
+
const outputParentDirectory = dirname(outputPath);
|
|
32
|
+
mkdirSync(outputParentDirectory, { recursive: true });
|
|
33
|
+
const outputParentRealPath = realpathSync(outputParentDirectory);
|
|
34
|
+
if (!(outputParentRealPath === outputDirRealPath || outputParentRealPath.startsWith(`${outputDirRealPath}${sep}`))) {
|
|
35
|
+
throw new Error(`Output path escapes target directory: ${options.fileName}`);
|
|
36
|
+
}
|
|
37
|
+
const openFlags = constants.O_WRONLY
|
|
38
|
+
| constants.O_CREAT
|
|
39
|
+
| (options.overwrite ? constants.O_TRUNC : constants.O_EXCL)
|
|
40
|
+
| constants.O_NOFOLLOW;
|
|
41
|
+
let fileDescriptor;
|
|
42
|
+
try {
|
|
43
|
+
fileDescriptor = openSync(outputPath, openFlags, 0o600);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const errorCode = error.code;
|
|
47
|
+
if (errorCode === 'ELOOP') {
|
|
48
|
+
throw new Error(`Symbolic links are not allowed for output file: ${outputPath}`);
|
|
49
|
+
}
|
|
50
|
+
if (errorCode === 'EEXIST' && !options.overwrite) {
|
|
51
|
+
throw new Error(`Output file exists and overwrite was cancelled: ${outputPath}`);
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
writeFileSync(fileDescriptor, options.content, 'utf-8');
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
closeSync(fileDescriptor);
|
|
60
|
+
}
|
|
61
|
+
const outputRealPath = realpathSync(outputPath);
|
|
62
|
+
if (!(outputRealPath === outputDirRealPath || outputRealPath.startsWith(`${outputDirRealPath}${sep}`))) {
|
|
63
|
+
throw new Error(`Output path escapes target directory: ${options.fileName}`);
|
|
64
|
+
}
|
|
65
|
+
return outputPath;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=index.js.map
|