@dewtech/dare-cli 3.8.2 → 3.9.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.
Files changed (140) hide show
  1. package/README.md +18 -0
  2. package/dist/__tests__/ide-command-parity.test.js +1 -0
  3. package/dist/__tests__/ide-command-parity.test.js.map +1 -1
  4. package/dist/__tests__/secure-executor-regression.test.d.ts +2 -0
  5. package/dist/__tests__/secure-executor-regression.test.d.ts.map +1 -0
  6. package/dist/__tests__/secure-executor-regression.test.js +294 -0
  7. package/dist/__tests__/secure-executor-regression.test.js.map +1 -0
  8. package/dist/agent/__tests__/budget.test.d.ts +2 -0
  9. package/dist/agent/__tests__/budget.test.d.ts.map +1 -0
  10. package/dist/agent/__tests__/budget.test.js +36 -0
  11. package/dist/agent/__tests__/budget.test.js.map +1 -0
  12. package/dist/agent/__tests__/claude-driver.test.d.ts +2 -0
  13. package/dist/agent/__tests__/claude-driver.test.d.ts.map +1 -0
  14. package/dist/agent/__tests__/claude-driver.test.js +88 -0
  15. package/dist/agent/__tests__/claude-driver.test.js.map +1 -0
  16. package/dist/agent/__tests__/cost-telemetry.test.d.ts +2 -0
  17. package/dist/agent/__tests__/cost-telemetry.test.d.ts.map +1 -0
  18. package/dist/agent/__tests__/cost-telemetry.test.js +61 -0
  19. package/dist/agent/__tests__/cost-telemetry.test.js.map +1 -0
  20. package/dist/agent/__tests__/driver.types.test.d.ts +2 -0
  21. package/dist/agent/__tests__/driver.types.test.d.ts.map +1 -0
  22. package/dist/agent/__tests__/driver.types.test.js +33 -0
  23. package/dist/agent/__tests__/driver.types.test.js.map +1 -0
  24. package/dist/agent/__tests__/mock-driver.test.d.ts +2 -0
  25. package/dist/agent/__tests__/mock-driver.test.d.ts.map +1 -0
  26. package/dist/agent/__tests__/mock-driver.test.js +100 -0
  27. package/dist/agent/__tests__/mock-driver.test.js.map +1 -0
  28. package/dist/agent/__tests__/no-llm-in-core.test.d.ts +2 -0
  29. package/dist/agent/__tests__/no-llm-in-core.test.d.ts.map +1 -0
  30. package/dist/agent/__tests__/no-llm-in-core.test.js +46 -0
  31. package/dist/agent/__tests__/no-llm-in-core.test.js.map +1 -0
  32. package/dist/agent/budget.d.ts +15 -0
  33. package/dist/agent/budget.d.ts.map +1 -0
  34. package/dist/agent/budget.js +23 -0
  35. package/dist/agent/budget.js.map +1 -0
  36. package/dist/agent/driver.d.ts +46 -0
  37. package/dist/agent/driver.d.ts.map +1 -0
  38. package/dist/agent/driver.js +2 -0
  39. package/dist/agent/driver.js.map +1 -0
  40. package/dist/agent/drivers/claude.d.ts +43 -0
  41. package/dist/agent/drivers/claude.d.ts.map +1 -0
  42. package/dist/agent/drivers/claude.js +134 -0
  43. package/dist/agent/drivers/claude.js.map +1 -0
  44. package/dist/agent/drivers/mock.d.ts +3 -0
  45. package/dist/agent/drivers/mock.d.ts.map +1 -0
  46. package/dist/agent/drivers/mock.js +56 -0
  47. package/dist/agent/drivers/mock.js.map +1 -0
  48. package/dist/agent/drivers/noop.d.ts +3 -0
  49. package/dist/agent/drivers/noop.d.ts.map +1 -0
  50. package/dist/agent/drivers/noop.js +13 -0
  51. package/dist/agent/drivers/noop.js.map +1 -0
  52. package/dist/agent/telemetry.d.ts +4 -0
  53. package/dist/agent/telemetry.d.ts.map +1 -0
  54. package/dist/agent/telemetry.js +25 -0
  55. package/dist/agent/telemetry.js.map +1 -0
  56. package/dist/bin/dare.js +2 -0
  57. package/dist/bin/dare.js.map +1 -1
  58. package/dist/commands/__tests__/execute-agent.test.d.ts +2 -0
  59. package/dist/commands/__tests__/execute-agent.test.d.ts.map +1 -0
  60. package/dist/commands/__tests__/execute-agent.test.js +191 -0
  61. package/dist/commands/__tests__/execute-agent.test.js.map +1 -0
  62. package/dist/commands/__tests__/require-approval.test.d.ts +2 -0
  63. package/dist/commands/__tests__/require-approval.test.d.ts.map +1 -0
  64. package/dist/commands/__tests__/require-approval.test.js +158 -0
  65. package/dist/commands/__tests__/require-approval.test.js.map +1 -0
  66. package/dist/commands/execute.d.ts +68 -0
  67. package/dist/commands/execute.d.ts.map +1 -1
  68. package/dist/commands/execute.js +558 -2
  69. package/dist/commands/execute.js.map +1 -1
  70. package/dist/commands/guard.d.ts +13 -0
  71. package/dist/commands/guard.d.ts.map +1 -0
  72. package/dist/commands/guard.js +338 -0
  73. package/dist/commands/guard.js.map +1 -0
  74. package/dist/guard/__tests__/boundary.test.d.ts +2 -0
  75. package/dist/guard/__tests__/boundary.test.d.ts.map +1 -0
  76. package/dist/guard/__tests__/boundary.test.js +37 -0
  77. package/dist/guard/__tests__/boundary.test.js.map +1 -0
  78. package/dist/guard/__tests__/guard-command.test.d.ts +2 -0
  79. package/dist/guard/__tests__/guard-command.test.d.ts.map +1 -0
  80. package/dist/guard/__tests__/guard-command.test.js +88 -0
  81. package/dist/guard/__tests__/guard-command.test.js.map +1 -0
  82. package/dist/guard/__tests__/guard-config.test.d.ts +2 -0
  83. package/dist/guard/__tests__/guard-config.test.d.ts.map +1 -0
  84. package/dist/guard/__tests__/guard-config.test.js +34 -0
  85. package/dist/guard/__tests__/guard-config.test.js.map +1 -0
  86. package/dist/guard/__tests__/guard-integration.test.d.ts +2 -0
  87. package/dist/guard/__tests__/guard-integration.test.d.ts.map +1 -0
  88. package/dist/guard/__tests__/guard-integration.test.js +218 -0
  89. package/dist/guard/__tests__/guard-integration.test.js.map +1 -0
  90. package/dist/guard/__tests__/guard-types.test.d.ts +2 -0
  91. package/dist/guard/__tests__/guard-types.test.d.ts.map +1 -0
  92. package/dist/guard/__tests__/guard-types.test.js +28 -0
  93. package/dist/guard/__tests__/guard-types.test.js.map +1 -0
  94. package/dist/guard/__tests__/provenance.test.d.ts +2 -0
  95. package/dist/guard/__tests__/provenance.test.d.ts.map +1 -0
  96. package/dist/guard/__tests__/provenance.test.js +80 -0
  97. package/dist/guard/__tests__/provenance.test.js.map +1 -0
  98. package/dist/guard/__tests__/scan.test.d.ts +2 -0
  99. package/dist/guard/__tests__/scan.test.d.ts.map +1 -0
  100. package/dist/guard/__tests__/scan.test.js +62 -0
  101. package/dist/guard/__tests__/scan.test.js.map +1 -0
  102. package/dist/guard/__tests__/unicode.test.d.ts +2 -0
  103. package/dist/guard/__tests__/unicode.test.d.ts.map +1 -0
  104. package/dist/guard/__tests__/unicode.test.js +75 -0
  105. package/dist/guard/__tests__/unicode.test.js.map +1 -0
  106. package/dist/guard/boundary.d.ts +9 -0
  107. package/dist/guard/boundary.d.ts.map +1 -0
  108. package/dist/guard/boundary.js +17 -0
  109. package/dist/guard/boundary.js.map +1 -0
  110. package/dist/guard/config.d.ts +60 -0
  111. package/dist/guard/config.d.ts.map +1 -0
  112. package/dist/guard/config.js +64 -0
  113. package/dist/guard/config.js.map +1 -0
  114. package/dist/guard/pipeline.d.ts +13 -0
  115. package/dist/guard/pipeline.d.ts.map +1 -0
  116. package/dist/guard/pipeline.js +120 -0
  117. package/dist/guard/pipeline.js.map +1 -0
  118. package/dist/guard/provenance.d.ts +18 -0
  119. package/dist/guard/provenance.d.ts.map +1 -0
  120. package/dist/guard/provenance.js +108 -0
  121. package/dist/guard/provenance.js.map +1 -0
  122. package/dist/guard/scan.d.ts +6 -0
  123. package/dist/guard/scan.d.ts.map +1 -0
  124. package/dist/guard/scan.js +84 -0
  125. package/dist/guard/scan.js.map +1 -0
  126. package/dist/guard/types.d.ts +28 -0
  127. package/dist/guard/types.d.ts.map +1 -0
  128. package/dist/guard/types.js +2 -0
  129. package/dist/guard/types.js.map +1 -0
  130. package/dist/guard/unicode.d.ts +8 -0
  131. package/dist/guard/unicode.d.ts.map +1 -0
  132. package/dist/guard/unicode.js +126 -0
  133. package/dist/guard/unicode.js.map +1 -0
  134. package/dist/utils/project-generator.d.ts.map +1 -1
  135. package/dist/utils/project-generator.js +2 -0
  136. package/dist/utils/project-generator.js.map +1 -1
  137. package/package.json +4 -1
  138. package/templates/ide/antigravity/.agents/skills/dare-guard/SKILL.md +16 -0
  139. package/templates/ide/claude/.claude/commands/dare-guard.md +16 -0
  140. package/templates/ide/cursor/.cursor/commands/dare-guard.md +16 -0
