@peac/cli 0.10.0 → 0.10.10

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 (57) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +78 -5
  3. package/dist/commands/conformance.d.ts +16 -0
  4. package/dist/commands/conformance.d.ts.map +1 -0
  5. package/dist/commands/samples.d.ts +17 -0
  6. package/dist/commands/samples.d.ts.map +1 -0
  7. package/dist/index.cjs +2257 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.mjs +2236 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/dist/lib/conformance/digest.d.ts +64 -0
  12. package/dist/lib/conformance/digest.d.ts.map +1 -0
  13. package/dist/lib/conformance/index.d.ts +11 -0
  14. package/dist/lib/conformance/index.d.ts.map +1 -0
  15. package/dist/lib/conformance/manifest.d.ts +15 -0
  16. package/dist/lib/conformance/manifest.d.ts.map +1 -0
  17. package/dist/lib/conformance/profiles.d.ts +33 -0
  18. package/dist/lib/conformance/profiles.d.ts.map +1 -0
  19. package/dist/lib/conformance/types.d.ts +186 -0
  20. package/dist/lib/conformance/types.d.ts.map +1 -0
  21. package/dist/lib/conformance/validators.d.ts +27 -0
  22. package/dist/lib/conformance/validators.d.ts.map +1 -0
  23. package/dist/lib/conformance-runner.d.ts +29 -0
  24. package/dist/lib/conformance-runner.d.ts.map +1 -0
  25. package/dist/lib/samples-loader.d.ts +44 -0
  26. package/dist/lib/samples-loader.d.ts.map +1 -0
  27. package/dist/lib/version.d.ts +22 -0
  28. package/dist/lib/version.d.ts.map +1 -0
  29. package/package.json +27 -13
  30. package/dist/cli.js +0 -90
  31. package/dist/cli.js.map +0 -1
  32. package/dist/commands/bridge/index.js +0 -20
  33. package/dist/commands/bridge/index.js.map +0 -1
  34. package/dist/commands/bridge/install.js +0 -27
  35. package/dist/commands/bridge/install.js.map +0 -1
  36. package/dist/commands/bridge/start.js +0 -123
  37. package/dist/commands/bridge/start.js.map +0 -1
  38. package/dist/commands/bridge/status.js +0 -192
  39. package/dist/commands/bridge/status.js.map +0 -1
  40. package/dist/commands/bridge/stop.js +0 -130
  41. package/dist/commands/bridge/stop.js.map +0 -1
  42. package/dist/commands/bundle.js +0 -363
  43. package/dist/commands/bundle.js.map +0 -1
  44. package/dist/commands/discover.js +0 -39
  45. package/dist/commands/discover.js.map +0 -1
  46. package/dist/commands/hash.js +0 -106
  47. package/dist/commands/hash.js.map +0 -1
  48. package/dist/commands/policy.js +0 -712
  49. package/dist/commands/policy.js.map +0 -1
  50. package/dist/commands/verify.js +0 -50
  51. package/dist/commands/verify.js.map +0 -1
  52. package/dist/index.js +0 -217
  53. package/dist/index.js.map +0 -1
  54. package/dist/types.js +0 -6
  55. package/dist/types.js.map +0 -1
  56. package/dist/utils.js +0 -101
  57. package/dist/utils.js.map +0 -1
