sapper-ai 0.7.0 → 0.8.1

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.
Files changed (39) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +280 -5
  4. package/dist/guard/ScanCache.d.ts +42 -0
  5. package/dist/guard/ScanCache.d.ts.map +1 -0
  6. package/dist/guard/ScanCache.js +261 -0
  7. package/dist/guard/WarningStore.d.ts +33 -0
  8. package/dist/guard/WarningStore.d.ts.map +1 -0
  9. package/dist/guard/WarningStore.js +305 -0
  10. package/dist/guard/getDefaultPolicy.d.ts +3 -0
  11. package/dist/guard/getDefaultPolicy.d.ts.map +1 -0
  12. package/dist/guard/getDefaultPolicy.js +23 -0
  13. package/dist/guard/hooks/guardCheck.d.ts +12 -0
  14. package/dist/guard/hooks/guardCheck.d.ts.map +1 -0
  15. package/dist/guard/hooks/guardCheck.js +137 -0
  16. package/dist/guard/hooks/guardScan.d.ts +27 -0
  17. package/dist/guard/hooks/guardScan.d.ts.map +1 -0
  18. package/dist/guard/hooks/guardScan.js +242 -0
  19. package/dist/guard/scanSingleSkill.d.ts +11 -0
  20. package/dist/guard/scanSingleSkill.d.ts.map +1 -0
  21. package/dist/guard/scanSingleSkill.js +82 -0
  22. package/dist/guard/setup.d.ts +44 -0
  23. package/dist/guard/setup.d.ts.map +1 -0
  24. package/dist/guard/setup.js +296 -0
  25. package/dist/guard/types.d.ts +43 -0
  26. package/dist/guard/types.d.ts.map +1 -0
  27. package/dist/guard/types.js +2 -0
  28. package/dist/harden.d.ts.map +1 -1
  29. package/dist/harden.js +2 -6
  30. package/dist/postinstall.d.ts.map +1 -1
  31. package/dist/postinstall.js +40 -1
  32. package/dist/scan.d.ts.map +1 -1
  33. package/dist/scan.js +7 -2
  34. package/dist/utils/fs.d.ts.map +1 -1
  35. package/dist/utils/fs.js +7 -1
  36. package/dist/utils/interactive.d.ts +15 -0
  37. package/dist/utils/interactive.d.ts.map +1 -0
  38. package/dist/utils/interactive.js +29 -0
  39. package/package.json +3 -3
@@ -0,0 +1,43 @@
1
+ export type GuardDecision = 'safe' | 'suspicious';
2
+ export interface SingleSkillScanResult {
3
+ skillName: string;
4
+ skillPath: string;
5
+ contentHash: string;
6
+ decision: GuardDecision;
7
+ risk: number;
8
+ reasons: string[];
9
+ }
10
+ export interface ScanCacheEntry {
11
+ path: string;
12
+ skillName: string;
13
+ decision: GuardDecision;
14
+ risk: number;
15
+ reasons: string[];
16
+ scannedAt: string;
17
+ }
18
+ export interface ScanCacheVerificationResult {
19
+ valid: boolean;
20
+ }
21
+ export interface SkillWarning {
22
+ skillName: string;
23
+ skillPath: string;
24
+ contentHash: string;
25
+ risk: number;
26
+ reasons: string[];
27
+ detectedAt: string;
28
+ }
29
+ export interface DismissedWarning {
30
+ skillName: string;
31
+ contentHash?: string;
32
+ dismissedAt: string;
33
+ }
34
+ export interface GuardHookOutput {
35
+ suppressPrompt: boolean;
36
+ message?: string;
37
+ warnings?: SkillWarning[];
38
+ summary?: Record<string, boolean | number | string>;
39
+ }
40
+ export interface OutputWriter {
41
+ write: (chunk: string) => unknown;
42
+ }
43
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guard/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,YAAY,CAAA;AAEjD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,aAAa,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,aAAa,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,OAAO,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;CACpD;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;CAClC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1 +1 @@
1
- {"version":3,"file":"harden.d.ts","sourceRoot":"","sources":["../src/harden.ts"],"names":[],"mappings":"AAeA,KAAK,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAA;AAUvC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,WAAW,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,EAAE,CAAA;KAChB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAoLD,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAOlG;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgG5E"}
1
+ {"version":3,"file":"harden.d.ts","sourceRoot":"","sources":["../src/harden.ts"],"names":[],"mappings":"AAeA,KAAK,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAA;AAUvC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,WAAW,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,EAAE,CAAA;KAChB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAkLD,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAOlG;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgG5E"}
package/dist/harden.js CHANGED
@@ -44,17 +44,13 @@ const node_path_1 = require("node:path");
44
44
  const readline = __importStar(require("node:readline"));
45
45
  const package_json_1 = __importDefault(require("../package.json"));
46
46
  const policyYaml_1 = require("./policyYaml");