@@ -0,0 +1,75 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { auditUnicode } from '../unicode.js';
3
+ describe('auditUnicode', () => {
4
+ it('detects_zero_width', () => {
5
+ const content = `abc\u200Bdef`;
6
+ const result = auditUnicode(content, 'strip');
7
+ expect(result.findings).toHaveLength(1);
8
+ expect(result.findings[0]).toMatchObject({
9
+ layer: 'unicode',
10
+ severity: 'WARN',
11
+ rule: 'zero-width',
12
+ });
13
+ expect(result.findings[0].evidence).toContain('U+200B');
14
+ expect(result.sanitized).toBe('abcdef');
15
+ });
16
+ it('detects_bidi_override', () => {
17
+ const content = `safe\u202Etext`;
18
+ const result = auditUnicode(content, 'strip');
19
+ expect(result.findings).toHaveLength(1);
20
+ expect(result.findings[0].rule).toBe('bidi-override');
21
+ expect(result.findings[0].evidence).toContain('U+202E');
22
+ expect(result.sanitized).toBe('safetext');
23
+ });
24
+ it('detects_variation_selector', () => {
25
+ const content = `warn\uFE0Fing`;
26
+ const result = auditUnicode(content, 'strip');
27
+ expect(result.findings).toHaveLength(1);
28
+ expect(result.findings[0].rule).toBe('variation-selector');
29
+ expect(result.findings[0].evidence).toContain('U+FE0F');
30
+ expect(result.sanitized).toBe('warning');
31
+ });
32
+ it('detects_tag_chars', () => {
33
+ const tagChar = String.fromCodePoint(0xe0001);
34
+ const content = `ab${tagChar}cd`;
35
+ const result = auditUnicode(content, 'strip');
36
+ expect(result.findings).toHaveLength(1);
37
+ expect(result.findings[0].rule).toBe('tag-char');
38
+ expect(result.findings[0].evidence).toContain('U+E0001');
39
+ expect(result.sanitized).toBe('abcd');
40
+ });
41
+ it('strip_removes_and_returns_clean', () => {
42
+ const content = `A\u200BB\u202EC\uFE0FD${String.fromCodePoint(0xe0001)}E`;
43
+ const result = auditUnicode(content, 'strip');
44
+ expect(result.findings.map((f) => f.severity)).toEqual([
45
+ 'WARN',
46
+ 'WARN',
47
+ 'WARN',
48
+ 'WARN',
49
+ ]);
50
+ expect(result.sanitized).toBe('ABCDE');
51
+ });
52
+ it('block_flags_fail_keeps_content', () => {
53
+ const content = `ab\u200Bcd`;
54
+ const result = auditUnicode(content, 'block');
55
+ expect(result.findings).toHaveLength(1);
56
+ expect(result.findings[0].severity).toBe('FAIL');
57
+ expect(result.sanitized).toBe(content);
58
+ });
59
+ it('clean_text_passes', () => {
60
+ const content = 'texto benigno sem unicode suspeito';
61
+ const result = auditUnicode(content, 'strip');
62
+ expect(result.findings).toHaveLength(0);
63
+ expect(result.sanitized).toBe(content);
64
+ });
65
+ it('homoglyph_basic', () => {
66
+ const content = 'раypal';
67
+ const result = auditUnicode(content, 'strip');
68
+ expect(result.findings).toHaveLength(2);
69
+ expect(result.findings.every((f) => f.rule === 'homoglyph')).toBe(true);
70
+ expect(result.findings[0].evidence).toContain('U+0440');
71
+ expect(result.findings[1].evidence).toContain('U+0430');
72
+ expect(result.sanitized).toBe(content);
73
+ });
74
+ });
75
+ //# sourceMappingURL=unicode.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unicode.test.js","sourceRoot":"","sources":["../../../src/guard/__tests__/unicode.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { GuardedArtifact } from './types.js';
2
+ export type BoundaryIntent = 'read' | 'execute-hook' | 'reorder-gate';
3
+ export declare class BoundaryViolationError extends Error {
4
+ readonly code: "BOUNDARY_VIOLATION";
5
+ constructor(message: string);
6
+ }
7
+ /** Dado nao-confiavel nao pode virar controle. */
8
+ export declare function enforceBoundary(artifact: GuardedArtifact, intent: BoundaryIntent): void;
9
+ //# sourceMappingURL=boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/guard/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,cAAc,GAAG,cAAc,CAAC;AAEtE,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,oBAAoB,CAAU;gBAElC,OAAO,EAAE,MAAM;CAI5B;AAED,kDAAkD;AAClD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,cAAc,GACrB,IAAI,CASN"}
@@ -0,0 +1,17 @@
1
+ export class BoundaryViolationError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.code = 'BOUNDARY_VIOLATION';
5
+ this.name = 'BoundaryViolationError';
6
+ }
7
+ }
8
+ /** Dado nao-confiavel nao pode virar controle. */
9
+ export function enforceBoundary(artifact, intent) {
10
+ if (intent === 'read')
11
+ return;
12
+ const isControlSigned = artifact.channel === 'control' && artifact.trust === 'signed';
13
+ if (isControlSigned)
14
+ return;
15
+ throw new BoundaryViolationError(`data-channel artifact cannot ${intent}`);
16
+ }
17
+ //# sourceMappingURL=boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../src/guard/boundary.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAG/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,SAAI,GAAG,oBAA6B,CAAC;QAI5C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,kDAAkD;AAClD,MAAM,UAAU,eAAe,CAC7B,QAAyB,EACzB,MAAsB;IAEtB,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO;IAE9B,MAAM,eAAe,GACnB,QAAQ,CAAC,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC;IAEhE,IAAI,eAAe;QAAE,OAAO;IAE5B,MAAM,IAAI,sBAAsB,CAAC,gCAAgC,MAAM,EAAE,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { z } from 'zod';
2
+ export declare const GUARD_DEFAULTS: {
3
+ enabled: boolean;
4
+ onExecute: boolean;
5
+ unicode: "strip";
6
+ trustedPaths: string[];
7
+ signing: {
8
+ enabled: false;
9
+ publicKey: string | undefined;
10
+ };
11
+ };
12
+ export declare const guardConfigSchema: z.ZodObject<{
13
+ enabled: z.ZodDefault<z.ZodBoolean>;
14
+ onExecute: z.ZodDefault<z.ZodBoolean>;
15
+ unicode: z.ZodDefault<z.ZodEnum<["strip", "block"]>>;
16
+ trustedPaths: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
17
+ signing: z.ZodDefault<z.ZodObject<{
18
+ enabled: z.ZodDefault<z.ZodBoolean>;
19
+ publicKey: z.ZodOptional<z.ZodString>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ enabled: boolean;
22
+ publicKey?: string | undefined;
23
+ }, {
24
+ enabled?: boolean | undefined;
25
+ publicKey?: string | undefined;
26
+ }>>;
27
+ }, "strict", z.ZodTypeAny, {
28
+ enabled: boolean;
29
+ onExecute: boolean;
30
+ unicode: "strip" | "block";
31
+ trustedPaths: string[];
32
+ signing: {
33
+ enabled: boolean;
34
+ publicKey?: string | undefined;
35
+ };
36
+ }, {
37
+ enabled?: boolean | undefined;
38
+ onExecute?: boolean | undefined;
39
+ unicode?: "strip" | "block" | undefined;
40
+ trustedPaths?: string[] | undefined;
41
+ signing?: {
42
+ enabled?: boolean | undefined;
43
+ publicKey?: string | undefined;
44
+ } | undefined;
45
+ }>;
46
+ export type GuardConfig = z.infer<typeof guardConfigSchema>;
47
+ export declare class GuardConfigError extends Error {
48
+ readonly issues: ReadonlyArray<{
49
+ path: string;
50
+ message: string;
51
+ }>;
52
+ constructor(issues: ReadonlyArray<{
53
+ path: string;
54
+ message: string;
55
+ }>);
56
+ }
57
+ export declare function parseGuardConfig(raw: unknown): GuardConfig;
58
+ export declare function defaultGuardConfigForProject(): GuardConfig;
59
+ export declare function seedGuardDefaultsIfAbsent(cfg: Record<string, unknown>): boolean;
60
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/guard/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,cAAc;;;;;;;mBAKmC,MAAM,GAAG,SAAS;;CAC/E,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAanB,CAAC;AAEZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;gBAEtD,MAAM,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrE;AAkBD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAW1D;AAED,wBAAgB,4BAA4B,IAAI,WAAW,CAE1D;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,OAAO,CAIT"}
@@ -0,0 +1,64 @@
1
+ import { z } from 'zod';
2
+ export const GUARD_DEFAULTS = {
3
+ enabled: false,
4
+ onExecute: true,
5
+ unicode: 'strip',
6
+ trustedPaths: ['.dare/steering/**', 'DARE/TASKS.md'],
7
+ signing: { enabled: false, publicKey: undefined },
8
+ };
9
+ export const guardConfigSchema = z
10
+ .object({
11
+ enabled: z.boolean().default(GUARD_DEFAULTS.enabled),
12
+ onExecute: z.boolean().default(GUARD_DEFAULTS.onExecute),
13
+ unicode: z.enum(['strip', 'block']).default(GUARD_DEFAULTS.unicode),
14
+ trustedPaths: z.array(z.string()).default([...GUARD_DEFAULTS.trustedPaths]),
15
+ signing: z
16
+ .object({
17
+ enabled: z.boolean().default(false),
18
+ publicKey: z.string().optional(),
19
+ })
20
+ .default({ enabled: false }),
21
+ })
22
+ .strict();
23
+ export class GuardConfigError extends Error {
24
+ constructor(issues) {
25
+ super(`Invalid guard config: ${issues.map((i) => `${i.path}: ${i.message}`).join('; ')}`);
26
+ this.name = 'GuardConfigError';
27
+ this.issues = issues;
28
+ }
29
+ }
30
+ function isGuardBlockAbsent(raw) {
31
+ if (raw === undefined || raw === null)
32
+ return true;
33
+ if (typeof raw !== 'object')
34
+ return false;
35
+ const rec = raw;
36
+ return !('guard' in rec) || rec.guard === undefined;
37
+ }
38
+ function zodIssues(error) {
39
+ return error.issues.map((issue) => ({
40
+ path: issue.path.length > 0 ? issue.path.join('.') : '(root)',
41
+ message: issue.message,
42
+ }));
43
+ }
44
+ export function parseGuardConfig(raw) {
45
+ if (isGuardBlockAbsent(raw)) {
46
+ return guardConfigSchema.parse({});
47
+ }
48
+ const block = raw.guard;
49
+ const result = guardConfigSchema.safeParse(block);
50
+ if (!result.success) {
51
+ throw new GuardConfigError(zodIssues(result.error));
52
+ }
53
+ return result.data;
54
+ }
55
+ export function defaultGuardConfigForProject() {
56
+ return guardConfigSchema.parse({});
57
+ }
58
+ export function seedGuardDefaultsIfAbsent(cfg) {
59
+ if (cfg.guard !== undefined)
60
+ return false;
61
+ cfg.guard = defaultGuardConfigForProject();
62
+ return true;
63
+ }
64
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/guard/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type BoundaryIntent } from './boundary.js';
2
+ import type { GuardConfig } from './config.js';
3
+ import type { GuardResult, GuardedArtifact } from './types.js';
4
+ export interface GuardPipelineOptions {
5
+ readonly cwd?: string;
6
+ readonly boundaryIntent?: BoundaryIntent;
7
+ }
8
+ export interface GuardPipelineOutput {
9
+ readonly result: GuardResult;
10
+ readonly artifact: GuardedArtifact;
11
+ }
12
+ export declare function runGuardPipeline(artifactPath: string, content: Buffer, cfg: GuardConfig, options?: GuardPipelineOptions): GuardPipelineOutput;
13
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/guard/pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,KAAK,EAEV,WAAW,EAEX,eAAe,EAChB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;CAC1C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;CACpC;AAkGD,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,EAChB,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CAwDrB"}
@@ -0,0 +1,120 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { BoundaryViolationError, enforceBoundary, } from './boundary.js';
4
+ import { classify, computeDigest, verifyArtifact } from './provenance.js';
5
+ import { scanHeuristics } from './scan.js';
6
+ import { auditUnicode } from './unicode.js';
7
+ function normalizeProjectPath(rawPath) {
8
+ return rawPath
9
+ .replace(/\\/g, '/')
10
+ .replace(/^[A-Za-z]:\//, '')
11
+ .replace(/^\.\/+/, '')
12
+ .replace(/^\/+/, '')
13
+ .replace(/\/{2,}/g, '/');
14
+ }
15
+ function worstVerdict(findings) {
16
+ if (findings.some((finding) => finding.severity === 'FAIL'))
17
+ return 'FAIL';
18
+ if (findings.some((finding) => finding.severity === 'WARN'))
19
+ return 'WARN';
20
+ return 'PASS';
21
+ }
22
+ function provenanceFinding(rule, evidence, severity = 'FAIL') {
23
+ return {
24
+ layer: 'provenance',
25
+ severity,
26
+ rule,
27
+ evidence,
28
+ };
29
+ }
30
+ function resolveKeyMaterial(cwd, configuredKey) {
31
+ const trimmed = configuredKey?.trim();
32
+ if (!trimmed)
33
+ return undefined;
34
+ if (trimmed.includes('BEGIN PUBLIC KEY'))
35
+ return trimmed;
36
+ const absPath = path.resolve(cwd, trimmed);
37
+ if (fs.existsSync(absPath) && fs.statSync(absPath).isFile()) {
38
+ return fs.readFileSync(absPath, 'utf8');
39
+ }
40
+ return trimmed;
41
+ }
42
+ function loadSignature(artifactAbsPath) {
43
+ const signaturePath = `${artifactAbsPath}.minisig`;
44
+ if (!fs.existsSync(signaturePath))
45
+ return undefined;
46
+ const signature = fs.readFileSync(signaturePath, 'utf8').trim();
47
+ return signature.length > 0 ? signature : undefined;
48
+ }
49
+ function runProvenanceChecks(args) {
50
+ const findings = [];
51
+ if (args.artifact.channel !== 'control' || !args.cfg.signing.enabled) {
52
+ return findings;
53
+ }
54
+ const publicKey = resolveKeyMaterial(args.cwd, args.cfg.signing.publicKey);
55
+ if (!publicKey) {
56
+ findings.push(provenanceFinding('signing-key-missing', 'guard.signing.publicKey is required when signing is enabled'));
57
+ return findings;
58
+ }
59
+ const signature = loadSignature(args.artifactAbsPath);
60
+ if (!signature) {
61
+ findings.push(provenanceFinding('signature-missing', `${args.artifact.path}.minisig is required for trusted artifacts`));
62
+ return findings;
63
+ }
64
+ if (!verifyArtifact(args.content, signature, publicKey)) {
65
+ findings.push(provenanceFinding('signature-invalid', `${args.artifact.path}.minisig does not match artifact digest`));
66
+ }
67
+ return findings;
68
+ }
69
+ export function runGuardPipeline(artifactPath, content, cfg, options = {}) {
70
+ const cwd = options.cwd ?? process.cwd();
71
+ const artifactAbsPath = path.isAbsolute(artifactPath)
72
+ ? artifactPath
73
+ : path.resolve(cwd, artifactPath);
74
+ const artifactRelPath = normalizeProjectPath(path.isAbsolute(artifactPath)
75
+ ? path.relative(cwd, artifactPath)
76
+ : artifactPath);
77
+ const utf8 = content.toString('utf8');
78
+ const cls = classify(artifactRelPath, cfg);
79
+ const unicode = auditUnicode(utf8, cfg.unicode);
80
+ const scan = scanHeuristics(unicode.sanitized);
81
+ const artifact = {
82
+ path: artifactRelPath,
83
+ origin: cls.origin,
84
+ channel: cls.channel,
85
+ trust: cls.trust,
86
+ digest: computeDigest(content),
87
+ };
88
+ const findings = [
89
+ ...unicode.findings,
90
+ ...scan,
91
+ ...runProvenanceChecks({
92
+ cwd,
93
+ artifactAbsPath,
94
+ content,
95
+ cfg,
96
+ artifact,
97
+ }),
98
+ ];
99
+ try {
100
+ enforceBoundary(artifact, options.boundaryIntent ?? 'read');
101
+ }
102
+ catch (err) {
103
+ if (err instanceof BoundaryViolationError) {
104
+ findings.push(provenanceFinding('boundary-violation', err.message));
105
+ }
106
+ else {
107
+ throw err;
108
+ }
109
+ }
110
+ const verdict = worstVerdict(findings);
111
+ const includeSanitized = cfg.unicode === 'strip' && unicode.sanitized !== utf8;
112
+ const result = {
113
+ artifact: artifactRelPath,
114
+ verdict,
115
+ findings,
116
+ ...(includeSanitized ? { sanitized: unicode.sanitized } : {}),
117
+ };
118
+ return { result, artifact };
119
+ }
120
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/guard/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { GuardConfig } from './config.js';
2
+ import type { ArtifactOrigin, TrustChannel } from './types.js';
3
+ type ArtifactTrust = 'signed' | 'unsigned';
4
+ export declare function computeDigest(content: Buffer): string;
5
+ /**
6
+ * Layout minisign-compat:
7
+ * - Linha 1: "untrusted comment: ..."
8
+ * - Linha 2: assinatura Ed25519 em base64 (raw)
9
+ */
10
+ export declare function signArtifact(content: Buffer, privKeyPem: string): string;
11
+ export declare function verifyArtifact(content: Buffer, sig: string, pubKeyPem: string): boolean;
12
+ export declare function classify(path: string, cfg: GuardConfig): {
13
+ origin: ArtifactOrigin;
14
+ channel: TrustChannel;
15
+ trust: ArtifactTrust;
16
+ };
17
+ export {};
18
+ //# sourceMappingURL=provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/guard/provenance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/D,KAAK,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;AAiF3C,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,OAAO,CAST;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,WAAW,GACf;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAezE"}
@@ -0,0 +1,108 @@
1
+ import { createHash, createPrivateKey, createPublicKey, sign, verify } from 'node:crypto';
2
+ function normalizePath(rawPath) {
3
+ return rawPath
4
+ .replace(/\\/g, '/')
5
+ .replace(/^[A-Za-z]:\//, '')
6
+ .replace(/^\.\/+/, '')
7
+ .replace(/^\/+/, '')
8
+ .replace(/\/{2,}/g, '/');
9
+ }
10
+ function isTrustedPath(path, pattern) {
11
+ const normalizedPath = normalizePath(path);
12
+ const normalizedPattern = normalizePath(pattern);
13
+ const hasWildcard = normalizedPattern.includes('*');
14
+ if (!hasWildcard) {
15
+ return (normalizedPath === normalizedPattern ||
16
+ normalizedPath.endsWith(`/${normalizedPattern}`));
17
+ }
18
+ const source = normalizedPattern
19
+ .replace(/[.+?^${}()|[\]\\]/g, '\\$&')
20
+ .replace(/\*\*/g, '::DOUBLE_STAR::')
21
+ .replace(/\*/g, '[^/]*')
22
+ .replace(/::DOUBLE_STAR::/g, '.*');
23
+ const regex = new RegExp(`^(?:.*/)?${source}$`);
24
+ return regex.test(normalizedPath);
25
+ }
26
+ function inferOrigin(path) {
27
+ const normalized = normalizePath(path).toLowerCase();
28
+ if (normalized.startsWith('.dare/')) {
29
+ return 'agent';
30
+ }
31
+ return 'external';
32
+ }
33
+ function decodeBase64Signature(line) {
34
+ const compact = line.replace(/\s+/g, '');
35
+ if (!/^[A-Za-z0-9+/]+={0,2}$/.test(compact)) {
36
+ return null;
37
+ }
38
+ try {
39
+ const decoded = Buffer.from(compact, 'base64');
40
+ if (decoded.length === 0)
41
+ return null;
42
+ const normalizedInput = compact.replace(/=+$/g, '');
43
+ const normalizedDecoded = decoded.toString('base64').replace(/=+$/g, '');
44
+ return normalizedInput === normalizedDecoded ? decoded : null;
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ function signaturePayload(signature) {
51
+ const lines = signature
52
+ .split(/\r?\n/)
53
+ .map((line) => line.trim())
54
+ .filter((line) => line.length > 0);
55
+ if (lines.length === 0)
56
+ return null;
57
+ const candidateLines = lines.length === 1
58
+ ? lines
59
+ : lines.filter((line) => !line.toLowerCase().startsWith('untrusted comment:') &&
60
+ !line.toLowerCase().startsWith('trusted comment:'));
61
+ for (const candidate of candidateLines) {
62
+ const decoded = decodeBase64Signature(candidate);
63
+ if (decoded)
64
+ return decoded;
65
+ }
66
+ return null;
67
+ }
68
+ export function computeDigest(content) {
69
+ return createHash('sha256').update(content).digest('hex');
70
+ }
71
+ /**
72
+ * Layout minisign-compat:
73
+ * - Linha 1: "untrusted comment: ..."
74
+ * - Linha 2: assinatura Ed25519 em base64 (raw)
75
+ */
76
+ export function signArtifact(content, privKeyPem) {
77
+ const privateKey = createPrivateKey(privKeyPem);
78
+ const signature = sign(null, content, privateKey).toString('base64');
79
+ return `untrusted comment: signature from dare guard\n${signature}`;
80
+ }
81
+ export function verifyArtifact(content, sig, pubKeyPem) {
82
+ const payload = signaturePayload(sig);
83
+ if (!payload)
84
+ return false;
85
+ try {
86
+ const publicKey = createPublicKey(pubKeyPem);
87
+ return verify(null, content, publicKey, payload);
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ export function classify(path, cfg) {
94
+ const trusted = cfg.trustedPaths.some((pattern) => isTrustedPath(path, pattern));
95
+ if (trusted) {
96
+ return {
97
+ origin: 'human',
98
+ channel: 'control',
99
+ trust: cfg.signing.enabled ? 'signed' : 'unsigned',
100
+ };
101
+ }
102
+ return {
103
+ origin: inferOrigin(path),
104
+ channel: 'data',
105
+ trust: 'unsigned',
106
+ };
107
+ }
108
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/guard/provenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { GuardFinding } from './types.js';
2
+ /**
3
+ * Heurística best-effort (camada 2): um achado isolado é sempre WARN.
4
+ */
5
+ export declare function scanHeuristics(content: string): GuardFinding[];
6
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/guard/scan.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoF/C;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAuB9D"}
@@ -0,0 +1,84 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const RULES_FILENAME = 'scan-rules.json';
5
+ const DEFAULT_RULES_PATH = fileURLToPath(new URL(`./rules/${RULES_FILENAME}`, import.meta.url));
6
+ const MAX_EVIDENCE_LENGTH = 160;
7
+ function parseRegexLiteral(literal) {
8
+ const trimmed = literal.trim();
9
+ const match = /^\/([\s\S]*)\/([a-z]*)$/i.exec(trimmed);
10
+ if (!match) {
11
+ throw new Error(`Invalid regex literal "${literal}"`);
12
+ }
13
+ const [, source, flags] = match;
14
+ return new RegExp(source, flags);
15
+ }
16
+ function resolveRulesPath() {
17
+ const overridePath = process.env.DARE_GUARD_SCAN_RULES_PATH?.trim();
18
+ if (!overridePath)
19
+ return DEFAULT_RULES_PATH;
20
+ return resolve(overridePath);
21
+ }
22
+ function loadRulesFile() {
23
+ const rulesPath = resolveRulesPath();
24
+ const raw = readFileSync(rulesPath, 'utf8');
25
+ const parsed = JSON.parse(raw);
26
+ if (typeof parsed !== 'object' || parsed === null) {
27
+ throw new Error(`Invalid scan rules at "${rulesPath}"`);
28
+ }
29
+ const rec = parsed;
30
+ if (!Array.isArray(rec.rules)) {
31
+ throw new Error(`Invalid scan rules at "${rulesPath}"`);
32
+ }
33
+ return {
34
+ version: typeof rec.version === 'number' ? rec.version : 0,
35
+ rules: rec.rules,
36
+ };
37
+ }
38
+ function compileRules(file) {
39
+ return file.rules.map((rule) => {
40
+ if (typeof rule.id !== 'string' ||
41
+ typeof rule.description !== 'string' ||
42
+ !Array.isArray(rule.regex)) {
43
+ throw new Error('Invalid scan rule definition');
44
+ }
45
+ return {
46
+ id: rule.id,
47
+ description: rule.description,
48
+ patterns: rule.regex.map((literal) => parseRegexLiteral(literal)),
49
+ };
50
+ });
51
+ }
52
+ function sanitizeEvidence(evidence) {
53
+ const collapsed = evidence.replace(/\s+/g, ' ').trim();
54
+ const redacted = collapsed.replace(/\b[A-Za-z0-9_=-]{16,}\b/g, '[REDACTED]');
55
+ if (redacted.length <= MAX_EVIDENCE_LENGTH)
56
+ return redacted;
57
+ return `${redacted.slice(0, MAX_EVIDENCE_LENGTH)}...`;
58
+ }
59
+ /**
60
+ * Heurística best-effort (camada 2): um achado isolado é sempre WARN.
61
+ */
62
+ export function scanHeuristics(content) {
63
+ if (!content)
64
+ return [];
65
+ const rules = compileRules(loadRulesFile());
66
+ const findings = [];
67
+ for (const rule of rules) {
68
+ for (const pattern of rule.patterns) {
69
+ pattern.lastIndex = 0;
70
+ const match = pattern.exec(content);
71
+ if (!match)
72
+ continue;
73
+ findings.push({
74
+ layer: 'scan',
75
+ severity: 'WARN',
76
+ rule: rule.id,
77
+ evidence: sanitizeEvidence(match[0]),
78
+ });
79
+ break;
80
+ }
81
+ }
82
+ return findings;
83
+ }
84
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/guard/scan.ts"],"names":[],"mappings":"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"}