@tienne/gestalt 0.6.0 โ 0.7.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.ko.md +21 -0
- package/README.md +21 -0
- package/dist/package.json +2 -1
- package/dist/src/cli/commands/interview.d.ts +1 -0
- package/dist/src/cli/commands/interview.d.ts.map +1 -1
- package/dist/src/cli/commands/interview.js +12 -53
- package/dist/src/cli/commands/interview.js.map +1 -1
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +2 -1
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/mcp/schemas.d.ts +3 -0
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +2 -0
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.js +26 -1
- package/dist/src/mcp/tools/interview-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/interview.d.ts.map +1 -1
- package/dist/src/mcp/tools/interview.js +26 -1
- package/dist/src/mcp/tools/interview.js.map +1 -1
- package/dist/src/recording/agg-converter.d.ts +25 -0
- package/dist/src/recording/agg-converter.d.ts.map +1 -0
- package/dist/src/recording/agg-converter.js +80 -0
- package/dist/src/recording/agg-converter.js.map +1 -0
- package/dist/src/recording/agg-installer.d.ts +6 -0
- package/dist/src/recording/agg-installer.d.ts.map +1 -0
- package/dist/src/recording/agg-installer.js +50 -0
- package/dist/src/recording/agg-installer.js.map +1 -0
- package/dist/src/recording/asciinema-installer.d.ts +6 -0
- package/dist/src/recording/asciinema-installer.d.ts.map +1 -0
- package/dist/src/recording/asciinema-installer.js +50 -0
- package/dist/src/recording/asciinema-installer.js.map +1 -0
- package/dist/src/recording/asciinema-recorder.d.ts +26 -0
- package/dist/src/recording/asciinema-recorder.d.ts.map +1 -0
- package/dist/src/recording/asciinema-recorder.js +52 -0
- package/dist/src/recording/asciinema-recorder.js.map +1 -0
- package/dist/src/recording/cast-generator.d.ts +7 -0
- package/dist/src/recording/cast-generator.d.ts.map +1 -0
- package/dist/src/recording/cast-generator.js +72 -0
- package/dist/src/recording/cast-generator.js.map +1 -0
- package/dist/src/recording/filename-generator.d.ts +1 -0
- package/dist/src/recording/filename-generator.d.ts.map +1 -1
- package/dist/src/recording/filename-generator.js +7 -0
- package/dist/src/recording/filename-generator.js.map +1 -1
- package/dist/src/recording/recording-orchestrator.d.ts +50 -0
- package/dist/src/recording/recording-orchestrator.d.ts.map +1 -0
- package/dist/src/recording/recording-orchestrator.js +98 -0
- package/dist/src/recording/recording-orchestrator.js.map +1 -0
- package/dist/src/scripts/postinstall.d.ts +2 -0
- package/dist/src/scripts/postinstall.d.ts.map +1 -0
- package/dist/src/scripts/postinstall.js +27 -0
- package/dist/src/scripts/postinstall.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agg-converter.js","sourceRoot":"","sources":["../../../src/recording/agg-converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agg-installer.d.ts","sourceRoot":"","sources":["../../../src/recording/agg-installer.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IACvB,WAAW,IAAI,OAAO;IAShB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAkCtC,OAAO,CAAC,UAAU;CAQnB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { execSync, spawnSync } from 'node:child_process';
|
|
2
|
+
export class AggInstaller {
|
|
3
|
+
isInstalled() {
|
|
4
|
+
try {
|
|
5
|
+
execSync('which agg', { stdio: 'pipe' });
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
async ensureInstalled() {
|
|
13
|
+
if (this.isInstalled())
|
|
14
|
+
return;
|
|
15
|
+
console.log('๐ฆ agg is not installed. Installing...');
|
|
16
|
+
const hasCargo = this.hasCommand('cargo');
|
|
17
|
+
const hasNpm = this.hasCommand('npm');
|
|
18
|
+
if (hasCargo) {
|
|
19
|
+
console.log(' โ cargo install agg');
|
|
20
|
+
const result = spawnSync('cargo', ['install', 'agg'], { stdio: 'inherit' });
|
|
21
|
+
if (result.status !== 0) {
|
|
22
|
+
throw new Error('Failed to install agg via cargo. Please install manually: https://github.com/asciinema/agg');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (hasNpm) {
|
|
26
|
+
console.log(' โ npm install -g @asciinema/agg');
|
|
27
|
+
const result = spawnSync('npm', ['install', '-g', '@asciinema/agg'], { stdio: 'inherit' });
|
|
28
|
+
if (result.status !== 0) {
|
|
29
|
+
throw new Error('Failed to install agg via npm. Please install manually: https://github.com/asciinema/agg');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
throw new Error('Neither cargo nor npm is available. Please install agg manually: https://github.com/asciinema/agg');
|
|
34
|
+
}
|
|
35
|
+
if (!this.isInstalled()) {
|
|
36
|
+
throw new Error('agg installation failed. Please install it manually: https://github.com/asciinema/agg');
|
|
37
|
+
}
|
|
38
|
+
console.log('โ
agg installed successfully.\n');
|
|
39
|
+
}
|
|
40
|
+
hasCommand(cmd) {
|
|
41
|
+
try {
|
|
42
|
+
execSync(`which ${cmd}`, { stdio: 'pipe' });
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=agg-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agg-installer.js","sourceRoot":"","sources":["../../../src/recording/agg-installer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,OAAO,YAAY;IACvB,WAAW;QACT,IAAI,CAAC;YACH,QAAQ,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO;QAE/B,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QAEtD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAEtC,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,4FAA4F,CAAC,CAAC;YAChH,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAC3F,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CACb,mGAAmG,CACpG,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IACjD,CAAC;IAEO,UAAU,CAAC,GAAW;QAC5B,IAAI,CAAC;YACH,QAAQ,CAAC,SAAS,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asciinema-installer.d.ts","sourceRoot":"","sources":["../../../src/recording/asciinema-installer.ts"],"names":[],"mappings":"AAGA,qBAAa,kBAAkB;IAC7B,WAAW,IAAI,OAAO;IAShB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAiCtC,OAAO,CAAC,mBAAmB;CAS5B"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { execSync, spawnSync } from 'node:child_process';
|
|
2
|
+
import { platform } from 'node:os';
|
|
3
|
+
export class AsciinemaInstaller {
|
|
4
|
+
isInstalled() {
|
|
5
|
+
try {
|
|
6
|
+
execSync('which asciinema', { stdio: 'pipe' });
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async ensureInstalled() {
|
|
14
|
+
if (this.isInstalled())
|
|
15
|
+
return;
|
|
16
|
+
const os = platform();
|
|
17
|
+
console.log('๐ฆ asciinema is not installed. Installing...');
|
|
18
|
+
if (os === 'darwin') {
|
|
19
|
+
this.ensureBrewAvailable();
|
|
20
|
+
console.log(' โ brew install asciinema');
|
|
21
|
+
const result = spawnSync('brew', ['install', 'asciinema'], { stdio: 'inherit' });
|
|
22
|
+
if (result.status !== 0) {
|
|
23
|
+
throw new Error('Failed to install asciinema via brew. Please install manually: brew install asciinema');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (os === 'linux') {
|
|
27
|
+
console.log(' โ pip3 install asciinema');
|
|
28
|
+
const result = spawnSync('pip3', ['install', 'asciinema'], { stdio: 'inherit' });
|
|
29
|
+
if (result.status !== 0) {
|
|
30
|
+
throw new Error('Failed to install asciinema via pip3. Please install manually: pip3 install asciinema');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw new Error(`Unsupported platform for automatic asciinema installation: ${os}. Please install asciinema manually: https://docs.asciinema.org/manual/cli/installation/`);
|
|
35
|
+
}
|
|
36
|
+
if (!this.isInstalled()) {
|
|
37
|
+
throw new Error('asciinema installation failed. Please install it manually: https://docs.asciinema.org/manual/cli/installation/');
|
|
38
|
+
}
|
|
39
|
+
console.log('โ
asciinema installed successfully.\n');
|
|
40
|
+
}
|
|
41
|
+
ensureBrewAvailable() {
|
|
42
|
+
try {
|
|
43
|
+
execSync('which brew', { stdio: 'pipe' });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
throw new Error('Homebrew is not installed. Please install it first: https://brew.sh, then run: brew install asciinema');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=asciinema-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asciinema-installer.js","sourceRoot":"","sources":["../../../src/recording/asciinema-installer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,OAAO,kBAAkB;IAC7B,WAAW;QACT,IAAI,CAAC;YACH,QAAQ,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO;QAE/B,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAE5D,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;YACpB,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACjF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;YAC3G,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACjF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;YAC3G,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CACb,8DAA8D,EAAE,0FAA0F,CAC3J,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACvD,CAAC;IAEO,mBAAmB;QACzB,IAAI,CAAC;YACH,QAAQ,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,uGAAuG,CACxG,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AsciinemaRecorder: self-respawn ํจํด์ผ๋ก asciinema ๋
นํ๋ฅผ ๊ตฌํํ๋ค.
|
|
3
|
+
*
|
|
4
|
+
* --record ํ๋๊ทธ๊ฐ ์๊ณ GESTALT_RECORDING ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด,
|
|
5
|
+
* ํ์ฌ ํ๋ก์ธ์ค๋ฅผ asciinema rec์ผ๋ก ๊ฐ์ธ์ ์ฌ์คํํ๋ค.
|
|
6
|
+
* ์ฌ์คํ๋ ํ๋ก์ธ์ค๋ GESTALT_RECORDING=1๋ก ์คํ๋๋ฏ๋ก ์ผ๋ฐ ์ธํฐ๋ทฐ ๋ก์ง์ ์ํํ๋ค.
|
|
7
|
+
*/
|
|
8
|
+
export declare class AsciinemaRecorder {
|
|
9
|
+
/** ์ด๋ฏธ asciinema๋ก ๊ฐ์ธ์ง ์ํ์ธ์ง ํ์ธ */
|
|
10
|
+
static isInsideRecording(): boolean;
|
|
11
|
+
/** ํ์ฌ ๋
นํ ์ค์ธ cast ํ์ผ ๊ฒฝ๋ก (GESTALT_CAST_PATH ํ๊ฒฝ๋ณ์) */
|
|
12
|
+
static getCurrentCastPath(): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* ์์ cast ํ์ผ ๊ฒฝ๋ก๋ฅผ ์์ฑํ๋ค.
|
|
15
|
+
* ์ค์ ํ์ผ๋ช
์ ์ธํฐ๋ทฐ ์๋ฃ ํ topic ๊ธฐ๋ฐ์ผ๋ก rename๋๋ค.
|
|
16
|
+
*/
|
|
17
|
+
static createTempCastPath(recordingsDir?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* asciinema rec์ผ๋ก ํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์ฌ์คํํ๋ค.
|
|
20
|
+
* ์ด ํจ์๋ returnํ์ง ์๋๋ค (spawnSync๊ฐ ๋ธ๋กํน).
|
|
21
|
+
*
|
|
22
|
+
* @param castPath - ๋
นํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ .cast ํ์ผ ๊ฒฝ๋ก
|
|
23
|
+
*/
|
|
24
|
+
static respawnWithAsciinema(castPath: string): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=asciinema-recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asciinema-recorder.d.ts","sourceRoot":"","sources":["../../../src/recording/asciinema-recorder.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC5B,gCAAgC;IAChC,MAAM,CAAC,iBAAiB,IAAI,OAAO;IAInC,mDAAmD;IACnD,MAAM,CAAC,kBAAkB,IAAI,MAAM,GAAG,SAAS;IAI/C;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,aAAa,SAAwB,GAAG,MAAM;IAKxE;;;;;OAKG;IACH,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAmBpD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
/**
|
|
6
|
+
* AsciinemaRecorder: self-respawn ํจํด์ผ๋ก asciinema ๋
นํ๋ฅผ ๊ตฌํํ๋ค.
|
|
7
|
+
*
|
|
8
|
+
* --record ํ๋๊ทธ๊ฐ ์๊ณ GESTALT_RECORDING ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด,
|
|
9
|
+
* ํ์ฌ ํ๋ก์ธ์ค๋ฅผ asciinema rec์ผ๋ก ๊ฐ์ธ์ ์ฌ์คํํ๋ค.
|
|
10
|
+
* ์ฌ์คํ๋ ํ๋ก์ธ์ค๋ GESTALT_RECORDING=1๋ก ์คํ๋๋ฏ๋ก ์ผ๋ฐ ์ธํฐ๋ทฐ ๋ก์ง์ ์ํํ๋ค.
|
|
11
|
+
*/
|
|
12
|
+
export class AsciinemaRecorder {
|
|
13
|
+
/** ์ด๋ฏธ asciinema๋ก ๊ฐ์ธ์ง ์ํ์ธ์ง ํ์ธ */
|
|
14
|
+
static isInsideRecording() {
|
|
15
|
+
return process.env['GESTALT_RECORDING'] === '1';
|
|
16
|
+
}
|
|
17
|
+
/** ํ์ฌ ๋
นํ ์ค์ธ cast ํ์ผ ๊ฒฝ๋ก (GESTALT_CAST_PATH ํ๊ฒฝ๋ณ์) */
|
|
18
|
+
static getCurrentCastPath() {
|
|
19
|
+
return process.env['GESTALT_CAST_PATH'];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* ์์ cast ํ์ผ ๊ฒฝ๋ก๋ฅผ ์์ฑํ๋ค.
|
|
23
|
+
* ์ค์ ํ์ผ๋ช
์ ์ธํฐ๋ทฐ ์๋ฃ ํ topic ๊ธฐ๋ฐ์ผ๋ก rename๋๋ค.
|
|
24
|
+
*/
|
|
25
|
+
static createTempCastPath(recordingsDir = '.gestalt/recordings') {
|
|
26
|
+
mkdirSync(recordingsDir, { recursive: true });
|
|
27
|
+
return `${recordingsDir}/tmp-${randomUUID()}.cast`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* asciinema rec์ผ๋ก ํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์ฌ์คํํ๋ค.
|
|
31
|
+
* ์ด ํจ์๋ returnํ์ง ์๋๋ค (spawnSync๊ฐ ๋ธ๋กํน).
|
|
32
|
+
*
|
|
33
|
+
* @param castPath - ๋
นํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ .cast ํ์ผ ๊ฒฝ๋ก
|
|
34
|
+
*/
|
|
35
|
+
static respawnWithAsciinema(castPath) {
|
|
36
|
+
// ํ์ฌ process.argv์์ node ์คํํ์ผ์ ์ ์ธํ ์คํฌ๋ฆฝํธ + ์ธ์
|
|
37
|
+
const [, ...scriptAndArgs] = process.argv;
|
|
38
|
+
// --record, -r ํ๋๊ทธ ์ ๊ฑฐ (์ฌ์คํ ์ ๋ฌดํ๋ฃจํ ๋ฐฉ์ง)
|
|
39
|
+
const filteredArgs = (scriptAndArgs ?? []).filter((a) => a !== '--record' && a !== '-r');
|
|
40
|
+
mkdirSync(dirname(castPath), { recursive: true });
|
|
41
|
+
const result = spawnSync('asciinema', ['rec', '--overwrite', castPath, '--', 'node', ...filteredArgs], {
|
|
42
|
+
stdio: 'inherit',
|
|
43
|
+
env: {
|
|
44
|
+
...process.env,
|
|
45
|
+
GESTALT_RECORDING: '1',
|
|
46
|
+
GESTALT_CAST_PATH: castPath,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
process.exit(result.status ?? 0);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=asciinema-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asciinema-recorder.js","sourceRoot":"","sources":["../../../src/recording/asciinema-recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IAC5B,gCAAgC;IAChC,MAAM,CAAC,iBAAiB;QACtB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,GAAG,CAAC;IAClD,CAAC;IAED,mDAAmD;IACnD,MAAM,CAAC,kBAAkB;QACvB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,aAAa,GAAG,qBAAqB;QAC7D,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO,GAAG,aAAa,QAAQ,UAAU,EAAE,OAAO,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,oBAAoB,CAAC,QAAgB;QAC1C,6CAA6C;QAC7C,MAAM,CAAC,EAAE,GAAG,aAAa,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;QAC1C,sCAAsC;QACtC,MAAM,YAAY,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAEzF,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAElD,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE;YACrG,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,iBAAiB,EAAE,GAAG;gBACtB,iBAAiB,EAAE,QAAQ;aAC5B;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InterviewSession } from '../core/types.js';
|
|
2
|
+
export declare function slugify(topic: string): string;
|
|
3
|
+
export declare function getDateString(date?: Date): string;
|
|
4
|
+
export declare class CastGenerator {
|
|
5
|
+
generate(session: InterviewSession, outputPath: string): void;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=cast-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cast-generator.d.ts","sourceRoot":"","sources":["../../../src/recording/cast-generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAYzD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7C;AAED,wBAAgB,aAAa,CAAC,IAAI,OAAa,GAAG,MAAM,CAEvD;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAyD9D"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
// ANSI color codes
|
|
4
|
+
const RESET = '\x1b[0m';
|
|
5
|
+
const BOLD = '\x1b[1m';
|
|
6
|
+
const CYAN = '\x1b[36m';
|
|
7
|
+
const YELLOW = '\x1b[33m';
|
|
8
|
+
const GREEN = '\x1b[32m';
|
|
9
|
+
const DIM = '\x1b[2m';
|
|
10
|
+
export function slugify(topic) {
|
|
11
|
+
return topic
|
|
12
|
+
.toLowerCase()
|
|
13
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
14
|
+
.replace(/^-+|-+$/g, '')
|
|
15
|
+
.slice(0, 50) || 'interview';
|
|
16
|
+
}
|
|
17
|
+
export function getDateString(date = new Date()) {
|
|
18
|
+
return date.toISOString().slice(0, 10).replace(/-/g, '');
|
|
19
|
+
}
|
|
20
|
+
export class CastGenerator {
|
|
21
|
+
generate(session, outputPath) {
|
|
22
|
+
const startTs = Math.floor(Date.parse(session.createdAt) / 1000);
|
|
23
|
+
const header = {
|
|
24
|
+
version: 2,
|
|
25
|
+
width: 100,
|
|
26
|
+
height: 40,
|
|
27
|
+
timestamp: startTs,
|
|
28
|
+
title: `Gestalt Interview: ${session.topic}`,
|
|
29
|
+
};
|
|
30
|
+
const events = [];
|
|
31
|
+
let t = 0;
|
|
32
|
+
// Banner
|
|
33
|
+
events.push([t, 'o', `\r\n${BOLD}${CYAN}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${RESET}\r\n`]);
|
|
34
|
+
t += 0.05;
|
|
35
|
+
events.push([t, 'o', `${BOLD}${CYAN}โ ๐ฏ Gestalt Interview โ${RESET}\r\n`]);
|
|
36
|
+
t += 0.05;
|
|
37
|
+
events.push([t, 'o', `${BOLD}${CYAN}โ ${DIM}${session.topic.slice(0, 44).padEnd(44)}${RESET}${BOLD}${CYAN} โ${RESET}\r\n`]);
|
|
38
|
+
t += 0.05;
|
|
39
|
+
events.push([t, 'o', `${BOLD}${CYAN}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${RESET}\r\n\r\n`]);
|
|
40
|
+
t += 0.5;
|
|
41
|
+
// Q&A rounds
|
|
42
|
+
for (const round of session.rounds) {
|
|
43
|
+
if (!round.userResponse)
|
|
44
|
+
continue;
|
|
45
|
+
// Question
|
|
46
|
+
events.push([t, 'o', `${BOLD}${YELLOW}Q${round.roundNumber} [${round.gestaltFocus}]${RESET}\r\n`]);
|
|
47
|
+
t += 0.1;
|
|
48
|
+
events.push([t, 'o', `${round.question}\r\n\r\n`]);
|
|
49
|
+
t += 1.2;
|
|
50
|
+
// Answer
|
|
51
|
+
events.push([t, 'o', `${BOLD}${GREEN}โฏ${RESET} `]);
|
|
52
|
+
t += 0.1;
|
|
53
|
+
events.push([t, 'o', `${round.userResponse}\r\n\r\n`]);
|
|
54
|
+
t += 0.8;
|
|
55
|
+
}
|
|
56
|
+
// Footer
|
|
57
|
+
events.push([t, 'o', `${BOLD}${CYAN}โ
Interview completed โ ${session.rounds.length} rounds${RESET}\r\n`]);
|
|
58
|
+
t += 0.3;
|
|
59
|
+
if (session.ambiguityScore) {
|
|
60
|
+
events.push([t, 'o', `${DIM}Ambiguity score: ${session.ambiguityScore.overall.toFixed(2)}${RESET}\r\n`]);
|
|
61
|
+
}
|
|
62
|
+
events.push([t + 0.2, 'o', '\r\n']);
|
|
63
|
+
// Write file
|
|
64
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
65
|
+
const lines = [
|
|
66
|
+
JSON.stringify(header),
|
|
67
|
+
...events.map((e) => JSON.stringify(e)),
|
|
68
|
+
];
|
|
69
|
+
writeFileSync(outputPath, lines.join('\n') + '\n', 'utf8');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=cast-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cast-generator.js","sourceRoot":"","sources":["../../../src/recording/cast-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,mBAAmB;AACnB,MAAM,KAAK,GAAG,SAAS,CAAC;AACxB,MAAM,IAAI,GAAG,SAAS,CAAC;AACvB,MAAM,IAAI,GAAG,UAAU,CAAC;AACxB,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,GAAG,GAAG,SAAS,CAAC;AAItB,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE;IAC7C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,OAAO,aAAa;IACxB,QAAQ,CAAC,OAAyB,EAAE,UAAkB;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG;YACb,OAAO,EAAE,CAAC;YACV,KAAK,EAAE,GAAG;YACV,MAAM,EAAE,EAAE;YACV,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,sBAAsB,OAAO,CAAC,KAAK,EAAE;SAC7C,CAAC;QAEF,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,CAAC;QAEV,SAAS;QACT,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,mDAAmD,KAAK,MAAM,CAAC,CAAC,CAAC;QACxG,CAAC,IAAI,IAAI,CAAC;QACV,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,mDAAmD,KAAK,MAAM,CAAC,CAAC,CAAC;QACpG,CAAC,IAAI,IAAI,CAAC;QACV,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC;QAC9H,CAAC,IAAI,IAAI,CAAC;QACV,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,mDAAmD,KAAK,UAAU,CAAC,CAAC,CAAC;QACxG,CAAC,IAAI,GAAG,CAAC;QAET,aAAa;QACb,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,CAAC,YAAY;gBAAE,SAAS;YAElC,WAAW;YACX,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC;YACnG,CAAC,IAAI,GAAG,CAAC;YACT,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,QAAQ,UAAU,CAAC,CAAC,CAAC;YACnD,CAAC,IAAI,GAAG,CAAC;YAET,SAAS;YACT,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;YACnD,CAAC,IAAI,GAAG,CAAC;YACT,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC;YACvD,CAAC,IAAI,GAAG,CAAC;QACX,CAAC;QAED,SAAS;QACT,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,2BAA2B,OAAO,CAAC,MAAM,CAAC,MAAM,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC;QAC3G,CAAC,IAAI,GAAG,CAAC;QACT,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,oBAAoB,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC;QAC3G,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QAEpC,aAAa;QACb,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG;YACZ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YACtB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;SACxC,CAAC;QACF,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;CACF"}
|
|
@@ -11,6 +11,7 @@ export declare class FilenameGenerator {
|
|
|
11
11
|
* YYYYMMDD ๋ ์ง ์ ๋ฏธ์ฌ๋ฅผ ๋ถ์ฌ GIF ํ์ผ๋ช
์ ์์ฑํ๋ค.
|
|
12
12
|
*/
|
|
13
13
|
generate(topic: string, sessionId: string): Promise<string>;
|
|
14
|
+
generateCast(topic: string, sessionId: string, outputDir?: string): Promise<string>;
|
|
14
15
|
private requestSlugFromLLM;
|
|
15
16
|
private fallbackSlug;
|
|
16
17
|
private getDateString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filename-generator.d.ts","sourceRoot":"","sources":["../../../src/recording/filename-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,wBAA6B;IAGzD;;;OAGG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"filename-generator.d.ts","sourceRoot":"","sources":["../../../src/recording/filename-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,wBAA6B;IAGzD;;;OAGG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ3D,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAQ3E,kBAAkB;IA2BhC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,aAAa;CAOtB"}
|
|
@@ -16,6 +16,13 @@ export class FilenameGenerator {
|
|
|
16
16
|
const dir = this.options.outputDir ?? '.';
|
|
17
17
|
return dir === '.' ? filename : `${dir}/${filename}`;
|
|
18
18
|
}
|
|
19
|
+
async generateCast(topic, sessionId, outputDir) {
|
|
20
|
+
const slug = await this.requestSlugFromLLM(topic, sessionId);
|
|
21
|
+
const date = this.getDateString();
|
|
22
|
+
const filename = `${slug}-${date}.cast`;
|
|
23
|
+
const dir = outputDir ?? this.options.outputDir ?? '.gestalt/recordings';
|
|
24
|
+
return `${dir}/${filename}`;
|
|
25
|
+
}
|
|
19
26
|
async requestSlugFromLLM(topic, sessionId) {
|
|
20
27
|
try {
|
|
21
28
|
const response = await this.llm.chat({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filename-generator.js","sourceRoot":"","sources":["../../../src/recording/filename-generator.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,iBAAiB;IAET;IACA;IAFnB,YACmB,GAAe,EACf,UAAoC,EAAE;QADtC,QAAG,GAAH,GAAG,CAAY;QACf,YAAO,GAAP,OAAO,CAA+B;IACtD,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,SAAiB;QAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,IAAI,MAAM,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC;QAC1C,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,QAAQ,EAAE,CAAC;IACvD,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,KAAa,EAAE,SAAiB;QAC/D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBACnC,MAAM,EAAE,uJAAuJ;gBAC/J,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,+FAA+F,KAAK,iBAAiB,SAAS,0DAA0D;qBAClM;iBACF;gBACD,SAAS,EAAE,EAAE;gBACb,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO;iBAC1B,IAAI,EAAE;iBACN,WAAW,EAAE;iBACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;iBAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;iBACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAEzB,OAAO,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,KAAa;QAChC,OAAO,KAAK;aACT,WAAW,EAAE;aACb,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;aAC3B,IAAI,EAAE;aACN,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;aACpB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC;IACjC,CAAC;IAEO,aAAa;QACnB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnD,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;IACjC,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"filename-generator.js","sourceRoot":"","sources":["../../../src/recording/filename-generator.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,iBAAiB;IAET;IACA;IAFnB,YACmB,GAAe,EACf,UAAoC,EAAE;QADtC,QAAG,GAAH,GAAG,CAAY;QACf,YAAO,GAAP,OAAO,CAA+B;IACtD,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,SAAiB;QAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,IAAI,MAAM,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC;QAC1C,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,QAAQ,EAAE,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,SAAiB,EAAE,SAAkB;QACrE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,IAAI,OAAO,CAAC;QACxC,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,qBAAqB,CAAC;QACzE,OAAO,GAAG,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,KAAa,EAAE,SAAiB;QAC/D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBACnC,MAAM,EAAE,uJAAuJ;gBAC/J,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,+FAA+F,KAAK,iBAAiB,SAAS,0DAA0D;qBAClM;iBACF;gBACD,SAAS,EAAE,EAAE;gBACb,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO;iBAC1B,IAAI,EAAE;iBACN,WAAW,EAAE;iBACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;iBAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;iBACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAEzB,OAAO,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,KAAa;QAChC,OAAO,KAAK;aACT,WAAW,EAAE;aACb,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;aAC3B,IAAI,EAAE;aACN,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;aACpB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC;IACjC,CAAC;IAEO,aAAa;QACnB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnD,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { LLMAdapter } from '../llm/types.js';
|
|
2
|
+
export interface RecordingOptions {
|
|
3
|
+
/** --record ๋๋ -r ํ๋๊ทธ */
|
|
4
|
+
record?: boolean;
|
|
5
|
+
/** --mp4 ํ๋๊ทธ โ GIF์ ํจ๊ป mp4๋ ์์ฑ */
|
|
6
|
+
mp4?: boolean;
|
|
7
|
+
/** ์ถ๋ ฅ ๋๋ ํ ๋ฆฌ (๊ธฐ๋ณธ๊ฐ: ํ์ฌ ๋๋ ํ ๋ฆฌ) */
|
|
8
|
+
outputDir?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* RecordingOrchestrator: asciinema ๊ธฐ๋ฐ ๋
นํ์ ์ ์ฒด ์๋ช
์ฃผ๊ธฐ๋ฅผ ์กฐ์จํ๋ค.
|
|
12
|
+
*
|
|
13
|
+
* ์ฌ์ฉ ํจํด (interview CLI):
|
|
14
|
+
*
|
|
15
|
+
* 1. startIfNeeded() โ interview ์์ ์ ํธ์ถ. --record ํ๋๊ทธ๊ฐ ์๊ณ
|
|
16
|
+
* ์์ง asciinema๋ก ๊ฐ์ธ์ง์ง ์์์ผ๋ฉด self-respawn์ผ๋ก ์ฌ์คํ.
|
|
17
|
+
*
|
|
18
|
+
* 2. stopAndConvert() โ interview ์๋ฃ ํ ํธ์ถ. ๋ฐฑ๊ทธ๋ผ์ด๋ ๋น๋๊ธฐ๋ก
|
|
19
|
+
* .cast โ GIF (โ mp4) ๋ณํ์ ํธ๋ฆฌ๊ฑฐํ๋ค.
|
|
20
|
+
*/
|
|
21
|
+
export declare class RecordingOrchestrator {
|
|
22
|
+
private readonly llm;
|
|
23
|
+
private readonly asciinemaInstaller;
|
|
24
|
+
private readonly aggInstaller;
|
|
25
|
+
private readonly converter;
|
|
26
|
+
constructor(llm: LLMAdapter);
|
|
27
|
+
/**
|
|
28
|
+
* ํ์ํ๋ฉด asciinema ๋
นํ๋ฅผ ์์ํ๋ค.
|
|
29
|
+
* - GESTALT_RECORDING=1์ด๋ฉด ์ด๋ฏธ asciinema ์์ ์์ผ๋ฏ๋ก ์๋ฌด๊ฒ๋ ํ์ง ์์.
|
|
30
|
+
* - --record ํ๋๊ทธ๊ฐ ์์ผ๋ฉด asciinema๋ฅผ ์ค์นํ๊ณ self-respawn.
|
|
31
|
+
* - ์ฌ์คํ ํ์๋ process.exit()์ด ํธ์ถ๋๋ฏ๋ก ์ด ํจ์๋ returnํ์ง ์์ ์ ์์.
|
|
32
|
+
*/
|
|
33
|
+
startIfNeeded(options: RecordingOptions): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* ํ์ฌ ํ๋ก์ธ์ค๊ฐ asciinema๋ก ๋
นํ ์ค์ธ์ง ํ์ธ.
|
|
36
|
+
* GESTALT_CAST_PATH ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด true.
|
|
37
|
+
*/
|
|
38
|
+
isRecording(): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* ๋
นํ๋ฅผ ์ข
๋ฃํ๊ณ GIF (+ mp4) ๋ณํ์ ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ํธ๋ฆฌ๊ฑฐํ๋ค.
|
|
41
|
+
* asciinema๋ ๋ถ๋ชจ ํ๋ก์ธ์ค(respawned)์์ ์๋ ์ข
๋ฃ๋๋ฏ๋ก
|
|
42
|
+
* ์ฌ๊ธฐ์๋ cast ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ฝ์ด ๋ณํ๋ง ์์ํ๋ค.
|
|
43
|
+
*
|
|
44
|
+
* @param topic - ์ธํฐ๋ทฐ ์ฃผ์ (ํ์ผ๋ช
์์ฑ์ฉ)
|
|
45
|
+
* @param sessionId - ์ธ์
ID (ํ์ผ๋ช
์์ฑ์ฉ)
|
|
46
|
+
* @param options - ๋
นํ ์ต์
|
|
47
|
+
*/
|
|
48
|
+
stopAndConvert(topic: string, sessionId: string, options?: RecordingOptions): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=recording-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/recording/recording-orchestrator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kCAAkC;IAClC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,qBAAqB;IAKpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJhC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAC/D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;gBAEnB,GAAG,EAAE,UAAU;IAE5C;;;;;OAKG;IACG,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7D;;;OAGG;IACH,WAAW,IAAI,OAAO;IAItB;;;;;;;;OAQG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAyCtG"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { AsciinemaInstaller } from './asciinema-installer.js';
|
|
2
|
+
import { AsciinemaRecorder } from './asciinema-recorder.js';
|
|
3
|
+
import { AggInstaller } from './agg-installer.js';
|
|
4
|
+
import { AggConverter } from './agg-converter.js';
|
|
5
|
+
import { FilenameGenerator } from './filename-generator.js';
|
|
6
|
+
/**
|
|
7
|
+
* RecordingOrchestrator: asciinema ๊ธฐ๋ฐ ๋
นํ์ ์ ์ฒด ์๋ช
์ฃผ๊ธฐ๋ฅผ ์กฐ์จํ๋ค.
|
|
8
|
+
*
|
|
9
|
+
* ์ฌ์ฉ ํจํด (interview CLI):
|
|
10
|
+
*
|
|
11
|
+
* 1. startIfNeeded() โ interview ์์ ์ ํธ์ถ. --record ํ๋๊ทธ๊ฐ ์๊ณ
|
|
12
|
+
* ์์ง asciinema๋ก ๊ฐ์ธ์ง์ง ์์์ผ๋ฉด self-respawn์ผ๋ก ์ฌ์คํ.
|
|
13
|
+
*
|
|
14
|
+
* 2. stopAndConvert() โ interview ์๋ฃ ํ ํธ์ถ. ๋ฐฑ๊ทธ๋ผ์ด๋ ๋น๋๊ธฐ๋ก
|
|
15
|
+
* .cast โ GIF (โ mp4) ๋ณํ์ ํธ๋ฆฌ๊ฑฐํ๋ค.
|
|
16
|
+
*/
|
|
17
|
+
export class RecordingOrchestrator {
|
|
18
|
+
llm;
|
|
19
|
+
asciinemaInstaller = new AsciinemaInstaller();
|
|
20
|
+
aggInstaller = new AggInstaller();
|
|
21
|
+
converter = new AggConverter();
|
|
22
|
+
constructor(llm) {
|
|
23
|
+
this.llm = llm;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* ํ์ํ๋ฉด asciinema ๋
นํ๋ฅผ ์์ํ๋ค.
|
|
27
|
+
* - GESTALT_RECORDING=1์ด๋ฉด ์ด๋ฏธ asciinema ์์ ์์ผ๋ฏ๋ก ์๋ฌด๊ฒ๋ ํ์ง ์์.
|
|
28
|
+
* - --record ํ๋๊ทธ๊ฐ ์์ผ๋ฉด asciinema๋ฅผ ์ค์นํ๊ณ self-respawn.
|
|
29
|
+
* - ์ฌ์คํ ํ์๋ process.exit()์ด ํธ์ถ๋๋ฏ๋ก ์ด ํจ์๋ returnํ์ง ์์ ์ ์์.
|
|
30
|
+
*/
|
|
31
|
+
async startIfNeeded(options) {
|
|
32
|
+
if (!options.record)
|
|
33
|
+
return;
|
|
34
|
+
if (AsciinemaRecorder.isInsideRecording())
|
|
35
|
+
return;
|
|
36
|
+
await this.asciinemaInstaller.ensureInstalled();
|
|
37
|
+
const castPath = AsciinemaRecorder.createTempCastPath();
|
|
38
|
+
console.log('๐น Starting asciinema recording...\n');
|
|
39
|
+
AsciinemaRecorder.respawnWithAsciinema(castPath);
|
|
40
|
+
// respawnWithAsciinema calls process.exit() โ ์ด ์ค์ ์คํ๋์ง ์์
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* ํ์ฌ ํ๋ก์ธ์ค๊ฐ asciinema๋ก ๋
นํ ์ค์ธ์ง ํ์ธ.
|
|
44
|
+
* GESTALT_CAST_PATH ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด true.
|
|
45
|
+
*/
|
|
46
|
+
isRecording() {
|
|
47
|
+
return AsciinemaRecorder.isInsideRecording() && !!AsciinemaRecorder.getCurrentCastPath();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* ๋
นํ๋ฅผ ์ข
๋ฃํ๊ณ GIF (+ mp4) ๋ณํ์ ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ํธ๋ฆฌ๊ฑฐํ๋ค.
|
|
51
|
+
* asciinema๋ ๋ถ๋ชจ ํ๋ก์ธ์ค(respawned)์์ ์๋ ์ข
๋ฃ๋๋ฏ๋ก
|
|
52
|
+
* ์ฌ๊ธฐ์๋ cast ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ฝ์ด ๋ณํ๋ง ์์ํ๋ค.
|
|
53
|
+
*
|
|
54
|
+
* @param topic - ์ธํฐ๋ทฐ ์ฃผ์ (ํ์ผ๋ช
์์ฑ์ฉ)
|
|
55
|
+
* @param sessionId - ์ธ์
ID (ํ์ผ๋ช
์์ฑ์ฉ)
|
|
56
|
+
* @param options - ๋
นํ ์ต์
|
|
57
|
+
*/
|
|
58
|
+
async stopAndConvert(topic, sessionId, options = {}) {
|
|
59
|
+
const castPath = AsciinemaRecorder.getCurrentCastPath();
|
|
60
|
+
if (!castPath)
|
|
61
|
+
return;
|
|
62
|
+
try {
|
|
63
|
+
await this.aggInstaller.ensureInstalled();
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
67
|
+
console.error(`โ ๏ธ agg installation failed: ${msg}`);
|
|
68
|
+
console.error(' GIF conversion skipped. The .cast file is preserved at:', castPath);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const filenameGen = new FilenameGenerator(this.llm, { outputDir: options.outputDir });
|
|
72
|
+
const gifPath = await filenameGen.generate(topic, sessionId);
|
|
73
|
+
console.log('\n๐ฌ Converting recording to GIF in background...');
|
|
74
|
+
// ๋ฐฑ๊ทธ๋ผ์ด๋ ๋น๋๊ธฐ โ awaitํ์ง ์์
|
|
75
|
+
void this.converter
|
|
76
|
+
.convertAsync(castPath, gifPath, {
|
|
77
|
+
deleteCastAfter: true,
|
|
78
|
+
onComplete: (outputPath) => {
|
|
79
|
+
console.log(`โ
GIF saved: ${outputPath}\n`);
|
|
80
|
+
if (options.mp4) {
|
|
81
|
+
const mp4Path = outputPath.replace(/\.gif$/, '.mp4');
|
|
82
|
+
void this.converter.convertGifToMp4Async(outputPath, mp4Path, {
|
|
83
|
+
onComplete: (p) => console.log(`โ
MP4 saved: ${p}\n`),
|
|
84
|
+
onError: (e) => console.error(`โ ๏ธ MP4 conversion failed: ${e.message}`),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
onError: (err) => {
|
|
89
|
+
console.error(`โ ๏ธ GIF conversion failed: ${err.message}`);
|
|
90
|
+
console.error(' The .cast file may be preserved at:', castPath);
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
.catch(() => {
|
|
94
|
+
// onError์์ ์ฒ๋ฆฌ๋จ
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=recording-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording-orchestrator.js","sourceRoot":"","sources":["../../../src/recording/recording-orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postinstall.d.ts","sourceRoot":"","sources":["../../../src/scripts/postinstall.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postinstall script: auto-setup agg for GIF recording support.
|
|
3
|
+
* Runs after: npm install @tienne/gestalt
|
|
4
|
+
*
|
|
5
|
+
* - Silently skips in CI or if GESTALT_SKIP_DEPS=1
|
|
6
|
+
* - Always exits 0 (never fails the install)
|
|
7
|
+
*/
|
|
8
|
+
import { AggInstaller } from '../recording/agg-installer.js';
|
|
9
|
+
async function main() {
|
|
10
|
+
if (process.env['CI'] || process.env['GESTALT_SKIP_DEPS'] === '1') {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const installer = new AggInstaller();
|
|
14
|
+
if (installer.isInstalled())
|
|
15
|
+
return;
|
|
16
|
+
process.stdout.write('\n[gestalt] agg not found โ setting up GIF recording support...\n');
|
|
17
|
+
try {
|
|
18
|
+
await installer.ensureInstalled();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
22
|
+
process.stdout.write(`[gestalt] Skipping agg setup: ${msg}\n`);
|
|
23
|
+
process.stdout.write('[gestalt] Install manually later: https://github.com/asciinema/agg\n\n');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
main().then(() => process.exit(0)).catch(() => process.exit(0));
|
|
27
|
+
//# sourceMappingURL=postinstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../../../src/scripts/postinstall.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,GAAG,EAAE,CAAC;QAClE,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,YAAY,EAAE,CAAC;IACrC,IAAI,SAAS,CAAC,WAAW,EAAE;QAAE,OAAO;IAEpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;IAE1F,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,eAAe,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,IAAI,CAAC,CAAC;QAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tienne/gestalt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"dev": "tsx bin/gestalt.ts",
|
|
25
25
|
"build": "tsc",
|
|
26
26
|
"postbuild": "cp -r agents dist/ && cp -r role-agents dist/ && cp -r review-agents dist/ && cp -r skills dist/ && cp -r schemas dist/ && cp package.json dist/ && chmod +x dist/bin/gestalt.js",
|
|
27
|
+
"postinstall": "node ./dist/src/scripts/postinstall.js || true",
|
|
27
28
|
"prepublishOnly": "pnpm build",
|
|
28
29
|
"test": "vitest run",
|
|
29
30
|
"test:watch": "vitest",
|