tenbrains 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +112 -0
- package/README.md +218 -0
- package/dist/ai/analyzer.d.ts +28 -0
- package/dist/ai/analyzer.d.ts.map +1 -0
- package/dist/ai/analyzer.js +35 -0
- package/dist/ai/analyzer.js.map +1 -0
- package/dist/ai/client.d.ts +12 -0
- package/dist/ai/client.d.ts.map +1 -0
- package/dist/ai/client.js +152 -0
- package/dist/ai/client.js.map +1 -0
- package/dist/ai/json.d.ts +7 -0
- package/dist/ai/json.d.ts.map +1 -0
- package/dist/ai/json.js +57 -0
- package/dist/ai/json.js.map +1 -0
- package/dist/ai/mock.d.ts +6 -0
- package/dist/ai/mock.d.ts.map +1 -0
- package/dist/ai/mock.js +66 -0
- package/dist/ai/mock.js.map +1 -0
- package/dist/ai/prompts.d.ts +19 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +40 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/ai/providers.d.ts +22 -0
- package/dist/ai/providers.d.ts.map +1 -0
- package/dist/ai/providers.js +56 -0
- package/dist/ai/providers.js.map +1 -0
- package/dist/ai/resolve.d.ts +24 -0
- package/dist/ai/resolve.d.ts.map +1 -0
- package/dist/ai/resolve.js +33 -0
- package/dist/ai/resolve.js.map +1 -0
- package/dist/bin/preflight.d.ts +2 -0
- package/dist/bin/preflight.d.ts.map +1 -0
- package/dist/bin/preflight.js +11 -0
- package/dist/bin/preflight.js.map +1 -0
- package/dist/bin/tenbrains.d.ts +3 -0
- package/dist/bin/tenbrains.d.ts.map +1 -0
- package/dist/bin/tenbrains.js +9 -0
- package/dist/bin/tenbrains.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +554 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/analyze.d.ts +7 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +204 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/bookmark.d.ts +9 -0
- package/dist/commands/bookmark.d.ts.map +1 -0
- package/dist/commands/bookmark.js +120 -0
- package/dist/commands/bookmark.js.map +1 -0
- package/dist/commands/config.d.ts +15 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +142 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/db.d.ts +9 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +64 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/digest.d.ts +19 -0
- package/dist/commands/digest.d.ts.map +1 -0
- package/dist/commands/digest.js +71 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/import.d.ts +11 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +78 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/learn.d.ts +9 -0
- package/dist/commands/learn.d.ts.map +1 -0
- package/dist/commands/learn.js +149 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/manifest.d.ts +13 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/manifest.js +62 -0
- package/dist/commands/manifest.js.map +1 -0
- package/dist/commands/record.d.ts +10 -0
- package/dist/commands/record.d.ts.map +1 -0
- package/dist/commands/record.js +37 -0
- package/dist/commands/record.js.map +1 -0
- package/dist/commands/search.d.ts +5 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +33 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/shared.d.ts +9 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +13 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/suggest.d.ts +9 -0
- package/dist/commands/suggest.d.ts.map +1 -0
- package/dist/commands/suggest.js +102 -0
- package/dist/commands/suggest.js.map +1 -0
- package/dist/commands/takeaway.d.ts +9 -0
- package/dist/commands/takeaway.d.ts.map +1 -0
- package/dist/commands/takeaway.js +167 -0
- package/dist/commands/takeaway.js.map +1 -0
- package/dist/core/config.d.ts +52 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +180 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +28 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +40 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/errors.d.ts +33 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +82 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/input.d.ts +9 -0
- package/dist/core/input.d.ts.map +1 -0
- package/dist/core/input.js +47 -0
- package/dist/core/input.js.map +1 -0
- package/dist/core/opts.d.ts +8 -0
- package/dist/core/opts.d.ts.map +1 -0
- package/dist/core/opts.js +38 -0
- package/dist/core/opts.js.map +1 -0
- package/dist/core/output.d.ts +58 -0
- package/dist/core/output.d.ts.map +1 -0
- package/dist/core/output.js +76 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/paths.d.ts +20 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +31 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/text.d.ts +10 -0
- package/dist/core/text.d.ts.map +1 -0
- package/dist/core/text.js +132 -0
- package/dist/core/text.js.map +1 -0
- package/dist/core/validate.d.ts +5 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +17 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/db/database.d.ts +27 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +90 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/fts.d.ts +12 -0
- package/dist/db/fts.d.ts.map +1 -0
- package/dist/db/fts.js +42 -0
- package/dist/db/fts.js.map +1 -0
- package/dist/db/migrations.d.ts +20 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +243 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/repositories.d.ts +130 -0
- package/dist/db/repositories.d.ts.map +1 -0
- package/dist/db/repositories.js +418 -0
- package/dist/db/repositories.js.map +1 -0
- package/dist/domain/learn.d.ts +25 -0
- package/dist/domain/learn.d.ts.map +1 -0
- package/dist/domain/learn.js +85 -0
- package/dist/domain/learn.js.map +1 -0
- package/dist/domain/schemas.d.ts +169 -0
- package/dist/domain/schemas.d.ts.map +1 -0
- package/dist/domain/schemas.js +54 -0
- package/dist/domain/schemas.js.map +1 -0
- package/dist/domain/search.d.ts +32 -0
- package/dist/domain/search.d.ts.map +1 -0
- package/dist/domain/search.js +77 -0
- package/dist/domain/search.js.map +1 -0
- package/dist/domain/suggest.d.ts +17 -0
- package/dist/domain/suggest.d.ts.map +1 -0
- package/dist/domain/suggest.js +114 -0
- package/dist/domain/suggest.js.map +1 -0
- package/dist/domain/tags.d.ts +9 -0
- package/dist/domain/tags.d.ts.map +1 -0
- package/dist/domain/tags.js +40 -0
- package/dist/domain/tags.js.map +1 -0
- package/dist/domain/types.d.ts +84 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +2 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/x/archive.d.ts +32 -0
- package/dist/x/archive.d.ts.map +1 -0
- package/dist/x/archive.js +108 -0
- package/dist/x/archive.js.map +1 -0
- package/dist/x/client.d.ts +61 -0
- package/dist/x/client.d.ts.map +1 -0
- package/dist/x/client.js +321 -0
- package/dist/x/client.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine-readable error codes. Every failure the CLI emits carries one of
|
|
3
|
+
* these so an agent can branch on `error.code` instead of parsing prose.
|
|
4
|
+
*/
|
|
5
|
+
export declare const ERROR_CODES: readonly ["USAGE", "VALIDATION", "NOT_FOUND", "CONFLICT", "MISSING_CREDENTIALS", "CONFIG_ERROR", "PROVIDER_UNAUTHORIZED", "PROVIDER_RATE_LIMITED", "PROVIDER_UPSTREAM", "PROVIDER_NETWORK", "PROVIDER_BAD_OUTPUT", "INTERNAL"];
|
|
6
|
+
export type ErrorCode = (typeof ERROR_CODES)[number];
|
|
7
|
+
export interface CliErrorOptions {
|
|
8
|
+
/** Structured, JSON-serializable context attached to the error envelope. */
|
|
9
|
+
details?: Record<string, unknown>;
|
|
10
|
+
/** Whether a caller could reasonably retry the same invocation. */
|
|
11
|
+
retryable?: boolean;
|
|
12
|
+
/** Underlying error, preserved for the stack but not serialized. */
|
|
13
|
+
cause?: unknown;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The one error type the CLI throws on purpose. Anything else bubbling up is
|
|
17
|
+
* treated as an INTERNAL error by the dispatcher.
|
|
18
|
+
*/
|
|
19
|
+
export declare class CliError extends Error {
|
|
20
|
+
readonly code: ErrorCode;
|
|
21
|
+
readonly details: Record<string, unknown> | undefined;
|
|
22
|
+
readonly retryable: boolean;
|
|
23
|
+
constructor(code: ErrorCode, message: string, options?: CliErrorOptions);
|
|
24
|
+
get exitCode(): number;
|
|
25
|
+
toJSON(): Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export declare function exitCodeForError(error: unknown): number;
|
|
28
|
+
export declare function exitCodeForCode(code: ErrorCode): number;
|
|
29
|
+
/** The full code -> exit-code map, for self-description in `manifest`. */
|
|
30
|
+
export declare function exitCodeMap(): Record<ErrorCode, number>;
|
|
31
|
+
/** Coerce any thrown value into a CliError for uniform reporting. */
|
|
32
|
+
export declare function toCliError(error: unknown): CliError;
|
|
33
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW,gOAad,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAqBrD,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;gBAEhB,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB;IAQ3E,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQlC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEvD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEvD;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,IAAI,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAEvD;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAMnD"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine-readable error codes. Every failure the CLI emits carries one of
|
|
3
|
+
* these so an agent can branch on `error.code` instead of parsing prose.
|
|
4
|
+
*/
|
|
5
|
+
export const ERROR_CODES = [
|
|
6
|
+
"USAGE",
|
|
7
|
+
"VALIDATION",
|
|
8
|
+
"NOT_FOUND",
|
|
9
|
+
"CONFLICT",
|
|
10
|
+
"MISSING_CREDENTIALS",
|
|
11
|
+
"CONFIG_ERROR",
|
|
12
|
+
"PROVIDER_UNAUTHORIZED",
|
|
13
|
+
"PROVIDER_RATE_LIMITED",
|
|
14
|
+
"PROVIDER_UPSTREAM",
|
|
15
|
+
"PROVIDER_NETWORK",
|
|
16
|
+
"PROVIDER_BAD_OUTPUT",
|
|
17
|
+
"INTERNAL",
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Process exit codes are stable per failure class so shell/agent callers can
|
|
21
|
+
* react without parsing stdout. 0 is success (never produced by an error).
|
|
22
|
+
*/
|
|
23
|
+
const EXIT_CODES = {
|
|
24
|
+
USAGE: 2,
|
|
25
|
+
VALIDATION: 6,
|
|
26
|
+
NOT_FOUND: 3,
|
|
27
|
+
CONFLICT: 7,
|
|
28
|
+
MISSING_CREDENTIALS: 4,
|
|
29
|
+
CONFIG_ERROR: 4,
|
|
30
|
+
PROVIDER_UNAUTHORIZED: 5,
|
|
31
|
+
PROVIDER_RATE_LIMITED: 5,
|
|
32
|
+
PROVIDER_UPSTREAM: 5,
|
|
33
|
+
PROVIDER_NETWORK: 5,
|
|
34
|
+
PROVIDER_BAD_OUTPUT: 5,
|
|
35
|
+
INTERNAL: 1,
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The one error type the CLI throws on purpose. Anything else bubbling up is
|
|
39
|
+
* treated as an INTERNAL error by the dispatcher.
|
|
40
|
+
*/
|
|
41
|
+
export class CliError extends Error {
|
|
42
|
+
code;
|
|
43
|
+
details;
|
|
44
|
+
retryable;
|
|
45
|
+
constructor(code, message, options = {}) {
|
|
46
|
+
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
47
|
+
this.name = "CliError";
|
|
48
|
+
this.code = code;
|
|
49
|
+
this.details = options.details;
|
|
50
|
+
this.retryable = options.retryable ?? false;
|
|
51
|
+
}
|
|
52
|
+
get exitCode() {
|
|
53
|
+
return EXIT_CODES[this.code];
|
|
54
|
+
}
|
|
55
|
+
toJSON() {
|
|
56
|
+
return {
|
|
57
|
+
code: this.code,
|
|
58
|
+
message: this.message,
|
|
59
|
+
retryable: this.retryable,
|
|
60
|
+
...(this.details ? { details: this.details } : {}),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function exitCodeForError(error) {
|
|
65
|
+
return error instanceof CliError ? error.exitCode : EXIT_CODES.INTERNAL;
|
|
66
|
+
}
|
|
67
|
+
export function exitCodeForCode(code) {
|
|
68
|
+
return EXIT_CODES[code];
|
|
69
|
+
}
|
|
70
|
+
/** The full code -> exit-code map, for self-description in `manifest`. */
|
|
71
|
+
export function exitCodeMap() {
|
|
72
|
+
return { ...EXIT_CODES };
|
|
73
|
+
}
|
|
74
|
+
/** Coerce any thrown value into a CliError for uniform reporting. */
|
|
75
|
+
export function toCliError(error) {
|
|
76
|
+
if (error instanceof CliError) {
|
|
77
|
+
return error;
|
|
78
|
+
}
|
|
79
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80
|
+
return new CliError("INTERNAL", message, { cause: error });
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,OAAO;IACP,YAAY;IACZ,WAAW;IACX,UAAU;IACV,qBAAqB;IACrB,cAAc;IACd,uBAAuB;IACvB,uBAAuB;IACvB,mBAAmB;IACnB,kBAAkB;IAClB,qBAAqB;IACrB,UAAU;CACF,CAAC;AAIX;;;GAGG;AACH,MAAM,UAAU,GAA8B;IAC5C,KAAK,EAAE,CAAC;IACR,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,CAAC;IACX,mBAAmB,EAAE,CAAC;IACtB,YAAY,EAAE,CAAC;IACf,qBAAqB,EAAE,CAAC;IACxB,qBAAqB,EAAE,CAAC;IACxB,iBAAiB,EAAE,CAAC;IACpB,gBAAgB,EAAE,CAAC;IACnB,mBAAmB,EAAE,CAAC;IACtB,QAAQ,EAAE,CAAC;CACZ,CAAC;AAWF;;;GAGG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAY;IAChB,OAAO,CAAsC;IAC7C,SAAS,CAAU;IAE5B,YAAY,IAAe,EAAE,OAAe,EAAE,UAA2B,EAAE;QACzE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAC9C,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,KAAK,YAAY,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAe;IAC7C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,WAAW;IACzB,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;AAC3B,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,IAAI,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a string argument that may be inline text, `@path` (read a file), or
|
|
3
|
+
* `-` (read stdin). This lets agents pipe large content in without shell
|
|
4
|
+
* quoting headaches: `tenbrains analyze --text - < post.txt`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveTextInput(value: string): string;
|
|
7
|
+
/** Resolve and JSON-parse an input that may be inline, `@file`, or `-` (stdin). */
|
|
8
|
+
export declare function resolveJsonInput(value: string): unknown;
|
|
9
|
+
//# sourceMappingURL=input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/core/input.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAatD;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAavD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { CliError } from "./errors.js";
|
|
3
|
+
function readStdinSync() {
|
|
4
|
+
try {
|
|
5
|
+
return readFileSync(0, "utf8");
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
throw new CliError("USAGE", "Failed to read from stdin.", { cause: error });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a string argument that may be inline text, `@path` (read a file), or
|
|
13
|
+
* `-` (read stdin). This lets agents pipe large content in without shell
|
|
14
|
+
* quoting headaches: `tenbrains analyze --text - < post.txt`.
|
|
15
|
+
*/
|
|
16
|
+
export function resolveTextInput(value) {
|
|
17
|
+
if (value === "-") {
|
|
18
|
+
return readStdinSync();
|
|
19
|
+
}
|
|
20
|
+
if (value.startsWith("@")) {
|
|
21
|
+
const path = value.slice(1);
|
|
22
|
+
try {
|
|
23
|
+
return readFileSync(path, "utf8");
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw new CliError("USAGE", `Failed to read file: ${path}`, { cause: error });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
/** Resolve and JSON-parse an input that may be inline, `@file`, or `-` (stdin). */
|
|
32
|
+
export function resolveJsonInput(value) {
|
|
33
|
+
const raw = resolveTextInput(value).trim();
|
|
34
|
+
if (!raw) {
|
|
35
|
+
throw new CliError("USAGE", "Expected JSON input but received empty content.");
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(raw);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new CliError("USAGE", "Input is not valid JSON.", {
|
|
42
|
+
details: { sample: raw.slice(0, 120) },
|
|
43
|
+
cause: error,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/core/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,SAAS,aAAa;IACpB,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,4BAA4B,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QAClB,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,wBAAwB,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,iDAAiD,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,0BAA0B,EAAE;YACtD,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YACtC,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type Opts = Record<string, unknown>;
|
|
2
|
+
export declare function optString(opts: Opts, key: string): string | undefined;
|
|
3
|
+
export declare function requireString(opts: Opts, key: string, flag: string): string;
|
|
4
|
+
export declare function optBool(opts: Opts, key: string): boolean;
|
|
5
|
+
export declare function optNumber(opts: Opts, key: string, fallback: number): number;
|
|
6
|
+
/** Parse a comma-separated list option (e.g. --tags a,b,c) into trimmed values. */
|
|
7
|
+
export declare function optList(opts: Opts, key: string): string[];
|
|
8
|
+
//# sourceMappingURL=opts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opts.d.ts","sourceRoot":"","sources":["../../src/core/opts.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGrE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3E;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU3E;AAED,mFAAmF;AACnF,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CASzD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CliError } from "./errors.js";
|
|
2
|
+
export function optString(opts, key) {
|
|
3
|
+
const value = opts[key];
|
|
4
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
5
|
+
}
|
|
6
|
+
export function requireString(opts, key, flag) {
|
|
7
|
+
const value = optString(opts, key);
|
|
8
|
+
if (value === undefined) {
|
|
9
|
+
throw new CliError("USAGE", `Missing required option ${flag}.`, { details: { flag } });
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
export function optBool(opts, key) {
|
|
14
|
+
return opts[key] === true;
|
|
15
|
+
}
|
|
16
|
+
export function optNumber(opts, key, fallback) {
|
|
17
|
+
const value = opts[key];
|
|
18
|
+
if (value === undefined) {
|
|
19
|
+
return fallback;
|
|
20
|
+
}
|
|
21
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(String(value), 10);
|
|
22
|
+
if (!Number.isFinite(parsed)) {
|
|
23
|
+
throw new CliError("USAGE", `Option --${key} must be a number.`, { details: { value } });
|
|
24
|
+
}
|
|
25
|
+
return parsed;
|
|
26
|
+
}
|
|
27
|
+
/** Parse a comma-separated list option (e.g. --tags a,b,c) into trimmed values. */
|
|
28
|
+
export function optList(opts, key) {
|
|
29
|
+
const value = optString(opts, key);
|
|
30
|
+
if (!value) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
return value
|
|
34
|
+
.split(",")
|
|
35
|
+
.map((item) => item.trim())
|
|
36
|
+
.filter((item) => item.length > 0);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=opts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opts.js","sourceRoot":"","sources":["../../src/core/opts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,MAAM,UAAU,SAAS,CAAC,IAAU,EAAE,GAAW;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,GAAW,EAAE,IAAY;IACjE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,2BAA2B,IAAI,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,GAAW;IAC7C,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAU,EAAE,GAAW,EAAE,QAAgB;IACjE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,oBAAoB,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,GAAW;IAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { CliError } from "./errors.js";
|
|
2
|
+
export type OutputMode = "json" | "pretty";
|
|
3
|
+
/**
|
|
4
|
+
* The value a command handler returns. `data` is the canonical machine payload;
|
|
5
|
+
* `meta` carries non-payload facts (ids, counts, persistence flags); `human` is
|
|
6
|
+
* an optional renderer used only in --pretty mode.
|
|
7
|
+
*/
|
|
8
|
+
export interface CommandResult<T = unknown> {
|
|
9
|
+
data: T;
|
|
10
|
+
meta?: Record<string, unknown>;
|
|
11
|
+
human?: (data: T) => string;
|
|
12
|
+
}
|
|
13
|
+
/** Stable success envelope. stdout contains exactly one of these per run. */
|
|
14
|
+
export interface SuccessEnvelope<T = unknown> {
|
|
15
|
+
ok: true;
|
|
16
|
+
command: string;
|
|
17
|
+
data: T;
|
|
18
|
+
meta: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** Stable error envelope. Mirrors SuccessEnvelope so `ok` is the only branch. */
|
|
21
|
+
export interface ErrorEnvelope {
|
|
22
|
+
ok: false;
|
|
23
|
+
command: string;
|
|
24
|
+
error: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
export declare function buildSuccessEnvelope<T>(command: string, result: CommandResult<T>): SuccessEnvelope<T>;
|
|
27
|
+
export declare function buildErrorEnvelope(command: string, error: unknown): ErrorEnvelope;
|
|
28
|
+
export interface Streams {
|
|
29
|
+
stdout: (text: string) => void;
|
|
30
|
+
stderr: (text: string) => void;
|
|
31
|
+
}
|
|
32
|
+
export declare const defaultStreams: Streams;
|
|
33
|
+
/**
|
|
34
|
+
* Render a successful command result.
|
|
35
|
+
* - json mode (default): the envelope is written to stdout.
|
|
36
|
+
* - pretty mode: the human renderer (or pretty JSON) is written to stdout.
|
|
37
|
+
*/
|
|
38
|
+
export declare function emitResult<T>(command: string, result: CommandResult<T>, mode: OutputMode, streams?: Streams): void;
|
|
39
|
+
/**
|
|
40
|
+
* Render a failure.
|
|
41
|
+
* - json mode: the error envelope goes to stdout (so stdout is always one JSON
|
|
42
|
+
* object) plus a one-line summary to stderr for terminal visibility.
|
|
43
|
+
* - pretty mode: a human error line goes to stderr; stdout stays empty.
|
|
44
|
+
*/
|
|
45
|
+
export declare function emitError(command: string, error: unknown, mode: OutputMode, streams?: Streams): void;
|
|
46
|
+
/** stderr-only logger. stdout is reserved for the result envelope. */
|
|
47
|
+
export declare class Logger {
|
|
48
|
+
private readonly mode;
|
|
49
|
+
private readonly quiet;
|
|
50
|
+
private readonly streams;
|
|
51
|
+
constructor(mode: OutputMode, quiet: boolean, streams?: Streams);
|
|
52
|
+
/** Human progress note. Suppressed in json mode and when --quiet is set. */
|
|
53
|
+
info(message: string): void;
|
|
54
|
+
/** Warnings always surface on stderr (still never pollute stdout). */
|
|
55
|
+
warn(message: string): void;
|
|
56
|
+
}
|
|
57
|
+
export { CliError };
|
|
58
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/core/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAc,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3C;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;CAC7B;AAED,6EAA6E;AAC7E,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACvB,eAAe,CAAC,CAAC,CAAC,CAOpB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,aAAa,CAGjF;AAMD,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,eAAO,MAAM,cAAc,EAAE,OAG5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,OAAwB,GAChC,IAAI,CAON;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,OAAwB,GAChC,IAAI,CASN;AAED,sEAAsE;AACtE,qBAAa,MAAM;IAEf,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,OAAwB;IAGpD,4EAA4E;IAC5E,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAO3B,sEAAsE;IACtE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAM5B;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CliError, toCliError } from "./errors.js";
|
|
2
|
+
export function buildSuccessEnvelope(command, result) {
|
|
3
|
+
return {
|
|
4
|
+
ok: true,
|
|
5
|
+
command,
|
|
6
|
+
data: result.data,
|
|
7
|
+
meta: result.meta ?? {},
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function buildErrorEnvelope(command, error) {
|
|
11
|
+
const cliError = toCliError(error);
|
|
12
|
+
return { ok: false, command, error: cliError.toJSON() };
|
|
13
|
+
}
|
|
14
|
+
function stringify(value) {
|
|
15
|
+
return JSON.stringify(value, null, 2);
|
|
16
|
+
}
|
|
17
|
+
export const defaultStreams = {
|
|
18
|
+
stdout: (text) => process.stdout.write(text),
|
|
19
|
+
stderr: (text) => process.stderr.write(text),
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Render a successful command result.
|
|
23
|
+
* - json mode (default): the envelope is written to stdout.
|
|
24
|
+
* - pretty mode: the human renderer (or pretty JSON) is written to stdout.
|
|
25
|
+
*/
|
|
26
|
+
export function emitResult(command, result, mode, streams = defaultStreams) {
|
|
27
|
+
if (mode === "pretty") {
|
|
28
|
+
const text = result.human ? result.human(result.data) : stringify(result.data);
|
|
29
|
+
streams.stdout(`${text}\n`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
streams.stdout(`${stringify(buildSuccessEnvelope(command, result))}\n`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Render a failure.
|
|
36
|
+
* - json mode: the error envelope goes to stdout (so stdout is always one JSON
|
|
37
|
+
* object) plus a one-line summary to stderr for terminal visibility.
|
|
38
|
+
* - pretty mode: a human error line goes to stderr; stdout stays empty.
|
|
39
|
+
*/
|
|
40
|
+
export function emitError(command, error, mode, streams = defaultStreams) {
|
|
41
|
+
const cliError = toCliError(error);
|
|
42
|
+
const summary = `tenbrains: ${cliError.code}: ${cliError.message}`;
|
|
43
|
+
if (mode === "pretty") {
|
|
44
|
+
streams.stderr(`${summary}\n`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
streams.stdout(`${stringify(buildErrorEnvelope(command, cliError))}\n`);
|
|
48
|
+
streams.stderr(`${summary}\n`);
|
|
49
|
+
}
|
|
50
|
+
/** stderr-only logger. stdout is reserved for the result envelope. */
|
|
51
|
+
export class Logger {
|
|
52
|
+
mode;
|
|
53
|
+
quiet;
|
|
54
|
+
streams;
|
|
55
|
+
constructor(mode, quiet, streams = defaultStreams) {
|
|
56
|
+
this.mode = mode;
|
|
57
|
+
this.quiet = quiet;
|
|
58
|
+
this.streams = streams;
|
|
59
|
+
}
|
|
60
|
+
/** Human progress note. Suppressed in json mode and when --quiet is set. */
|
|
61
|
+
info(message) {
|
|
62
|
+
if (this.quiet || this.mode === "json") {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this.streams.stderr(`${message}\n`);
|
|
66
|
+
}
|
|
67
|
+
/** Warnings always surface on stderr (still never pollute stdout). */
|
|
68
|
+
warn(message) {
|
|
69
|
+
if (this.quiet) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.streams.stderr(`warning: ${message}\n`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export { CliError };
|
|
76
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/core/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem locations the CLI uses. Resolution order for each path is:
|
|
3
|
+
* 1. an explicit override (CLI flag, e.g. --config-dir / --db)
|
|
4
|
+
* 2. the XDG base-directory environment variables (OS convention)
|
|
5
|
+
* 3. a sensible default under the user's home directory
|
|
6
|
+
*
|
|
7
|
+
* The CLI never requires application-specific environment variables and never
|
|
8
|
+
* asks the user to author a dotfile by hand: credential collection happens
|
|
9
|
+
* through `tenbrains setup` / `tenbrains config set`, which write the managed
|
|
10
|
+
* config file returned by {@link resolveConfigFile}.
|
|
11
|
+
*/
|
|
12
|
+
export interface PathOverrides {
|
|
13
|
+
configDir?: string | undefined;
|
|
14
|
+
dbPath?: string | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare function resolveConfigDir(overrides?: PathOverrides): string;
|
|
17
|
+
export declare function resolveConfigFile(overrides?: PathOverrides): string;
|
|
18
|
+
export declare function resolveDataDir(overrides?: PathOverrides): string;
|
|
19
|
+
export declare function resolveDbPath(overrides?: PathOverrides): string;
|
|
20
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAID,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,aAAkB,GAAG,MAAM,CAStE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,aAAkB,GAAG,MAAM,CAEvE;AAED,wBAAgB,cAAc,CAAC,SAAS,GAAE,aAAkB,GAAG,MAAM,CAMpE;AAED,wBAAgB,aAAa,CAAC,SAAS,GAAE,aAAkB,GAAG,MAAM,CAMnE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const APP_DIR = "tenbrains";
|
|
4
|
+
export function resolveConfigDir(overrides = {}) {
|
|
5
|
+
if (overrides.configDir?.trim()) {
|
|
6
|
+
return path.resolve(overrides.configDir.trim());
|
|
7
|
+
}
|
|
8
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
9
|
+
if (xdg?.trim()) {
|
|
10
|
+
return path.join(path.resolve(xdg.trim()), APP_DIR);
|
|
11
|
+
}
|
|
12
|
+
return path.join(homedir(), ".config", APP_DIR);
|
|
13
|
+
}
|
|
14
|
+
export function resolveConfigFile(overrides = {}) {
|
|
15
|
+
return path.join(resolveConfigDir(overrides), "config.json");
|
|
16
|
+
}
|
|
17
|
+
export function resolveDataDir(overrides = {}) {
|
|
18
|
+
const xdg = process.env.XDG_DATA_HOME;
|
|
19
|
+
if (xdg?.trim()) {
|
|
20
|
+
return path.join(path.resolve(xdg.trim()), APP_DIR);
|
|
21
|
+
}
|
|
22
|
+
return path.join(homedir(), ".local", "share", APP_DIR);
|
|
23
|
+
}
|
|
24
|
+
export function resolveDbPath(overrides = {}) {
|
|
25
|
+
const requested = overrides.dbPath?.trim();
|
|
26
|
+
if (requested) {
|
|
27
|
+
return requested === ":memory:" ? ":memory:" : path.resolve(requested);
|
|
28
|
+
}
|
|
29
|
+
return path.join(resolveDataDir(overrides), "tenbrains.db");
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAkB7B,MAAM,OAAO,GAAG,WAAW,CAAC;AAE5B,MAAM,UAAU,gBAAgB,CAAC,YAA2B,EAAE;IAC5D,IAAI,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,YAA2B,EAAE;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,YAA2B,EAAE;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACtC,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,YAA2B,EAAE;IACzD,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Lowercase content words (length >= 4, non-stopword), URLs stripped. */
|
|
2
|
+
export declare function tokenize(text: string): string[];
|
|
3
|
+
/** Unique content tokens, hashes stripped — useful for overlap scoring. */
|
|
4
|
+
export declare function tokenSet(text: string): Set<string>;
|
|
5
|
+
/** Top `n` terms by frequency; ties resolved by first appearance (stable). */
|
|
6
|
+
export declare function significantTerms(text: string, n: number): string[];
|
|
7
|
+
export declare function slugify(value: string): string;
|
|
8
|
+
/** Extract #hashtags (without the #), lowercased. */
|
|
9
|
+
export declare function hashtags(text: string): string[];
|
|
10
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/core/text.ts"],"names":[],"mappings":"AAyFA,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAO/C;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAElD;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBlE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7C;AAED,qDAAqD;AACrD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/C"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const STOPWORDS = new Set([
|
|
2
|
+
"the",
|
|
3
|
+
"and",
|
|
4
|
+
"for",
|
|
5
|
+
"are",
|
|
6
|
+
"but",
|
|
7
|
+
"not",
|
|
8
|
+
"you",
|
|
9
|
+
"all",
|
|
10
|
+
"any",
|
|
11
|
+
"can",
|
|
12
|
+
"had",
|
|
13
|
+
"her",
|
|
14
|
+
"was",
|
|
15
|
+
"one",
|
|
16
|
+
"our",
|
|
17
|
+
"out",
|
|
18
|
+
"day",
|
|
19
|
+
"get",
|
|
20
|
+
"has",
|
|
21
|
+
"him",
|
|
22
|
+
"his",
|
|
23
|
+
"how",
|
|
24
|
+
"man",
|
|
25
|
+
"new",
|
|
26
|
+
"now",
|
|
27
|
+
"old",
|
|
28
|
+
"see",
|
|
29
|
+
"two",
|
|
30
|
+
"way",
|
|
31
|
+
"who",
|
|
32
|
+
"did",
|
|
33
|
+
"its",
|
|
34
|
+
"let",
|
|
35
|
+
"put",
|
|
36
|
+
"say",
|
|
37
|
+
"she",
|
|
38
|
+
"too",
|
|
39
|
+
"use",
|
|
40
|
+
"that",
|
|
41
|
+
"with",
|
|
42
|
+
"this",
|
|
43
|
+
"have",
|
|
44
|
+
"from",
|
|
45
|
+
"they",
|
|
46
|
+
"will",
|
|
47
|
+
"your",
|
|
48
|
+
"what",
|
|
49
|
+
"when",
|
|
50
|
+
"make",
|
|
51
|
+
"like",
|
|
52
|
+
"time",
|
|
53
|
+
"just",
|
|
54
|
+
"them",
|
|
55
|
+
"than",
|
|
56
|
+
"then",
|
|
57
|
+
"into",
|
|
58
|
+
"more",
|
|
59
|
+
"some",
|
|
60
|
+
"such",
|
|
61
|
+
"only",
|
|
62
|
+
"over",
|
|
63
|
+
"also",
|
|
64
|
+
"back",
|
|
65
|
+
"after",
|
|
66
|
+
"very",
|
|
67
|
+
"most",
|
|
68
|
+
"good",
|
|
69
|
+
"much",
|
|
70
|
+
"many",
|
|
71
|
+
"been",
|
|
72
|
+
"were",
|
|
73
|
+
"would",
|
|
74
|
+
"about",
|
|
75
|
+
"there",
|
|
76
|
+
"their",
|
|
77
|
+
"which",
|
|
78
|
+
"these",
|
|
79
|
+
"those",
|
|
80
|
+
"could",
|
|
81
|
+
"should",
|
|
82
|
+
"because",
|
|
83
|
+
"here",
|
|
84
|
+
"http",
|
|
85
|
+
"https",
|
|
86
|
+
"com",
|
|
87
|
+
"www",
|
|
88
|
+
]);
|
|
89
|
+
/** Lowercase content words (length >= 4, non-stopword), URLs stripped. */
|
|
90
|
+
export function tokenize(text) {
|
|
91
|
+
return text
|
|
92
|
+
.toLowerCase()
|
|
93
|
+
.replace(/https?:\/\/\S+/g, " ")
|
|
94
|
+
.replace(/[^a-z0-9#\s]/g, " ")
|
|
95
|
+
.split(/\s+/)
|
|
96
|
+
.filter((w) => w.length >= 4 && !STOPWORDS.has(w.replace(/^#/, "")));
|
|
97
|
+
}
|
|
98
|
+
/** Unique content tokens, hashes stripped — useful for overlap scoring. */
|
|
99
|
+
export function tokenSet(text) {
|
|
100
|
+
return new Set(tokenize(text).map((w) => w.replace(/^#/, "")));
|
|
101
|
+
}
|
|
102
|
+
/** Top `n` terms by frequency; ties resolved by first appearance (stable). */
|
|
103
|
+
export function significantTerms(text, n) {
|
|
104
|
+
const counts = new Map();
|
|
105
|
+
let index = 0;
|
|
106
|
+
for (const word of tokenize(text)) {
|
|
107
|
+
const entry = counts.get(word);
|
|
108
|
+
if (entry) {
|
|
109
|
+
entry.count += 1;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
counts.set(word, { count: 1, first: index });
|
|
113
|
+
}
|
|
114
|
+
index += 1;
|
|
115
|
+
}
|
|
116
|
+
return [...counts.entries()]
|
|
117
|
+
.sort((a, b) => b[1].count - a[1].count || a[1].first - b[1].first)
|
|
118
|
+
.slice(0, n)
|
|
119
|
+
.map(([word]) => word);
|
|
120
|
+
}
|
|
121
|
+
export function slugify(value) {
|
|
122
|
+
return value
|
|
123
|
+
.toLowerCase()
|
|
124
|
+
.replace(/^#/, "")
|
|
125
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
126
|
+
.replace(/^-+|-+$/g, "");
|
|
127
|
+
}
|
|
128
|
+
/** Extract #hashtags (without the #), lowercased. */
|
|
129
|
+
export function hashtags(text) {
|
|
130
|
+
return [...text.matchAll(/#(\w{2,})/g)].map((m) => m[1].toLowerCase());
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/core/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import { type ErrorCode } from "./errors.js";
|
|
3
|
+
/** Parse with a zod schema, converting failures into a structured CliError. */
|
|
4
|
+
export declare function parseOrThrow<T>(schema: z.ZodType<T>, value: unknown, message: string, code?: ErrorCode): T;
|
|
5
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAEvD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,SAAwB,GAC7B,CAAC,CAaH"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CliError } from "./errors.js";
|
|
2
|
+
/** Parse with a zod schema, converting failures into a structured CliError. */
|
|
3
|
+
export function parseOrThrow(schema, value, message, code = "VALIDATION") {
|
|
4
|
+
const result = schema.safeParse(value);
|
|
5
|
+
if (!result.success) {
|
|
6
|
+
throw new CliError(code, message, {
|
|
7
|
+
details: {
|
|
8
|
+
issues: result.error.issues.map((issue) => ({
|
|
9
|
+
path: issue.path.join("."),
|
|
10
|
+
message: issue.message,
|
|
11
|
+
})),
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return result.data;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAEvD,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAC1B,MAAoB,EACpB,KAAc,EACd,OAAe,EACf,OAAkB,YAAY;IAE9B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE;YAChC,OAAO,EAAE;gBACP,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;oBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB,CAAC,CAAC;aACJ;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
|