47
- const env_1 = require("./utils/env");
48
47
  const fs_1 = require("./utils/fs");
48
+ const interactive_1 = require("./utils/interactive");
49
49
  const repoRoot_1 = require("./utils/repoRoot");
50
50
  const semver_1 = require("./utils/semver");
51
51
  const wrapConfig_1 = require("./mcp/wrapConfig");
52
52
  function isInteractivePromptAllowed(options) {
53
- if (options.noPrompt === true)
54
- return false;
55
- if ((0, env_1.isCiEnv)(options.env))
56
- return false;
57
- return process.stdout.isTTY === true && process.stdin.isTTY === true;
53
+ return (0, interactive_1.getInteractivePromptState)({ noPrompt: options.noPrompt, env: options.env }).allowed;
58
54
  }
59
55
  async function promptYesNo(question, defaultYes) {
60
56
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
@@ -1 +1 @@
1
- {"version":3,"file":"postinstall.d.ts","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,IAAI,IAAI,CAYrC"}
1
+ {"version":3,"file":"postinstall.d.ts","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":"AAQA,wBAAgB,cAAc,IAAI,IAAI,CAgBrC"}
@@ -1,21 +1,60 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
39
  exports.runPostinstall = runPostinstall;
40
+ const fs = __importStar(require("node:fs"));
41
+ const os = __importStar(require("node:os"));
42
+ const path = __importStar(require("node:path"));
7
43
  const package_json_1 = __importDefault(require("../package.json"));
8
44
  const format_1 = require("./utils/format");
9
45
  function runPostinstall() {
10
46
  try {
47
+ const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? os.homedir();
48
+ fs.mkdirSync(path.join(homeDir, '.sapper-ai'), { recursive: true });
11
49
  const colors = (0, format_1.createColors)();
12
50
  const version = typeof package_json_1.default.version === 'string' ? package_json_1.default.version : '';
13
51
  const name = colors.olive ? `${colors.olive}sapper-ai${colors.reset}` : 'sapper-ai';
14
52
  const ver = version ? `${colors.dim}v${version}${colors.reset}` : '';
15
53
  console.log(`\n ${name} ${ver}\n`);
16
- console.log(' Run npx sapper-ai scan to get started.\n');
54
+ console.log(' SapperAI 설치 완료. Skill Guard 활성화: sapper-ai setup\n');
17
55
  }
18
56
  catch {
57
+ // Postinstall failure must not block package installation.
19
58
  }
20
59
  }
21
60
  if (require.main === module) {
@@ -1 +1 @@
1
- {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAiBD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,EAAE;QACP,cAAc,EAAE,OAAO,CAAA;KACxB,CAAA;IACD,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,MAAM,CAAA;QACrB,YAAY,EAAE,MAAM,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,wBAAwB,EAAE,MAAM,CAAA;QAChC,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,QAAQ,EAAE,KAAK,CAAC;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,EAAE,CAAA;QACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,WAAW,EAAE,KAAK,CAAC;YACjB,KAAK,EAAE,MAAM,CAAA;YACb,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAA;YAC3B,SAAS,EAAE,MAAM,CAAA;YACjB,OAAO,EAAE,MAAM,CAAA;SAChB,CAAC,CAAA;KACH,CAAC,CAAA;CACH;AA8XD,wBAAsB,OAAO,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6RxE"}
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAiBD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,EAAE;QACP,cAAc,EAAE,OAAO,CAAA;KACxB,CAAA;IACD,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,MAAM,CAAA;QACrB,YAAY,EAAE,MAAM,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,wBAAwB,EAAE,MAAM,CAAA;QAChC,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,QAAQ,EAAE,KAAK,CAAC;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,EAAE,CAAA;QACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,WAAW,EAAE,KAAK,CAAC;YACjB,KAAK,EAAE,MAAM,CAAA;YACb,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAA;YAC3B,SAAS,EAAE,MAAM,CAAA;YACjB,OAAO,EAAE,MAAM,CAAA;SAChB,CAAC,CAAA;KACH,CAAC,CAAA;CACH;AA8XD,wBAAsB,OAAO,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgSxE"}
package/dist/scan.js CHANGED
@@ -40,6 +40,7 @@ const node_path_1 = require("node:path");
40
40
  const core_1 = require("@sapper-ai/core");
41
41
  const auth_1 = require("./auth");
42
42
  const presets_1 = require("./presets");
43
+ const interactive_1 = require("./utils/interactive");
43
44
  const progress_1 = require("./utils/progress");
44
45
  const format_1 = require("./utils/format");
45
46
  const repoRoot_1 = require("./utils/repoRoot");
@@ -351,9 +352,13 @@ async function runScan(options = {}) {
351
352
  if (aiEnabled) {
352
353
  let apiKey = await (0, auth_1.loadOpenAiApiKey)();
353
354
  if (!apiKey) {
354
- const canPrompt = options.noPrompt !== true && process.stdout.isTTY === true && process.stdin.isTTY === true;
355
- if (!canPrompt) {
355
+ const promptState = (0, interactive_1.getInteractivePromptState)({
356
+ noPrompt: options.noPrompt,
357
+ checkCi: false,
358
+ });
359
+ if (!promptState.allowed) {
356
360
  console.log(' Error: OPENAI_API_KEY environment variable is required for --ai mode.\n');
361
+ console.log(` Prompt unavailable: ${(0, interactive_1.formatInteractivePromptReasons)(promptState.reasons)}.\n`);
357
362
  return 1;
358
363
  }
359
364
  console.log(' No OpenAI API key found.\n');
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAIA,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAM/E;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAkBD,wBAAsB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKtE;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9B,OAAO,CAAC,IAAI,CAAC,CASf"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAIA,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAM/E;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAkBD,wBAAsB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKtE;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf"}
package/dist/utils/fs.js CHANGED
@@ -43,5 +43,11 @@ async function atomicWriteFile(filePath, content, options = {}) {
43
43
  const tmpName = `.${(0, node_path_1.basename)(filePath)}.tmp.${process.pid}.${Date.now()}`;
44
44
  const tmpPath = (0, node_path_1.join)(dir, tmpName);
45
45
  await (0, promises_1.writeFile)(tmpPath, content, { encoding: 'utf8', mode: options.mode });
46
- await (0, promises_1.rename)(tmpPath, filePath);
46
+ try {
47
+ await (0, promises_1.rename)(tmpPath, filePath);
48
+ }
49
+ catch (error) {
50
+ await (0, promises_1.unlink)(tmpPath).catch(() => { });
51
+ throw error;
52
+ }
47
53
  }
@@ -0,0 +1,15 @@
1
+ export type InteractivePromptReason = 'no_prompt_flag' | 'ci_env' | 'stdout_not_tty' | 'stdin_not_tty';
2
+ export interface InteractivePromptCheckInput {
3
+ noPrompt?: boolean;
4
+ env?: NodeJS.ProcessEnv;
5
+ stdoutIsTTY?: boolean;
6
+ stdinIsTTY?: boolean;
7
+ checkCi?: boolean;
8
+ }
9
+ export interface InteractivePromptCheckResult {
10
+ allowed: boolean;
11
+ reasons: InteractivePromptReason[];
12
+ }
13
+ export declare function getInteractivePromptState(input?: InteractivePromptCheckInput): InteractivePromptCheckResult;
14
+ export declare function formatInteractivePromptReasons(reasons: readonly InteractivePromptReason[]): string;
15
+ //# sourceMappingURL=interactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/utils/interactive.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG,QAAQ,GAAG,gBAAgB,GAAG,eAAe,CAAA;AAEtG,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,uBAAuB,EAAE,CAAA;CACnC;AAED,wBAAgB,yBAAyB,CAAC,KAAK,GAAE,2BAAgC,GAAG,4BAA4B,CAyB/G;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,SAAS,uBAAuB,EAAE,GAAG,MAAM,CAElG"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getInteractivePromptState = getInteractivePromptState;
4
+ exports.formatInteractivePromptReasons = formatInteractivePromptReasons;
5
+ const env_1 = require("./env");
6
+ function getInteractivePromptState(input = {}) {
7
+ const reasons = [];
8
+ if (input.noPrompt === true) {
9
+ reasons.push('no_prompt_flag');
10
+ }
11
+ if ((input.checkCi ?? true) && (0, env_1.isCiEnv)(input.env ?? process.env)) {
12
+ reasons.push('ci_env');
13
+ }
14
+ const stdoutIsTTY = input.stdoutIsTTY ?? process.stdout.isTTY;
15
+ if (stdoutIsTTY !== true) {
16
+ reasons.push('stdout_not_tty');
17
+ }
18
+ const stdinIsTTY = input.stdinIsTTY ?? process.stdin.isTTY;
19
+ if (stdinIsTTY !== true) {
20
+ reasons.push('stdin_not_tty');
21
+ }
22
+ return {
23
+ allowed: reasons.length === 0,
24
+ reasons,
25
+ };
26
+ }
27
+ function formatInteractivePromptReasons(reasons) {
28
+ return reasons.length > 0 ? reasons.join(', ') : 'unknown';
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-ai",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "AI security guardrails - single install, sensible defaults",
5
5
  "keywords": [
6
6
  "security",
@@ -46,8 +46,8 @@
46
46
  "@inquirer/password": "^4.0.0",
47
47
  "@inquirer/select": "^4.0.0",
48
48
  "@sapper-ai/core": "0.3.0",
49
- "@sapper-ai/mcp": "0.3.2",
50
- "@sapper-ai/types": "0.3.0"
49
+ "@sapper-ai/types": "0.3.0",
50
+ "@sapper-ai/mcp": "0.3.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "^20.0.0",