@dsh-cc/command-permissions 0.8.0-rc.2 → 0.8.1-rc.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAUlD,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,wBAAwB,EACxB,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAErF,eAAO,MAAM,IAAI,wBAAwB,CAAA;AACzC;;;;;GAKG;AACH,eAAO,MAAM,MAAM,UAAe,CAAA;AAqHlC;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAUxC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAalD,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,wBAAwB,EACxB,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAErF,eAAO,MAAM,IAAI,wBAAwB,CAAA;AACzC;;;;;GAKG;AACH,eAAO,MAAM,MAAM,UAAe,CAAA;AA6JlC;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAaxC"}
package/lib/index.js CHANGED
@@ -28,6 +28,9 @@
28
28
  * @module @dsh-cc/command-permissions
29
29
  */
30
30
  import { PERMISSION_COMMAND_MODES } from "./modes.js";
31
+ import { applyUserLint, lintRuleSet, lintUserSection, renderLint } from "./lint.js";
32
+ import { PERMISSION_SETTINGS_NAMESPACE } from '@dsh-cc/permission-rules';
33
+ import { foldPlanMode, foldPermissionMode } from '@dsh-cc/permission-rules';
31
34
  import { planPhaseOf } from "./plan-phase.js";
32
35
  import { renderPermissions } from "./permissions.js";
33
36
  import { helpable } from '@dsh-cc/command-usage';
@@ -45,10 +48,17 @@ export const inject = ['commands'];
45
48
  /** The shared modes list — the switch list and the client popup both read it. */
46
49
  const MODES = PERMISSION_COMMAND_MODES;
47
50
  /** Render the current rule state from a mounted engine. */