@@ -1,712 +0,0 @@
1
- "use strict";
2
- /**
3
- * PEAC Policy CLI Commands
4
- *
5
- * Commands for managing policy files:
6
- * - init: Create a new policy file
7
- * - validate: Validate policy syntax and schema
8
- * - explain: Debug rule matching
9
- * - generate: Compile policy to deployment artifacts
10
- * - list-profiles: List available policy profiles (v0.9.23+)
11
- * - show-profile: Show profile details (v0.9.23+)
12
- *
13
- * Automation flags (v0.9.23+):
14
- * - --json: Machine-readable JSON output
15
- * - --yes: Skip confirmation prompts (auto-confirm)
16
- * - --strict: Exit non-zero on warnings
17
- */
18
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- var desc = Object.getOwnPropertyDescriptor(m, k);
21
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
- desc = { enumerable: true, get: function() { return m[k]; } };
23
- }
24
- Object.defineProperty(o, k2, desc);
25
- }) : (function(o, m, k, k2) {
26
- if (k2 === undefined) k2 = k;
27
- o[k2] = m[k];
28
- }));
29
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
- Object.defineProperty(o, "default", { enumerable: true, value: v });
31
- }) : function(o, v) {
32
- o["default"] = v;
33
- });
34
- var __importStar = (this && this.__importStar) || (function () {
35
- var ownKeys = function(o) {
36
- ownKeys = Object.getOwnPropertyNames || function (o) {
37
- var ar = [];
38
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
39
- return ar;
40
- };
41
- return ownKeys(o);
42
- };
43
- return function (mod) {
44
- if (mod && mod.__esModule) return mod;
45
- var result = {};
46
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
47
- __setModuleDefault(result, mod);
48
- return result;
49
- };
50
- })();
51
- Object.defineProperty(exports, "__esModule", { value: true });
52
- exports.policy = void 0;
53
- const commander_1 = require("commander");
54
- const fs = __importStar(require("fs"));
55
- const path = __importStar(require("path"));
56
- const policy_kit_1 = require("@peac/policy-kit");
57
- /**
58
- * Get global options from parent command
59
- */
60
- function getGlobalOptions(cmd) {
61
- const parent = cmd.parent;
62
- if (!parent)
63
- return {};
64
- return parent.opts();
65
- }
66
- /**
67
- * Output result - handles JSON vs human-readable format
68
- */
69
- function output(data, opts, humanMessage) {
70
- if (opts.json) {
71
- console.log(JSON.stringify(data, null, 2));
72
- }
73
- else if (humanMessage) {
74
- console.log(humanMessage);
75
- }
76
- }
77
- /**
78
- * Output error - handles JSON vs human-readable format
79
- */
80
- function outputError(error, details, opts) {
81
- if (opts.json) {
82
- console.log(JSON.stringify({ success: false, error, ...details }, null, 2));
83
- }
84
- else {
85
- console.error(`Error: ${error}`);
86
- }
87
- }
88
- const policy = new commander_1.Command('policy')
89
- .description('Policy file operations')
90
- .option('--json', 'Output in machine-readable JSON format')
91
- .option('--yes', 'Skip confirmation prompts (auto-confirm)')
92
- .option('--strict', 'Exit non-zero on warnings');
93
- exports.policy = policy;
94
- /**
95
- * peac policy init
96
- *
97
- * Create a new peac-policy.yaml file in the current directory.
98
- */
99
- policy
100
- .command('init')
101
- .description('Create a new PEAC policy file')
102
- .option('-f, --format <format>', 'Output format (yaml or json)', 'yaml')
103
- .option('-o, --output <file>', 'Output file path')
104
- .option('--force', 'Overwrite existing file')
105
- .option('--profile <id>', 'Use a pre-built profile as template')
106
- .action((options, cmd) => {
107
- const globalOpts = getGlobalOptions(cmd);
108
- try {
109
- const format = options.format?.toLowerCase() || 'yaml';
110
- const outputPath = options.output || (format === 'json' ? 'peac-policy.json' : 'peac-policy.yaml');
111
- // Check if file exists and --force/--yes not set
112
- if (fs.existsSync(outputPath) && !options.force && !globalOpts.yes) {
113
- outputError(`File already exists: ${outputPath}`, { path: outputPath, hint: 'Use --force or --yes to overwrite' }, globalOpts);
114
- process.exit(1);
115
- }
116
- let content;
117
- let policyName;
118
- if (options.profile) {
119
- // Use profile as template
120
- try {
121
- const profile = (0, policy_kit_1.loadProfile)(options.profile);
122
- const policyDoc = profile.policy;
123
- content =
124
- format === 'json' ? (0, policy_kit_1.serializePolicyJson)(policyDoc) : (0, policy_kit_1.serializePolicyYaml)(policyDoc);
125
- policyName = profile.name;
126
- }
127
- catch (err) {
128
- if (err instanceof policy_kit_1.ProfileError) {
129
- outputError(err.message, { code: err.code, profile: options.profile }, globalOpts);
130
- process.exit(1);
131
- }
132
- throw err;
133
- }
134
- }
135
- else {
136
- const example = (0, policy_kit_1.createExamplePolicy)();
137
- content = format === 'json' ? (0, policy_kit_1.serializePolicyJson)(example) : (0, policy_kit_1.serializePolicyYaml)(example);
138
- policyName = 'Example Policy';
139
- }
140
- fs.writeFileSync(outputPath, content, 'utf-8');
141
- if (globalOpts.json) {
142
- output({
143
- success: true,
144
- file: outputPath,
145
- format,
146
- profile: options.profile || null,
147
- policyName,
148
- }, globalOpts);
149
- }
150
- else {
151
- console.log(`Created policy file: ${outputPath}`);
152
- if (options.profile) {
153
- console.log(`Based on profile: ${options.profile}`);
154
- }
155
- console.log('');
156
- console.log('Next steps:');
157
- console.log(' 1. Edit the policy file to define your access rules');
158
- console.log(' 2. Validate with: peac policy validate ' + outputPath);
159
- console.log(' 3. Generate artifacts with: peac policy generate ' + outputPath);
160
- }
161
- process.exit(0);
162
- }
163
- catch (err) {
164
- outputError(err instanceof Error ? err.message : String(err), {}, globalOpts);
165
- process.exit(1);
166
- }
167
- });
168
- /**
169
- * peac policy validate <file>
170
- */
171
- policy
172
- .command('validate')
173
- .description('Validate a PEAC policy file (YAML or JSON)')
174
- .argument('<file>', 'Path to policy file')
175
- .option('-v, --verbose', 'Show detailed validation output')
176
- .action((file, options, cmd) => {
177
- const globalOpts = getGlobalOptions(cmd);
178
- const warnings = [];
179
- try {
180
- const policyDoc = (0, policy_kit_1.loadPolicy)(file);
181
- // Collect any warnings (e.g., deprecated features)
182
- // Currently no warnings defined, but this is the pattern for future use
183
- const result = {
184
- success: true,
185
- file,
186
- valid: true,
187
- warnings,
188
- policy: {
189
- version: policyDoc.version,
190
- name: policyDoc.name || null,
191
- defaultDecision: policyDoc.defaults.decision,
192
- ruleCount: policyDoc.rules.length,
193
- rules: options.verbose
194
- ? policyDoc.rules.map((r) => ({
195
- name: r.name,
196
- decision: r.decision,
197
- subject: r.subject || null,
198
- purpose: r.purpose || null,
199
- licensingMode: r.licensing_mode || null,
200
- }))
201
- : undefined,
202
- },
203
- };
204
- if (globalOpts.json) {
205
- output(result, globalOpts);
206
- }
207
- else {
208
- console.log(`Validating policy file: ${file}\n`);
209
- console.log('Policy is valid!\n');
210
- console.log('Policy Information:');
211
- console.log(` Version: ${policyDoc.version}`);
212
- if (policyDoc.name) {
213
- console.log(` Name: ${policyDoc.name}`);
214
- }
215
- console.log(` Default: ${policyDoc.defaults.decision}`);
216
- console.log(` Rules: ${policyDoc.rules.length}`);
217
- if (options.verbose && policyDoc.rules.length > 0) {
218
- console.log('\nRules:');
219
- for (const rule of policyDoc.rules) {
220
- console.log(` - ${rule.name}: ${rule.decision}`);
221
- if (rule.subject) {
222
- const parts = [];
223
- if (rule.subject.type) {
224
- const types = Array.isArray(rule.subject.type)
225
- ? rule.subject.type.join('|')
226
- : rule.subject.type;
227
- parts.push(`type=${types}`);
228
- }
229
- if (rule.subject.labels) {
230
- parts.push(`labels=[${rule.subject.labels.join(',')}]`);
231
- }
232
- if (rule.subject.id) {
233
- parts.push(`id=${rule.subject.id}`);
234
- }
235
- if (parts.length > 0) {
236
- console.log(` subject: ${parts.join(', ')}`);
237
- }
238
- }
239
- if (rule.purpose) {
240
- const purposes = Array.isArray(rule.purpose) ? rule.purpose.join('|') : rule.purpose;
241
- console.log(` purpose: ${purposes}`);
242
- }
243
- if (rule.licensing_mode) {
244
- const modes = Array.isArray(rule.licensing_mode)
245
- ? rule.licensing_mode.join('|')
246
- : rule.licensing_mode;
247
- console.log(` licensing_mode: ${modes}`);
248
- }
249
- }
250
- }
251
- if (warnings.length > 0) {
252
- console.log('\nWarnings:');
253
- for (const warning of warnings) {
254
- console.log(` - ${warning}`);
255
- }
256
- }
257
- }
258
- // Exit with non-zero if --strict and there are warnings
259
- if (globalOpts.strict && warnings.length > 0) {
260
- process.exit(1);
261
- }
262
- process.exit(0);
263
- }
264
- catch (err) {
265
- if (err instanceof policy_kit_1.PolicyValidationError) {
266
- const issues = err.issues.map((i) => ({
267
- path: i.path.join('.'),
268
- message: i.message,
269
- }));
270
- if (globalOpts.json) {
271
- output({
272
- success: false,
273
- file,
274
- valid: false,
275
- error: 'Validation failed',
276
- issues,
277
- }, globalOpts);
278
- }
279
- else {
280
- console.error('Policy validation failed:\n');
281
- for (const issue of err.issues) {
282
- console.error(` - ${issue.path.join('.')}: ${issue.message}`);
283
- }
284
- }
285
- process.exit(1);
286
- }
287
- else if (err instanceof policy_kit_1.PolicyLoadError) {
288
- outputError(`Failed to load policy: ${err.message}`, { file }, globalOpts);
289
- process.exit(1);
290
- }
291
- else {
292
- outputError(err instanceof Error ? err.message : String(err), {}, globalOpts);
293
- process.exit(1);
294
- }
295
- }
296
- });
297
- /**
298
- * peac policy generate <file>
299
- *
300
- * Generate deployment artifacts from a policy file:
301
- * - peac.txt (PEAC discovery file)
302
- * - robots.txt snippet
303
- * - AIPREF header templates
304
- * - ai-policy.md (human-readable summary)
305
- */
306
- policy
307
- .command('generate')
308
- .description('Generate deployment artifacts from a policy file')
309
- .argument('<file>', 'Path to policy file')
310
- .option('-o, --out <dir>', 'Output directory (use "-" for stdout)', 'dist')
311
- .option('--well-known', 'Output peac.txt to .well-known/ subdirectory')
312
- .option('--dry-run', 'Show what would be generated without writing files')
313
- .option('--peac-version <version>', 'PEAC protocol version (default: 0.9)')
314
- .option('--site-url <url>', 'Site URL for peac.txt')
315
- .option('--contact <email>', 'Contact email for policy questions')
316
- .option('--attribution <mode>', 'Attribution requirement (required, optional, none)')
317
- .option('--receipts <mode>', 'Receipts requirement (required, optional, omit)')
318
- .option('--rate-limit <limit>', 'Rate limit string (e.g., "100/hour", "unlimited")')
319
- .option('--negotiate <url>', 'Negotiate endpoint URL')
320
- .option('--no-comments', 'Omit comments from generated files')
321
- .action((file, options, cmd) => {
322
- const globalOpts = getGlobalOptions(cmd);
323
- const isStdout = options.out === '-';
324
- try {
325
- if (!globalOpts.json && !isStdout) {
326
- console.log(`Loading policy: ${file}\n`);
327
- }
328
- const policyDoc = (0, policy_kit_1.loadPolicy)(file);
329
- const compileOptions = {
330
- peacVersion: options.peacVersion,
331
- siteUrl: options.siteUrl,
332
- contact: options.contact,
333
- attribution: options.attribution,
334
- receipts: options.receipts,
335
- rateLimit: options.rateLimit,
336
- negotiateUrl: options.negotiate,
337
- includeComments: options.comments !== false,
338
- };
339
- // Generate content
340
- const peacTxt = (0, policy_kit_1.compilePeacTxt)(policyDoc, compileOptions);
341
- const robotsTxt = (0, policy_kit_1.compileRobotsSnippet)(policyDoc, compileOptions);
342
- const aiprefTemplates = (0, policy_kit_1.compileAiprefTemplates)(policyDoc, compileOptions);
343
- const markdown = (0, policy_kit_1.renderPolicyMarkdown)(policyDoc, compileOptions);
344
- // Stdout mode: output all content as JSON
345
- if (isStdout || globalOpts.json) {
346
- const result = {
347
- success: true,
348
- source: file,
349
- artifacts: {
350
- 'peac.txt': peacTxt,
351
- 'robots-ai-snippet.txt': robotsTxt,
352
- 'aipref-headers.json': aiprefTemplates,
353
- 'ai-policy.md': markdown,
354
- },
355
- };
356
- if (isStdout && !globalOpts.json) {
357
- // Plain stdout: just output peac.txt
358
- console.log(peacTxt);
359
- }
360
- else {
361
- output(result, { json: true });
362
- }
363
- process.exit(0);
364
- }
365
- // Determine output paths
366
- const outDir = options.out;
367
- let peacTxtPath;
368
- if (options.wellKnown) {
369
- peacTxtPath = path.join(outDir, '.well-known', 'peac.txt');
370
- }
371
- else {
372
- peacTxtPath = path.join(outDir, 'peac.txt');
373
- }
374
- const robotsPath = path.join(outDir, 'robots-ai-snippet.txt');
375
- const aiprefPath = path.join(outDir, 'aipref-headers.json');
376
- const mdPath = path.join(outDir, 'ai-policy.md');
377
- if (options.dryRun) {
378
- // Dry run: show what would be generated
379
- console.log('Dry run - files that would be generated:\n');
380
- console.log(`--- ${peacTxtPath} ---`);
381
- console.log(peacTxt);
382
- console.log(`--- ${robotsPath} ---`);
383
- console.log(robotsTxt);
384
- console.log(`--- ${aiprefPath} ---`);
385
- console.log(JSON.stringify(aiprefTemplates, null, 2));
386
- console.log(`\n--- ${mdPath} ---`);
387
- console.log(markdown);
388
- process.exit(0);
389
- }
390
- // Create output directories
391
- if (!fs.existsSync(outDir)) {
392
- fs.mkdirSync(outDir, { recursive: true });
393
- }
394
- if (options.wellKnown) {
395
- const wellKnownDir = path.join(outDir, '.well-known');
396
- if (!fs.existsSync(wellKnownDir)) {
397
- fs.mkdirSync(wellKnownDir, { recursive: true });
398
- }
399
- }
400
- // Write files
401
- fs.writeFileSync(peacTxtPath, peacTxt, 'utf-8');
402
- console.log(`Generated: ${peacTxtPath}`);
403
- fs.writeFileSync(robotsPath, robotsTxt, 'utf-8');
404
- console.log(`Generated: ${robotsPath}`);
405
- fs.writeFileSync(aiprefPath, JSON.stringify(aiprefTemplates, null, 2), 'utf-8');
406
- console.log(`Generated: ${aiprefPath}`);
407
- fs.writeFileSync(mdPath, markdown, 'utf-8');
408
- console.log(`Generated: ${mdPath}`);
409
- console.log('');
410
- console.log('Deployment instructions:');
411
- if (options.wellKnown) {
412
- console.log(` 1. Deploy ${peacTxtPath} to serve at /.well-known/peac.txt`);
413
- }
414
- else {
415
- console.log(` 1. Copy ${peacTxtPath} to /.well-known/peac.txt`);
416
- }
417
- console.log(` 2. Append ${robotsPath} to your robots.txt`);
418
- console.log(` 3. Add headers from ${aiprefPath} to your server config`);
419
- console.log(` 4. Publish ${mdPath} for human reference`);
420
- process.exit(0);
421
- }
422
- catch (err) {
423
- if (err instanceof policy_kit_1.PolicyLoadError) {
424
- outputError(`Failed to load policy: ${err.message}`, { file }, globalOpts);
425
- process.exit(1);
426
- }
427
- else {
428
- outputError(err instanceof Error ? err.message : String(err), {}, globalOpts);
429
- process.exit(1);
430
- }
431
- }
432
- });
433
- /**
434
- * peac policy explain <file>
435
- *
436
- * Debug tool: explain which rule would apply for a given context.
437
- */
438
- policy
439
- .command('explain')
440
- .description('Explain which rule would apply for a given context')
441
- .argument('<file>', 'Path to policy file')
442
- .option('-t, --type <type>', 'Subject type (human, org, agent)')
443
- .option('-l, --labels <labels>', 'Subject labels (comma-separated)')
444
- .option('-i, --id <id>', 'Subject ID')
445
- .option('-p, --purpose <purpose>', 'Access purpose (crawl, index, train, inference, ai_input, ai_index, search)')
446
- .option('-m, --licensing-mode <mode>', 'Licensing mode (subscription, pay_per_crawl, pay_per_inference)')
447
- .option('--all-matches', 'Show all matching rules, not just the first')
448
- .action((file, options, cmd) => {
449
- const globalOpts = getGlobalOptions(cmd);
450
- try {
451
- const policyDoc = (0, policy_kit_1.loadPolicy)(file);
452
- // Build evaluation context from options
453
- const context = {};
454
- if (options.type || options.labels || options.id) {
455
- context.subject = {};
456
- if (options.type) {
457
- context.subject.type = options.type;
458
- }
459
- if (options.labels) {
460
- context.subject.labels = options.labels.split(',').map((l) => l.trim());
461
- }
462
- if (options.id) {
463
- context.subject.id = options.id;
464
- }
465
- }
466
- if (options.purpose) {
467
- context.purpose = options.purpose;
468
- }
469
- if (options.licensingMode) {
470
- context.licensing_mode = options.licensingMode;
471
- }
472
- if (options.allMatches) {
473
- const matches = (0, policy_kit_1.explainMatches)(policyDoc, context);
474
- if (globalOpts.json) {
475
- output({
476
- success: true,
477
- context,
478
- matches: matches.map((m) => {
479
- if (m === '[default]') {
480
- return {
481
- rule: '[default]',
482
- decision: policyDoc.defaults.decision,
483
- };
484
- }
485
- const rule = policyDoc.rules.find((r) => r.name === m);
486
- return rule
487
- ? { rule: rule.name, decision: rule.decision }
488
- : { rule: m, decision: null };
489
- }),
490
- }, globalOpts);
491
- }
492
- else {
493
- console.log('Evaluation Context:');
494
- if (context.subject) {
495
- console.log(` Subject: ${JSON.stringify(context.subject)}`);
496
- }
497
- else {
498
- console.log(' Subject: (any)');
499
- }
500
- console.log(` Purpose: ${context.purpose || '(any)'}`);
501
- console.log(` Licensing Mode: ${context.licensing_mode || '(any)'}`);
502
- console.log();
503
- console.log(`Matching Rules (${matches.length}):`);
504
- for (const match of matches) {
505
- if (match === '[default]') {
506
- console.log(` - [default] -> ${policyDoc.defaults.decision}`);
507
- }
508
- else {
509
- const rule = policyDoc.rules.find((r) => r.name === match);
510
- if (rule) {
511
- console.log(` - ${rule.name} -> ${rule.decision}`);
512
- }
513
- }
514
- }
515
- }
516
- }
517
- else {
518
- const result = (0, policy_kit_1.evaluate)(policyDoc, context);
519
- if (globalOpts.json) {
520
- output({
521
- success: true,
522
- context,
523
- result: {
524
- decision: result.decision,
525
- matchedRule: result.matched_rule || '[default]',
526
- reason: result.reason || null,
527
- },
528
- }, globalOpts);
529
- }
530
- else {
531
- console.log('Evaluation Context:');
532
- if (context.subject) {
533
- console.log(` Subject: ${JSON.stringify(context.subject)}`);
534
- }
535
- else {
536
- console.log(' Subject: (any)');
537
- }
538
- console.log(` Purpose: ${context.purpose || '(any)'}`);
539
- console.log(` Licensing Mode: ${context.licensing_mode || '(any)'}`);
540
- console.log();
541
- console.log('Result:');
542
- console.log(` Decision: ${result.decision}`);
543
- if (result.matched_rule) {
544
- console.log(` Matched Rule: ${result.matched_rule}`);
545
- }
546
- else {
547
- console.log(' Matched Rule: (default)');
548
- }
549
- if (result.reason) {
550
- console.log(` Reason: ${result.reason}`);
551
- }
552
- }
553
- }
554
- process.exit(0);
555
- }
556
- catch (err) {
557
- if (err instanceof policy_kit_1.PolicyLoadError) {
558
- outputError(`Failed to load policy: ${err.message}`, { file }, globalOpts);
559
- process.exit(1);
560
- }
561
- else {
562
- outputError(err instanceof Error ? err.message : String(err), {}, globalOpts);
563
- process.exit(1);
564
- }
565
- }
566
- });
567
- /**
568
- * peac policy list-profiles
569
- *
570
- * List available pre-built policy profiles (v0.9.23+)
571
- */
572
- policy
573
- .command('list-profiles')
574
- .description('List available pre-built policy profiles')
575
- .action((options, cmd) => {
576
- const globalOpts = getGlobalOptions(cmd);
577
- try {
578
- const profileIds = (0, policy_kit_1.listProfiles)();
579
- const profiles = profileIds.map((id) => (0, policy_kit_1.getProfileSummary)(id));
580
- if (globalOpts.json) {
581
- output({
582
- success: true,
583
- profiles: profiles.map((p) => ({
584
- id: p.id,
585
- name: p.name,
586
- description: p.description,
587
- defaultDecision: p.defaultDecision,
588
- ruleCount: p.ruleCount,
589
- requiresReceipt: p.requiresReceipt,
590
- requiredParams: p.requiredParams,
591
- optionalParams: p.optionalParams,
592
- })),
593
- }, globalOpts);
594
- }
595
- else {
596
- console.log('Available Policy Profiles:\n');
597
- for (const profile of profiles) {
598
- console.log(` ${profile.id}`);
599
- console.log(` Name: ${profile.name}`);
600
- console.log(` Default: ${profile.defaultDecision}`);
601
- console.log(` Rules: ${profile.ruleCount}`);
602
- if (profile.requiresReceipt) {
603
- console.log(' Requires receipt: yes');
604
- }
605
- if (profile.requiredParams.length > 0) {
606
- console.log(` Required params: ${profile.requiredParams.join(', ')}`);
607
- }
608
- console.log();
609
- }
610
- console.log('Use "peac policy show-profile <id>" for full details');
611
- console.log('Use "peac policy init --profile <id>" to create a policy from a profile');
612
- }
613
- process.exit(0);
614
- }
615
- catch (err) {
616
- outputError(err instanceof Error ? err.message : String(err), {}, globalOpts);
617
- process.exit(1);
618
- }
619
- });
620
- /**
621
- * peac policy show-profile <id>
622
- *
623
- * Show details of a specific profile (v0.9.23+)
624
- */
625
- policy
626
- .command('show-profile')
627
- .description('Show details of a specific policy profile')
628
- .argument('<id>', 'Profile ID')
629
- .action((id, options, cmd) => {
630
- const globalOpts = getGlobalOptions(cmd);
631
- try {
632
- const profile = (0, policy_kit_1.loadProfile)(id);
633
- const summary = (0, policy_kit_1.getProfileSummary)(id);
634
- if (globalOpts.json) {
635
- output({
636
- success: true,
637
- profile: {
638
- id: profile.id,
639
- name: profile.name,
640
- description: profile.description,
641
- policy: profile.policy,
642
- parameters: profile.parameters,
643
- defaults: profile.defaults,
644
- },
645
- }, globalOpts);
646
- }
647
- else {
648
- console.log(`Profile: ${profile.name}`);
649
- console.log(`ID: ${profile.id}`);
650
- console.log();
651
- console.log('Description:');
652
- console.log(profile.description
653
- .split('\n')
654
- .map((l) => ` ${l}`)
655
- .join('\n'));
656
- console.log();
657
- console.log('Policy:');
658
- console.log(` Version: ${profile.policy.version}`);
659
- console.log(` Default decision: ${profile.policy.defaults.decision}`);
660
- console.log(` Rules: ${profile.policy.rules?.length || 0}`);
661
- if (profile.policy.rules && profile.policy.rules.length > 0) {
662
- console.log();
663
- console.log('Rules:');
664
- for (const rule of profile.policy.rules) {
665
- console.log(` - ${rule.name}: ${rule.decision}`);
666
- if (rule.purpose) {
667
- const purposes = Array.isArray(rule.purpose) ? rule.purpose.join(', ') : rule.purpose;
668
- console.log(` purpose: ${purposes}`);
669
- }
670
- if (rule.reason) {
671
- console.log(` reason: ${rule.reason}`);
672
- }
673
- }
674
- }
675
- if (Object.keys(profile.parameters || {}).length > 0) {
676
- console.log();
677
- console.log('Parameters:');
678
- for (const [key, param] of Object.entries(profile.parameters || {})) {
679
- const required = param.required ? ' (required)' : '';
680
- console.log(` ${key}${required}`);
681
- console.log(` ${param.description}`);
682
- if (param.default) {
683
- console.log(` Default: ${param.default}`);
684
- }
685
- if (param.example) {
686
- console.log(` Example: ${param.example}`);
687
- }
688
- }
689
- }
690
- if (profile.defaults) {
691
- console.log();
692
- console.log('Defaults:');
693
- if (profile.defaults.requirements?.receipt) {
694
- console.log(' Receipt required: yes');
695
- }
696
- if (profile.defaults.rate_limit) {
697
- console.log(` Rate limit: ${profile.defaults.rate_limit.limit}/${profile.defaults.rate_limit.window_seconds}s`);
698
- }
699
- }
700
- }
701
- process.exit(0);
702
- }
703
- catch (err) {
704
- if (err instanceof policy_kit_1.ProfileError) {
705
- outputError(err.message, { code: err.code, profile: id }, globalOpts);
706
- process.exit(1);
707
- }
708
- outputError(err instanceof Error ? err.message : String(err), {}, globalOpts);
709
- process.exit(1);
710
- }
711
- });
712
- //# sourceMappingURL=policy.js.map