@cjhyy/code-shell-core 0.8.6 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/agent-server-stdio.js +7 -5
- package/dist/context/manager.js +10 -2
- package/dist/engine/engine.d.ts +60 -8
- package/dist/engine/engine.js +153 -16
- package/dist/engine/run-setup.d.ts +1 -0
- package/dist/engine/run-setup.js +2 -1
- package/dist/engine/run-types.d.ts +7 -0
- package/dist/engine/turn-loop.d.ts +0 -3
- package/dist/engine/turn-loop.js +1 -80
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/panel-apps/manifest.d.ts +11 -11
- package/dist/panel-apps/manifest.js +16 -3
- package/dist/prompt/composer.d.ts +7 -0
- package/dist/prompt/composer.js +15 -8
- package/dist/prompt/sections/browser.md +2 -2
- package/dist/protocol/server.js +41 -1
- package/dist/protocol/types.d.ts +14 -0
- package/dist/session/memory.d.ts +10 -0
- package/dist/session/memory.js +7 -1
- package/dist/session/session-manager.js +1 -0
- package/dist/session/transcript.d.ts +36 -0
- package/dist/session/transcript.js +149 -4
- package/dist/tool-system/browser-bridge.d.ts +3 -0
- package/dist/tool-system/builtin/browser-tools.js +13 -0
- package/dist/tool-system/path-policy.js +84 -5
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -432,9 +432,10 @@ function isSkillTreeResource(resolved, skillsRoot) {
|
|
|
432
432
|
*
|
|
433
433
|
* Keep the exception narrow:
|
|
434
434
|
* - read-only (the caller checks the operation);
|
|
435
|
-
* - user Skills,
|
|
435
|
+
* - user Skills, an installed plugin recorded in the V2 registry, or a
|
|
436
|
+
* declared Skill in the installed Panel App registry;
|
|
436
437
|
* - plugin installs must realpath beneath the managed plugin cache;
|
|
437
|
-
* - the target must remain inside
|
|
438
|
+
* - the target must remain inside the registered Skill directory.
|
|
438
439
|
*/
|
|
439
440
|
function isRegisteredSkillResourceRead(resolved) {
|
|
440
441
|
let codeShellRoot;
|
|
@@ -448,6 +449,8 @@ function isRegisteredSkillResourceRead(resolved) {
|
|
|
448
449
|
return false;
|
|
449
450
|
if (isSkillTreeResource(resolved, join(codeShellRoot, "skills")))
|
|
450
451
|
return true;
|
|
452
|
+
if (isInstalledPanelAppSkillResourceRead(resolved, codeShellRoot))
|
|
453
|
+
return true;
|
|
451
454
|
let cacheRoot;
|
|
452
455
|
try {
|
|
453
456
|
cacheRoot = realpathSync(join(codeShellRoot, "plugins", "cache"));
|
|
@@ -475,6 +478,84 @@ function isRegisteredSkillResourceRead(resolved) {
|
|
|
475
478
|
}
|
|
476
479
|
return false;
|
|
477
480
|
}
|
|
481
|
+
/**
|
|
482
|
+
* Panel App Skills live under the otherwise-sensitive
|
|
483
|
+
* `~/.code-shell/panel-apps` tree. Installation already reviews and copies the
|
|
484
|
+
* package, and the Skill scanner exposes only entries declared by the app
|
|
485
|
+
* manifest. Mirror that exact boundary here so reading a Skill reference does
|
|
486
|
+
* not trigger a second approval prompt.
|
|
487
|
+
*
|
|
488
|
+
* Registry, app root, manifest, declared SKILL.md and target are all
|
|
489
|
+
* realpathed and containment-checked. This deliberately does not trust an
|
|
490
|
+
* undeclared Skill directory or a symlink escaping the installed app.
|
|
491
|
+
*/
|
|
492
|
+
function isInstalledPanelAppSkillResourceRead(resolved, codeShellRoot) {
|
|
493
|
+
let appsRoot;
|
|
494
|
+
let registryPath;
|
|
495
|
+
try {
|
|
496
|
+
appsRoot = realpathSync(join(codeShellRoot, "panel-apps"));
|
|
497
|
+
if (!isInsideDir(appsRoot, codeShellRoot))
|
|
498
|
+
return false;
|
|
499
|
+
registryPath = realpathSync(join(appsRoot, "installed.json"));
|
|
500
|
+
if (!isInsideDir(registryPath, appsRoot))
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
let registry;
|
|
507
|
+
try {
|
|
508
|
+
registry = JSON.parse(readFileSync(registryPath, "utf-8"));
|
|
509
|
+
}
|
|
510
|
+
catch {
|
|
511
|
+
return false;
|
|
512
|
+
}
|
|
513
|
+
if (registry.version !== 1 || !Array.isArray(registry.apps))
|
|
514
|
+
return false;
|
|
515
|
+
for (const rawEntry of registry.apps) {
|
|
516
|
+
if (!rawEntry || typeof rawEntry !== "object")
|
|
517
|
+
continue;
|
|
518
|
+
const id = rawEntry.id;
|
|
519
|
+
if (typeof id !== "string" || !/^[a-z][a-z0-9-]{0,63}$/.test(id))
|
|
520
|
+
continue;
|
|
521
|
+
try {
|
|
522
|
+
const appRoot = realpathSync(join(appsRoot, id));
|
|
523
|
+
if (appRoot === appsRoot || !isInsideDir(appRoot, appsRoot))
|
|
524
|
+
continue;
|
|
525
|
+
const manifestPath = realpathSync(join(appRoot, ".codeshell-panel", "panel.json"));
|
|
526
|
+
if (!isInsideDir(manifestPath, appRoot) || !statSync(manifestPath).isFile())
|
|
527
|
+
continue;
|
|
528
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
529
|
+
if (manifest.schemaVersion !== 2 ||
|
|
530
|
+
manifest.id !== id ||
|
|
531
|
+
!Array.isArray(manifest.agent?.skills)) {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
for (const skillEntry of manifest.agent.skills) {
|
|
535
|
+
if (typeof skillEntry !== "string")
|
|
536
|
+
continue;
|
|
537
|
+
const segments = skillEntry.split("/");
|
|
538
|
+
if (segments.length !== 4 ||
|
|
539
|
+
segments[0] !== "agent" ||
|
|
540
|
+
segments[1] !== "skills" ||
|
|
541
|
+
!/^[a-z][a-z0-9-]{0,63}$/.test(segments[2] ?? "") ||
|
|
542
|
+
segments[3] !== "SKILL.md") {
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
const skillManifest = realpathSync(join(appRoot, ...segments));
|
|
546
|
+
if (!isInsideDir(skillManifest, appRoot) || !statSync(skillManifest).isFile())
|
|
547
|
+
continue;
|
|
548
|
+
const skillRoot = dirname(skillManifest);
|
|
549
|
+
if (isInsideDir(resolved, skillRoot))
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
catch {
|
|
554
|
+
// A stale, malformed, or tampered Panel App entry grants no read access.
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
478
559
|
/**
|
|
479
560
|
* Returns the matching sensitive-dir entry (with the user's home prefix) if
|
|
480
561
|
* `resolved` lives underneath any sensitive directory, else undefined.
|
|
@@ -564,9 +645,7 @@ export function classifyPath(rawPath, opts) {
|
|
|
564
645
|
// files through the ordinary Read tool as well. A credential-shaped basename
|
|
565
646
|
// (.env, token.txt, key files, ...) deliberately keeps the sensitive-file
|
|
566
647
|
// gate even inside a Skill tree.
|
|
567
|
-
if (opts.operation === "read" &&
|
|
568
|
-
!sensitiveFile &&
|
|
569
|
-
isRegisteredSkillResourceRead(resolved)) {
|
|
648
|
+
if (opts.operation === "read" && !sensitiveFile && isRegisteredSkillResourceRead(resolved)) {
|
|
570
649
|
return {
|
|
571
650
|
decision: "allow",
|
|
572
651
|
reason: "registered Skill resource read",
|
package/dist/types.d.ts
CHANGED
|
@@ -145,7 +145,7 @@ export interface RegisteredTool {
|
|
|
145
145
|
*/
|
|
146
146
|
timeoutMs?: number;
|
|
147
147
|
}
|
|
148
|
-
export type TranscriptEventType = "message" | "tool_use" | "tool_result" | "summary" | "context_transfer" | "content_replace" | "file_history" | "plan_operation" | "session_meta" | "subagent" | "external_file_changes" | "turn_boundary" | "run_result" | "goal_progress" | "turn_stopped" | "error";
|
|
148
|
+
export type TranscriptEventType = "message" | "tool_use" | "tool_result" | "summary" | "context_transfer" | "range_archive" | "content_replace" | "file_history" | "plan_operation" | "session_meta" | "subagent" | "external_file_changes" | "turn_boundary" | "run_result" | "goal_progress" | "turn_stopped" | "error";
|
|
149
149
|
export interface TranscriptEvent {
|
|
150
150
|
id: string;
|
|
151
151
|
type: TranscriptEventType;
|
package/package.json
CHANGED