48
- function renderState(service) {
51
+ function renderState(service, agent) {
52
+ const merged = service.ruleSet;
53
+ const mode = foldPlanMode(agent?.session.snapshotEvents() ?? [])
54
+ ? 'plan'
55
+ : foldPermissionMode(agent?.session.snapshotEvents() ?? []) ?? service.defaultMode;
56
+ const effective = service.effectiveRuleSet(mode);
49
57
  return {
50
58
  kind: 'success',
51
- text: renderPermissions(service.ruleSet, service.ruleSet.bypassImmune.length),
59
+ text: renderPermissions(effective, service.ruleSet.bypassImmune.length, {
60
+ suspendedAllow: merged.allow.length - effective.allow.length,
61
+ }),
52
62
  };
53
63
  }
54
64
  /**
@@ -69,11 +79,13 @@ async function executePermissions(ctx, invocation) {
69
79
  if (service === undefined) {
70
80
  return { kind: 'success', text: 'The permission-rules engine is not mounted in this composition.' };
71
81
  }
72
- return renderState(service);
82
+ return renderState(service, invocation.agent);
73
83
  }
74
84
  if (service === undefined) {
75
85
  return { kind: 'error', text: 'The permission-rules engine is not mounted in this composition.' };
76
86
  }
87
+ if (raw === 'lint' || raw.startsWith('lint '))
88
+ return executeLint(ctx, raw);
77
89
  const [mode = ''] = raw.split(/\s+/);
78
90
  if (!MODES.includes(mode)) {
79
91
  return { kind: 'error', text: `unknown permission mode "${mode}"; available: ${MODES.join(', ')}` };
@@ -112,8 +124,36 @@ async function executePermissions(ctx, invocation) {
112
124
  return { kind: 'error', text: error instanceof Error ? error.message : String(error) };
113
125
  }
114
126
  }
115
- /** Whether this session selected the CC agent preset (last `agent-preset/selected` wins, else the creation header). */
116
- function isCcSession(agent) {
127
+ /**
128
+ * Read the raw user-layer `permissions` section from the settings provider's
129
+ * `describe()` descriptors (the raw user file section, never the merged one).
130
+ */
131
+ function userSectionOf(settings) {
132
+ const descriptor = settings
133
+ .describe?.()
134
+ ?.find(entry => String(entry.ns) === String(PERMISSION_SETTINGS_NAMESPACE));
135
+ return descriptor !== undefined && descriptor.user !== null && typeof descriptor.user === 'object'
136
+ ? descriptor.user
137
+ : {};
138
+ }
139
+ /**
140
+ * Execute `/permissions lint [--apply]`. Read-only by default; `--apply`
141
+ * performs only the user-layer cleanup through `editUserSection`.
142
+ */
143
+ async function executeLint(ctx, raw) {
144
+ const service = ctx.get('permissionRules');
145
+ if (service === undefined) {
146
+ return { kind: 'error', text: 'The permission-rules engine is not mounted in this composition.' };
147
+ }
148
+ const settings = ctx.get('settings');
149
+ const userLint = settings === undefined ? undefined : lintUserSection(userSectionOf(settings));
150
+ const report = renderLint(lintRuleSet(service.ruleSet), userLint);
151
+ if (!raw.includes('--apply'))
152
+ return { kind: 'success', text: report };
153
+ const result = await applyUserLint(settings);
154
+ return { kind: 'success', text: `${report}\n${result}` };
155
+ }
156
+ /** Whether this session selected the CC agent preset (last `agent-preset/selected` wins, else the creation header). */ function isCcSession(agent) {
117
157
  const events = agent.session.snapshotEvents();
118
158
  for (let index = events.length - 1; index >= 0; index -= 1) {
119
159
  const event = events[index];
@@ -158,10 +198,13 @@ export function apply(ctx) {
158
198
  ctx.commands.register(helpable({
159
199
  name: 'permissions',
160
200
  description: 'show or switch the permission mode (default|acceptEdits|plan|auto|bypassPermissions)',
161
- input: { hint: '[mode]' },
201
+ input: { hint: '[mode|lint [--apply]]' },
162
202
  handler: (invocation) => executePermissions(ctx, invocation),
163
203
  }, {
164
- subcommands: PERMISSION_MODE_OPTIONS.map(option => ({ word: option.id, summary: option.detail })),
204
+ subcommands: [
205
+ ...PERMISSION_MODE_OPTIONS.map(option => ({ word: option.id, summary: option.detail })),
206
+ { word: 'lint', summary: 'report rule-hygiene findings; --apply cleans the user layer' },
207
+ ],
165
208
  }));
166
209
  if (ctx.get('agent') === undefined)
167
210
  installCatalogWrap(ctx);
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAMH,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACnF,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,EAAE,WAAW,EAA0C,MAAM,iBAAiB,CAAA;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAEpD,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,wBAAwB,EACxB,uBAAuB,GAGxB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAA0C,MAAM,iBAAiB,CAAA;AAErF,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAA;AACzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,CAAA;AAWlC,iFAAiF;AACjF,MAAM,KAAK,GAAG,wBAAwB,CAAA;AAEtC,2DAA2D;AAC3D,SAAS,WAAW,CAAC,OAA4B,EAAE,KAAa;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,OAA0D,CAAA;IACjF,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;QAC9D,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,CAAC,WAAW,CAAA;IACpF,MAAM,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAChD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,iBAAiB,CAAC,SAAkB,EAAE,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE;YAC/E,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM;SAC7D,CAAC;KACH,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAY,EAAE,KAAY;IAC9C,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAEnC,CAAA;IACb,MAAM,SAAS,GAAG,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAkC,CAAA;IAC9F,OAAO,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,SAAS,CAAC,CAAA;AAC/D,CAAC;AAED,0EAA0E;AAC1E,KAAK,UAAU,kBAAkB,CAAC,GAAY,EAAE,UAA6B;IAC3E,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAoC,CAAA;IAC7E,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;IACtC,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAA;QACrG,CAAC;QACD,OAAO,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,CAAA;IAC/C,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAA;IACnG,CAAC;IACD,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC3E,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACpC,IAAI,CAAE,KAA2B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,4BAA4B,IAAI,iBAAiB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;IACrG,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;IAC9B,IAAI,CAAC;QACH,sEAAsE;QACtE,uEAAuE;QACvE,oEAAoE;QACpE,yEAAyE;QACzE,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,IAAI,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;gBACtC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAA;YACpE,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;YACnF,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,8CAA8C,EAAE,CAAA;YAChF,CAAC;YACD,OAAO,SAAS,CAAC,MAAM,CAAA;QACzB,CAAC;QACD,sEAAsE;QACtE,yEAAyE;QACzE,wEAAwE;QACxE,IAAI,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;YACvF,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,8CAA8C,EAAE,CAAA;YAChF,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,SAAS,CAAC,MAAM,CAAA;QAChE,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC5B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,2BAA2B,IAAI,IAAI,EAAE,CAAA;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;IACxF,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,QAAiB;IACtC,MAAM,UAAU,GAAI,QAAwE;SACzF,QAAQ,EAAE,EAAE;QACb,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAA;IAC7E,OAAO,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QAChG,CAAC,CAAC,UAAU,CAAC,IAA+B;QAC5C,CAAC,CAAC,EAAE,CAAA;AACR,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,WAAW,CAAC,GAAY,EAAE,GAAW;IAClD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAoC,CAAA;IAC7E,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAA;IACnG,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAY,CAAA;IAC/C,MAAM,QAAQ,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC9F,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,OAAgB,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC1E,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IACtE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAA;IAC5C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,MAAM,KAAK,MAAM,EAAE,EAAE,CAAA;AAC1D,CAAC;AAED,uHAAuH,CAAA,SAAS,WAAW,CAAC,KAAY;IACtJ,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,CAAA;IAC7C,KAAK,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAuD,CAAA;QACjF,IAAI,KAAK,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAA;QACzC,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAkC,CAAA;IAC/D,OAAO,MAAM,CAAC,WAAW,KAAK,IAAI,CAAA;AACpC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,GAAY;IACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;IAC7B,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAA;IAClC,MAAM,WAAW,GAAG,SAAS,IAAI,CAAwB,KAAY;QACnE,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAA;QAChE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAA;QAC9D,OAAO,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC7E,CAAC,CAAA;IACD,QAAQ,CAAC,IAAI,GAAG,WAAmC,CAAA;IACnD,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QACpB,QAAQ,CAAC,IAAI,GAAG,YAAY,CAAA;IAC9B,CAAC,EAAE,2DAA2D,CAAC,CAAA;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7B,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,sFAAsF;QACnG,KAAK,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE;QACxC,OAAO,EAAE,CAAC,UAA6B,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC;KAChF,EAAE;QACD,WAAW,EAAE;YACX,GAAG,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACvF,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,6DAA6D,EAAE;SACzF;KACF,CAAC,CAAC,CAAA;IACH,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS;QAAE,kBAAkB,CAAC,GAAG,CAAC,CAAA;AAC7D,CAAC"}
package/lib/lint.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * `/permissions lint` — read-only rule-hygiene report over the permission
3
+ * engine's cross-source rule set, plus a proposed before/after diff for the
4
+ * user settings layer. `--apply` performs ONLY the user-layer cleanup through
5
+ * the settings cascade's `editUserSection` raw-user seam; project/policy/
6
+ * session layers are never written, and removals never cross behavior groups
7
+ * (`ruleSubsumes` requires equal behavior).
8
+ * @module @dsh-cc/command-permissions/lint
9
+ */
10
+ import type { PermissionBehavior, PermissionRuleSet, PermissionRuleSource } from '@dsh-cc/permission-rules/types';
11
+ /** One hygiene finding about a single rule. */
12
+ export interface LintFinding {
13
+ kind: 'malformed' | 'duplicate' | 'subsumed' | 'broad' | 'unknownTool';
14
+ source: PermissionRuleSource;
15
+ behavior: PermissionBehavior;
16
+ toolName: string;
17
+ /** The rule string (raw source string for `malformed`). */
18
+ rule: string;
19
+ detail: string;
20
+ }
21
+ declare const BEHAVIORS: readonly ["allow", "deny", "ask"];
22
+ type ListKey = (typeof BEHAVIORS)[number];
23
+ /**
24
+ * Lint the engine's cross-source rule set: exact duplicates and prefix-subsumed
25
+ * rules within one source+behavior group, bare whole-tool `Bash` allows, and
26
+ * unknown tool names. Read-only — the parsed engine rules carry no raw strings,
27
+ * so malformed strings are reported by the user-layer scan only.
28
+ */
29
+ export declare function lintRuleSet(rules: PermissionRuleSet): LintFinding[];
30
+ /** The user-layer lint result: malformed findings, and the proposed cleanup. */
31
+ export interface UserLayerLint {
32
+ findings: LintFinding[];
33
+ /** Raw user-layer lists as found. */
34
+ before: Partial<Record<ListKey, string[]>>;
35
+ /** Raw user-layer lists after removing duplicates and subsumed entries. */
36
+ after: Partial<Record<ListKey, string[]>>;
37
+ }
38
+ /**
39
+ * Lint the RAW user settings section (rule strings, not engine rules):
40
+ * flags malformed strings (kept — apply never rewrites unparseable entries),
41
+ * and computes the cleaned lists (exact duplicates and same-behavior subsumed
42
+ * entries removed, first/broader kept). Bare `Bash` allows and unknown tool
43
+ * names are flagged but kept.
44
+ */
45
+ export declare function lintUserSection(raw: Record<string, unknown>): UserLayerLint;
46
+ /**
47
+ * Render the lint report: findings grouped by source/behavior, then the
48
+ * proposed user-layer before/after diff (removals marked `-`).
49
+ */
50
+ export declare function renderLint(engineFindings: readonly LintFinding[], userLint: UserLayerLint | undefined): string;
51
+ /**
52
+ * Apply the proposed cleanup to the RAW user layer only, via
53
+ * `editUserSection` (never project/policy/session layers; never across
54
+ * behavior groups — removals come from `ruleSubsumes`, which requires equal
55
+ * behavior). Returns a result message, or `undefined`-error text on
56
+ * degradation.
57
+ */
58
+ export declare function applyUserLint(settings: unknown): Promise<string>;
59
+ export {};
60
+ //# sourceMappingURL=lint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,KAAK,EACV,kBAAkB,EAElB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,gCAAgC,CAAA;AAIvC,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAA;IACtE,MAAM,EAAE,oBAAoB,CAAA;IAC5B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAgBD,QAAA,MAAM,SAAS,mCAAoC,CAAA;AACnD,KAAK,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;AAYzC;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,WAAW,EAAE,CAoCnE;AAED,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,qCAAqC;IACrC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;IAC1C,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;CAC1C;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CA0C3E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,cAAc,EAAE,SAAS,WAAW,EAAE,EAAE,QAAQ,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,CAkC9G;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBtE"}
package/lib/lint.js ADDED
@@ -0,0 +1,210 @@
1
+ /**
2
+ * `/permissions lint` — read-only rule-hygiene report over the permission
3
+ * engine's cross-source rule set, plus a proposed before/after diff for the
4
+ * user settings layer. `--apply` performs ONLY the user-layer cleanup through
5
+ * the settings cascade's `editUserSection` raw-user seam; project/policy/
6
+ * session layers are never written, and removals never cross behavior groups
7
+ * (`ruleSubsumes` requires equal behavior).
8
+ * @module @dsh-cc/command-permissions/lint
9
+ */
10
+ import { PERMISSION_SETTINGS_NAMESPACE, parseRuleSafe, ruleString, ruleSubsumes, } from '@dsh-cc/permission-rules';
11
+ import { SOURCE_PRIORITY } from '@dsh-cc/permission-rules/types';
12
+ import { KNOWN_HARNESS_TOOLS, ccToolAliases } from '@dsh-cc/tools';
13
+ const FINDING_LABEL = {
14
+ malformed: 'malformed (unparseable rule string)',
15
+ duplicate: 'exact duplicate',
16
+ subsumed: 'subsumed by a broader rule in the same source and behavior group',
17
+ broad: 'broad grant (whole-tool allow)',
18
+ unknownTool: 'unknown tool name',
19
+ };
20
+ const BEHAVIORS = ['allow', 'deny', 'ask'];
21
+ /** Whether a tool name is known to the harness or the CC vocabulary. */
22
+ function isKnownTool(toolName) {
23
+ return ccToolAliases(toolName).some(alias => KNOWN_HARNESS_TOOLS.has(alias));
24
+ }
25
+ /** Whether a rule is a bare whole-tool `Bash` allow (a broad persistent grant). */
26
+ function isBroadBashAllow(rule) {
27
+ return rule.behavior === 'allow' && rule.toolName === 'Bash' && rule.content === undefined;
28
+ }
29
+ /**
30
+ * Lint the engine's cross-source rule set: exact duplicates and prefix-subsumed
31
+ * rules within one source+behavior group, bare whole-tool `Bash` allows, and
32
+ * unknown tool names. Read-only — the parsed engine rules carry no raw strings,
33
+ * so malformed strings are reported by the user-layer scan only.
34
+ */
35
+ export function lintRuleSet(rules) {
36
+ const findings = [];
37
+ for (const rule of [...rules.allow, ...rules.deny, ...rules.ask]) {
38
+ if (isBroadBashAllow(rule)) {
39
+ findings.push({ kind: 'broad', source: rule.source, behavior: rule.behavior, toolName: rule.toolName, rule: ruleString(rule.toolName, rule.content), detail: 'whole-tool allow; consider a narrower prefix rule' });
40
+ }
41
+ if (!isKnownTool(rule.toolName)) {
42
+ findings.push({ kind: 'unknownTool', source: rule.source, behavior: rule.behavior, toolName: rule.toolName, rule: ruleString(rule.toolName, rule.content), detail: `tool "${rule.toolName}" matches no harness or CC tool name` });
43
+ }
44
+ }
45
+ // Duplication/subsumption only within one source+behavior group, per tool.
46
+ const groups = new Map();
47
+ for (const rule of [...rules.allow, ...rules.deny, ...rules.ask]) {
48
+ if (rule.content === undefined)
49
+ continue;
50
+ const key = `${rule.source}|${rule.behavior}|${rule.toolName}`;
51
+ const group = groups.get(key);
52
+ if (group === undefined)
53
+ groups.set(key, [rule]);
54
+ else
55
+ group.push(rule);
56
+ }
57
+ for (const group of groups.values()) {
58
+ for (let i = 0; i < group.length; i += 1) {
59
+ for (let j = 0; j < group.length; j += 1) {
60
+ if (i === j)
61
+ continue;
62
+ const a = group[i];
63
+ const b = group[j];
64
+ if (!ruleSubsumes(a, b))
65
+ continue;
66
+ if (a.content === b.content) {
67
+ if (i < j)
68
+ findings.push({ kind: 'duplicate', source: b.source, behavior: b.behavior, toolName: b.toolName, rule: ruleString(b.toolName, b.content), detail: `identical to another ${b.source} ${b.behavior} rule` });
69
+ }
70
+ else {
71
+ findings.push({ kind: 'subsumed', source: b.source, behavior: b.behavior, toolName: b.toolName, rule: ruleString(b.toolName, b.content), detail: `covered by ${ruleString(a.toolName, a.content)}` });
72
+ }
73
+ break;
74
+ }
75
+ }
76
+ }
77
+ return findings;
78
+ }
79
+ /**
80
+ * Lint the RAW user settings section (rule strings, not engine rules):
81
+ * flags malformed strings (kept — apply never rewrites unparseable entries),
82
+ * and computes the cleaned lists (exact duplicates and same-behavior subsumed
83
+ * entries removed, first/broader kept). Bare `Bash` allows and unknown tool
84
+ * names are flagged but kept.
85
+ */
86
+ export function lintUserSection(raw) {
87
+ const findings = [];
88
+ const before = {};
89
+ const after = {};
90
+ for (const behavior of BEHAVIORS) {
91
+ const list = raw[behavior];
92
+ if (!Array.isArray(list))
93
+ continue;
94
+ const strings = list.filter((entry) => typeof entry === 'string');
95
+ before[behavior] = strings;
96
+ const kept = [];
97
+ const keptRules = [];
98
+ for (const entry of strings) {
99
+ const parsed = parseRuleSafe(entry, behavior, 'userSettings');
100
+ if (parsed === undefined) {
101
+ findings.push({ kind: 'malformed', source: 'userSettings', behavior, toolName: '?', rule: entry, detail: 'the rule string does not parse' });
102
+ kept.push(entry);
103
+ continue;
104
+ }
105
+ if (isBroadBashAllow(parsed)) {
106
+ findings.push({ kind: 'broad', source: 'userSettings', behavior, toolName: parsed.toolName, rule: entry, detail: 'whole-tool allow; consider a narrower prefix rule' });
107
+ }
108
+ if (!isKnownTool(parsed.toolName)) {
109
+ findings.push({ kind: 'unknownTool', source: 'userSettings', behavior, toolName: parsed.toolName, rule: entry, detail: `tool "${parsed.toolName}" matches no harness or CC tool name` });
110
+ }
111
+ const cover = keptRules.find(kept => ruleSubsumes(kept, parsed));
112
+ if (cover !== undefined) {
113
+ findings.push({
114
+ kind: parsed.content === cover.content ? 'duplicate' : 'subsumed',
115
+ source: 'userSettings',
116
+ behavior,
117
+ toolName: parsed.toolName,
118
+ rule: entry,
119
+ detail: parsed.content === cover.content ? 'identical to an earlier entry' : `covered by ${ruleString(cover.toolName, cover.content)}`,
120
+ });
121
+ continue;
122
+ }
123
+ kept.push(entry);
124
+ keptRules.push(parsed);
125
+ }
126
+ after[behavior] = kept;
127
+ }
128
+ return { findings, before, after };
129
+ }
130
+ /**
131
+ * Render the lint report: findings grouped by source/behavior, then the
132
+ * proposed user-layer before/after diff (removals marked `-`).
133
+ */
134
+ export function renderLint(engineFindings, userLint) {
135
+ const lines = ['Permission rules lint (read-only)'];
136
+ const all = [...engineFindings, ...(userLint?.findings ?? [])];
137
+ if (all.length === 0) {
138
+ lines.push(' (no findings)');
139
+ }
140
+ else {
141
+ for (const source of SOURCE_PRIORITY) {
142
+ for (const behavior of BEHAVIORS) {
143
+ const rows = all.filter(f => f.source === source && f.behavior === behavior);
144
+ if (rows.length === 0)
145
+ continue;
146
+ lines.push(` ${source} ${behavior}:`);
147
+ for (const f of rows)
148
+ lines.push(` ${f.rule} — ${FINDING_LABEL[f.kind]} (${f.detail})`);
149
+ }
150
+ }
151
+ }
152
+ lines.push('Proposed user-layer cleanup:');
153
+ if (userLint === undefined) {
154
+ lines.push(' (user settings layer not reachable)');
155
+ }
156
+ else {
157
+ let any = false;
158
+ for (const behavior of BEHAVIORS) {
159
+ const before = userLint.before[behavior];
160
+ const after = userLint.after[behavior];
161
+ if (before === undefined || after === undefined || before.length === after.length)
162
+ continue;
163
+ any = true;
164
+ lines.push(` ${behavior}:`);
165
+ for (const entry of before) {
166
+ if (!after.includes(entry))
167
+ lines.push(` - ${entry}`);
168
+ else
169
+ lines.push(` ${entry}`);
170
+ }
171
+ }
172
+ if (!any)
173
+ lines.push(' (no changes proposed)');
174
+ }
175
+ return lines.join('\n');
176
+ }
177
+ /**
178
+ * Apply the proposed cleanup to the RAW user layer only, via
179
+ * `editUserSection` (never project/policy/session layers; never across
180
+ * behavior groups — removals come from `ruleSubsumes`, which requires equal
181
+ * behavior). Returns a result message, or `undefined`-error text on
182
+ * degradation.
183
+ */
184
+ export async function applyUserLint(settings) {
185
+ const provider = settings;
186
+ if (provider === undefined || typeof provider.editUserSection !== 'function' || provider.writable === false) {
187
+ return 'Cannot apply — no writable settings provider with a raw user-layer edit seam is mounted.';
188
+ }
189
+ let removed = 0;
190
+ await provider.editUserSection(PERMISSION_SETTINGS_NAMESPACE, raw => {
191
+ const lint = lintUserSection(raw);
192
+ removed = 0;
193
+ for (const behavior of BEHAVIORS) {
194
+ const before = lint.before[behavior];
195
+ const after = lint.after[behavior];
196
+ if (before !== undefined && after !== undefined)
197
+ removed += before.length - after.length;
198
+ }
199
+ if (removed === 0)
200
+ return undefined;
201
+ const next = { ...raw };
202
+ for (const behavior of BEHAVIORS) {
203
+ if (lint.before[behavior] !== undefined)
204
+ next[behavior] = lint.after[behavior];
205
+ }
206
+ return next;
207
+ });
208
+ return removed === 0 ? 'Nothing to apply — the user layer is already clean.' : `Applied: removed ${removed} redundant user-layer rule(s).`;
209
+ }
210
+ //# sourceMappingURL=lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.js","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,11 @@ export interface Totals {
22
22
  * Render the effective permission rule state from a rule set.
23
23
  * @param rules - the merged rule set (the engine's `ruleSet`).
24
24
  * @param bypassImmune - bypass-immune rule count (deny, guard-enforced).
25
+ * @param opts - when `suspendedAllow` > 0 (auto mode only), annotate the
26
+ * count of allow rules suspended at evaluation time (design doc D1).
25
27
  * @returns a read-only report of rule counts per source and in total.
26
28
  */
27
- export declare function renderPermissions(rules: PermissionRuleSet, bypassImmune: number): string;
29
+ export declare function renderPermissions(rules: PermissionRuleSet, bypassImmune: number, opts?: {
30
+ suspendedAllow?: number;
31
+ }): string;
28
32
  //# sourceMappingURL=permissions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,gCAAgC,CAAA;AAEvC,6CAA6C;AAC7C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,uCAAuC;AACvC,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;CACrB;AAqBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAcxF"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,gCAAgC,CAAA;AAEvC,6CAA6C;AAC7C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,uCAAuC;AACvC,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;CACrB;AAqBD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAgBhI"}
@@ -29,9 +29,11 @@ function addTotals(total, counts) {
29
29
  * Render the effective permission rule state from a rule set.
30
30
  * @param rules - the merged rule set (the engine's `ruleSet`).
31
31
  * @param bypassImmune - bypass-immune rule count (deny, guard-enforced).
32
+ * @param opts - when `suspendedAllow` > 0 (auto mode only), annotate the
33
+ * count of allow rules suspended at evaluation time (design doc D1).
32
34
  * @returns a read-only report of rule counts per source and in total.
33
35
  */
34
- export function renderPermissions(rules, bypassImmune) {
36
+ export function renderPermissions(rules, bypassImmune, opts = {}) {
35
37
  const lines = ['Permission rules (read-only)'];
36
38
  const total = { allow: 0, deny: 0, ask: 0, bypassImmune };
37
39
  let any = false;
@@ -46,6 +48,9 @@ export function renderPermissions(rules, bypassImmune) {
46
48
  if (!any)
47
49
  lines.push(' (no rules configured)');
48
50
  lines.push(`Total: allow=${total.allow} deny=${total.deny} ask=${total.ask} (bypassImmune=${bypassImmune})`);
51
+ const suspended = opts.suspendedAllow ?? 0;
52
+ if (suspended > 0)
53
+ lines.push(`Total: ${suspended} allow rule(s) suspended in auto mode`);
49
54
  return lines.join('\n');
50
55
  }
51
56
  //# sourceMappingURL=permissions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,GAGhB,MAAM,gCAAgC,CAAA;AAkBvC,kEAAkE;AAClE,SAAS,SAAS,CAAC,MAAc,EAAE,KAAgC;IACjE,MAAM,GAAG,GAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAA;IACxE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;YAAE,SAAQ;QACpC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE,GAAG,CAAC,KAAK,IAAI,CAAC,CAAA;aACxC,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM;YAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAA;aAC3C,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK;YAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,qDAAqD;AACrD,SAAS,SAAS,CAAC,KAAa,EAAE,MAAoB;IACpD,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAA;IAC3B,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAA;IACzB,KAAK,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAAA;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAwB,EAAE,YAAoB;IAC9E,MAAM,KAAK,GAAG,CAAC,8BAA8B,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAW,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAA;IACjE,IAAI,GAAG,GAAG,KAAK,CAAA;IACf,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/E,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC;YAAE,SAAQ;QACzE,GAAG,GAAG,IAAI,CAAA;QACV,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,WAAW,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;IACxF,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;IAC/C,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,KAAK,SAAS,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,GAAG,kBAAkB,YAAY,GAAG,CAAC,CAAA;IAC5G,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,GAGhB,MAAM,gCAAgC,CAAA;AAkBvC,kEAAkE;AAClE,SAAS,SAAS,CAAC,MAAc,EAAE,KAAgC;IACjE,MAAM,GAAG,GAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAA;IACxE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;YAAE,SAAQ;QACpC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE,GAAG,CAAC,KAAK,IAAI,CAAC,CAAA;aACxC,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM;YAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAA;aAC3C,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK;YAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,qDAAqD;AACrD,SAAS,SAAS,CAAC,KAAa,EAAE,MAAoB;IACpD,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAA;IAC3B,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAA;IACzB,KAAK,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAAA;AACzB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAwB,EAAE,YAAoB,EAAE,OAAoC,EAAE;IACtH,MAAM,KAAK,GAAG,CAAC,8BAA8B,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAW,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAA;IACjE,IAAI,GAAG,GAAG,KAAK,CAAA;IACf,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/E,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC;YAAE,SAAQ;QACzE,GAAG,GAAG,IAAI,CAAA;QACV,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,WAAW,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;IACxF,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;IAC/C,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,KAAK,SAAS,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,GAAG,kBAAkB,YAAY,GAAG,CAAC,CAAA;IAC5G,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,CAAA;IAC1C,IAAI,SAAS,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,SAAS,uCAAuC,CAAC,CAAA;IACzF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dsh-cc/command-permissions",
3
3
  "description": "Human-facing /permissions command (CC rule-engine modes) plus a popupSelect decoration (and TUI overlay) for the bare invocation",
4
- "version": "0.8.0-rc.2",
4
+ "version": "0.8.1-rc.1",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/dsh-cc/dsh-cc.git",
@@ -38,8 +38,9 @@
38
38
  }
39
39
  },
40
40
  "dependencies": {
41
- "@dsh-cc/permission-rules": "^0.8.0-rc.2",
42
- "@dsh-cc/command-usage": "^0.8.0-rc.2"
41
+ "@dsh-cc/command-usage": "^0.8.1-rc.1",
42
+ "@dsh-cc/tools": "^0.8.1-rc.1",
43
+ "@dsh-cc/permission-rules": "^0.8.1-rc.1"
43
44
  },
44
45
  "peerDependencies": {
45
46
  "@deepseek-ai/cordis": ">=0.1.5-rc.1",