appostle-installer 0.0.4 → 0.0.6
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/appostle.js +1913 -325
- package/dist/appostle.js.map +4 -4
- package/dist/worker.js +2668 -476
- package/dist/worker.js.map +4 -4
- package/package.json +1 -2
package/dist/appostle.js
CHANGED
|
@@ -454,18 +454,18 @@ function resolveNodePtyPackageRoot() {
|
|
|
454
454
|
return null;
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
|
-
function ensureExecutableBit(
|
|
458
|
-
if (!existsSync2(
|
|
457
|
+
function ensureExecutableBit(path24) {
|
|
458
|
+
if (!existsSync2(path24)) {
|
|
459
459
|
return;
|
|
460
460
|
}
|
|
461
|
-
const stat5 = statSync(
|
|
461
|
+
const stat5 = statSync(path24);
|
|
462
462
|
if (!stat5.isFile()) {
|
|
463
463
|
return;
|
|
464
464
|
}
|
|
465
465
|
if ((stat5.mode & 73) === 73) {
|
|
466
466
|
return;
|
|
467
467
|
}
|
|
468
|
-
chmodSync(
|
|
468
|
+
chmodSync(path24, stat5.mode | 73);
|
|
469
469
|
}
|
|
470
470
|
function ensureNodePtySpawnHelperExecutableForCurrentPlatform(options = {}) {
|
|
471
471
|
const platform2 = options.platform ?? process.platform;
|
|
@@ -547,11 +547,11 @@ function parseGitRevParsePath(stdout) {
|
|
|
547
547
|
if (lines.length !== 1) {
|
|
548
548
|
return null;
|
|
549
549
|
}
|
|
550
|
-
const
|
|
551
|
-
if (!
|
|
550
|
+
const path24 = lines[0]?.trim() ?? "";
|
|
551
|
+
if (!path24 || path24.startsWith("--")) {
|
|
552
552
|
return null;
|
|
553
553
|
}
|
|
554
|
-
return
|
|
554
|
+
return path24;
|
|
555
555
|
}
|
|
556
556
|
function resolveGitRevParsePath(cwd, stdout) {
|
|
557
557
|
const parsed = parseGitRevParsePath(stdout);
|
|
@@ -1324,9 +1324,9 @@ async function deleteAppostleWorktree({
|
|
|
1324
1324
|
}
|
|
1325
1325
|
}
|
|
1326
1326
|
}
|
|
1327
|
-
async function pathExists(
|
|
1327
|
+
async function pathExists(path24) {
|
|
1328
1328
|
try {
|
|
1329
|
-
await stat(
|
|
1329
|
+
await stat(path24);
|
|
1330
1330
|
return true;
|
|
1331
1331
|
} catch (error) {
|
|
1332
1332
|
if (error.code === "ENOENT") {
|
|
@@ -1335,8 +1335,8 @@ async function pathExists(path23) {
|
|
|
1335
1335
|
throw error;
|
|
1336
1336
|
}
|
|
1337
1337
|
}
|
|
1338
|
-
async function removeDirectoryWithRetries(
|
|
1339
|
-
if (!await pathExists(
|
|
1338
|
+
async function removeDirectoryWithRetries(path24) {
|
|
1339
|
+
if (!await pathExists(path24)) {
|
|
1340
1340
|
return;
|
|
1341
1341
|
}
|
|
1342
1342
|
const delaysMs = [0, 100, 300, 700, 1500];
|
|
@@ -1346,17 +1346,17 @@ async function removeDirectoryWithRetries(path23) {
|
|
|
1346
1346
|
await new Promise((resolve12) => setTimeout(resolve12, delay));
|
|
1347
1347
|
}
|
|
1348
1348
|
try {
|
|
1349
|
-
await rm(
|
|
1350
|
-
if (!await pathExists(
|
|
1349
|
+
await rm(path24, { recursive: true, force: true });
|
|
1350
|
+
if (!await pathExists(path24)) {
|
|
1351
1351
|
return;
|
|
1352
1352
|
}
|
|
1353
|
-
lastError = new Error(`Directory still present after rm: ${
|
|
1353
|
+
lastError = new Error(`Directory still present after rm: ${path24}`);
|
|
1354
1354
|
} catch (error) {
|
|
1355
1355
|
lastError = error;
|
|
1356
1356
|
}
|
|
1357
1357
|
}
|
|
1358
|
-
if (await pathExists(
|
|
1359
|
-
throw lastError instanceof Error ? lastError : new Error(`Failed to remove worktree directory: ${
|
|
1358
|
+
if (await pathExists(path24)) {
|
|
1359
|
+
throw lastError instanceof Error ? lastError : new Error(`Failed to remove worktree directory: ${path24}`);
|
|
1360
1360
|
}
|
|
1361
1361
|
}
|
|
1362
1362
|
var createWorktree = async ({
|
|
@@ -2545,14 +2545,14 @@ var LoopStopResponseSchema = z7.object({
|
|
|
2545
2545
|
})
|
|
2546
2546
|
});
|
|
2547
2547
|
|
|
2548
|
-
// ../server/src/server/
|
|
2548
|
+
// ../server/src/server/quest/rpc-schemas.ts
|
|
2549
2549
|
import { z as z9 } from "zod";
|
|
2550
2550
|
|
|
2551
|
-
// ../server/src/server/
|
|
2551
|
+
// ../server/src/server/quest/types.ts
|
|
2552
2552
|
import { z as z8 } from "zod";
|
|
2553
|
-
var
|
|
2553
|
+
var QuestKindSchema = z8.enum(["loop", "ralph", "run", "orchestrate"]);
|
|
2554
2554
|
var FieldModeSchema = z8.enum(["locked", "inherit", "free"]);
|
|
2555
|
-
var
|
|
2555
|
+
var QuestRulesSchema = z8.object({
|
|
2556
2556
|
perCardRole: FieldModeSchema,
|
|
2557
2557
|
perCardModel: FieldModeSchema,
|
|
2558
2558
|
perCardPrompt: FieldModeSchema,
|
|
@@ -2576,79 +2576,101 @@ var CardWiringSchema = z8.object({
|
|
|
2576
2576
|
inputs: CardWiringInputsSchema,
|
|
2577
2577
|
outputs: CardWiringOutputsSchema
|
|
2578
2578
|
});
|
|
2579
|
-
var
|
|
2579
|
+
var QuestCardStatusSchema = z8.enum([
|
|
2580
2580
|
"queued",
|
|
2581
2581
|
"running",
|
|
2582
2582
|
"succeeded",
|
|
2583
2583
|
"failed",
|
|
2584
2584
|
"stopped"
|
|
2585
2585
|
]);
|
|
2586
|
-
var
|
|
2586
|
+
var QuestCardVerifySchema = z8.object({
|
|
2587
2587
|
verifierAgentId: z8.string().nullable(),
|
|
2588
2588
|
passed: z8.boolean().nullable(),
|
|
2589
2589
|
reason: z8.string().nullable(),
|
|
2590
2590
|
startedAt: z8.string().nullable(),
|
|
2591
2591
|
completedAt: z8.string().nullable()
|
|
2592
2592
|
});
|
|
2593
|
-
var
|
|
2593
|
+
var QuestCardSchema = z8.object({
|
|
2594
2594
|
/**
|
|
2595
2595
|
* 1..N for iteration cards. The summarizer card uses 0 as a sentinel —
|
|
2596
|
-
* it lives on `
|
|
2596
|
+
* it lives on `QuestRecord.summarizerCard`, not in the cards array,
|
|
2597
2597
|
* and the UI renders it as "Summary" when it sees index === 0.
|
|
2598
2598
|
*/
|
|
2599
2599
|
index: z8.number().int().nonnegative(),
|
|
2600
|
-
/** Role name resolved against the agents/.scanner. Null = use
|
|
2600
|
+
/** Role name resolved against the agents/.scanner. Null = use quest default. */
|
|
2601
2601
|
role: z8.string().nullable(),
|
|
2602
|
-
/** Model override. Null = use
|
|
2602
|
+
/** Model override. Null = use quest.defaultModel. */
|
|
2603
2603
|
model: z8.string().nullable(),
|
|
2604
|
-
/** Prompt override. Null = use
|
|
2604
|
+
/** Prompt override. Null = use quest.prompt. */
|
|
2605
2605
|
prompt: z8.string().nullable(),
|
|
2606
2606
|
wiring: CardWiringSchema,
|
|
2607
|
-
status:
|
|
2607
|
+
status: QuestCardStatusSchema,
|
|
2608
2608
|
/** Populated when the card runs. Null until the runner spawns the agent. */
|
|
2609
2609
|
agentId: z8.string().nullable(),
|
|
2610
2610
|
startedAt: z8.string().nullable(),
|
|
2611
2611
|
completedAt: z8.string().nullable(),
|
|
2612
2612
|
/** Ralph-only — null for loop cards. */
|
|
2613
|
-
verify:
|
|
2613
|
+
verify: QuestCardVerifySchema.nullable()
|
|
2614
2614
|
});
|
|
2615
|
-
var
|
|
2615
|
+
var QuestTerminationCountSchema = z8.object({
|
|
2616
2616
|
type: z8.literal("count"),
|
|
2617
2617
|
/** 1..10 in v1. */
|
|
2618
2618
|
n: z8.number().int().min(1).max(10)
|
|
2619
2619
|
});
|
|
2620
|
-
var
|
|
2620
|
+
var QuestTerminationVerifySchema = z8.object({
|
|
2621
2621
|
type: z8.literal("verify"),
|
|
2622
2622
|
/** Verifier agent system prompt. Null means rely on shell checks alone. */
|
|
2623
2623
|
verifyPrompt: z8.string().nullable(),
|
|
2624
2624
|
/** Shell commands that must exit 0 for the iteration to pass. */
|
|
2625
2625
|
verifyChecks: z8.array(z8.string()),
|
|
2626
|
+
/**
|
|
2627
|
+
* Exact completion token that MUST appear in worker output before the quest
|
|
2628
|
+
* may succeed. Mirrors Ralph's completion-promise guardrail.
|
|
2629
|
+
*/
|
|
2630
|
+
completionPromise: z8.string().trim().min(1).optional().default("<promise>COMPLETE</promise>"),
|
|
2626
2631
|
/** Hard cap on iterations regardless of verifier outcome. */
|
|
2627
2632
|
maxIterations: z8.number().int().min(1)
|
|
2628
2633
|
});
|
|
2629
|
-
var
|
|
2630
|
-
|
|
2631
|
-
|
|
2634
|
+
var QuestTerminationOrchestrateSchema = z8.object({
|
|
2635
|
+
type: z8.literal("orchestrate")
|
|
2636
|
+
});
|
|
2637
|
+
var QuestTerminationSchema = z8.discriminatedUnion("type", [
|
|
2638
|
+
QuestTerminationCountSchema,
|
|
2639
|
+
QuestTerminationVerifySchema,
|
|
2640
|
+
QuestTerminationOrchestrateSchema
|
|
2632
2641
|
]);
|
|
2633
|
-
var
|
|
2634
|
-
var
|
|
2642
|
+
var QuestStatusSchema = z8.enum(["running", "succeeded", "failed", "stopped"]);
|
|
2643
|
+
var QuestRecordSchema = z8.object({
|
|
2635
2644
|
id: z8.string(),
|
|
2636
|
-
kind:
|
|
2637
|
-
rules:
|
|
2645
|
+
kind: QuestKindSchema,
|
|
2646
|
+
rules: QuestRulesSchema,
|
|
2638
2647
|
cwd: z8.string(),
|
|
2639
2648
|
/** User's task prompt — fed to every card unless overridden per-card. */
|
|
2640
2649
|
prompt: z8.string(),
|
|
2641
2650
|
defaultProvider: AgentProviderSchema,
|
|
2642
2651
|
defaultModel: z8.string().nullable(),
|
|
2643
|
-
termination:
|
|
2652
|
+
termination: QuestTerminationSchema,
|
|
2644
2653
|
/**
|
|
2645
2654
|
* For "loop" kind: pre-rendered N cards from the start.
|
|
2646
2655
|
* For "ralph" kind: appended as iterations execute.
|
|
2647
2656
|
*/
|
|
2648
|
-
cards: z8.array(
|
|
2657
|
+
cards: z8.array(QuestCardSchema),
|
|
2649
2658
|
/** Populated when summarizer is enabled. Runs after all cards complete. */
|
|
2650
|
-
summarizerCard:
|
|
2651
|
-
|
|
2659
|
+
summarizerCard: QuestCardSchema.nullable(),
|
|
2660
|
+
/**
|
|
2661
|
+
* Queen-bee coordinator card for "orchestrate" kind. The queen reads the
|
|
2662
|
+
* hivemind doc, decides dispatch waves, and writes JSON decisions back. It
|
|
2663
|
+
* is promotable (same affordance as regular cards). Null for non-orchestrate
|
|
2664
|
+
* kinds. Optional + default so old persisted records remain valid.
|
|
2665
|
+
*/
|
|
2666
|
+
queenCard: QuestCardSchema.nullable().optional().default(null),
|
|
2667
|
+
/**
|
|
2668
|
+
* Path to the orchestration's hivemind markdown doc. Null for non-
|
|
2669
|
+
* orchestrate kinds. Optional + default so old persisted records remain
|
|
2670
|
+
* valid.
|
|
2671
|
+
*/
|
|
2672
|
+
hivemindPath: z8.string().nullable().optional().default(null),
|
|
2673
|
+
status: QuestStatusSchema,
|
|
2652
2674
|
createdAt: z8.string(),
|
|
2653
2675
|
updatedAt: z8.string(),
|
|
2654
2676
|
startedAt: z8.string().nullable(),
|
|
@@ -2656,107 +2678,293 @@ var WorkflowRecordSchema = z8.object({
|
|
|
2656
2678
|
stopRequestedAt: z8.string().nullable()
|
|
2657
2679
|
});
|
|
2658
2680
|
|
|
2659
|
-
// ../server/src/server/
|
|
2660
|
-
var
|
|
2681
|
+
// ../server/src/server/quest/rpc-schemas.ts
|
|
2682
|
+
var QuestCardConfigInputSchema = z9.object({
|
|
2661
2683
|
role: z9.string().nullable().optional(),
|
|
2662
2684
|
model: z9.string().nullable().optional(),
|
|
2663
2685
|
prompt: z9.string().nullable().optional()
|
|
2664
2686
|
});
|
|
2665
|
-
var
|
|
2666
|
-
type: z9.literal("
|
|
2687
|
+
var QuestRunRequestSchema = z9.object({
|
|
2688
|
+
type: z9.literal("quest/run"),
|
|
2667
2689
|
requestId: z9.string(),
|
|
2668
|
-
kind:
|
|
2690
|
+
kind: QuestKindSchema,
|
|
2669
2691
|
cwd: z9.string(),
|
|
2670
2692
|
prompt: z9.string().trim().min(1),
|
|
2671
2693
|
defaultProvider: AgentProviderSchema.optional(),
|
|
2672
2694
|
defaultModel: z9.string().trim().min(1).optional(),
|
|
2673
|
-
termination:
|
|
2695
|
+
termination: QuestTerminationSchema,
|
|
2674
2696
|
/** Per-card overrides (length must match termination.n for "count"). Optional. */
|
|
2675
|
-
cards: z9.array(
|
|
2697
|
+
cards: z9.array(QuestCardConfigInputSchema).optional(),
|
|
2676
2698
|
summarizerEnabled: z9.boolean().optional()
|
|
2677
2699
|
});
|
|
2678
|
-
var
|
|
2679
|
-
type: z9.literal("
|
|
2700
|
+
var QuestListRequestSchema = z9.object({
|
|
2701
|
+
type: z9.literal("quest/list"),
|
|
2680
2702
|
requestId: z9.string()
|
|
2681
2703
|
});
|
|
2682
|
-
var
|
|
2683
|
-
type: z9.literal("
|
|
2704
|
+
var QuestInspectRequestSchema = z9.object({
|
|
2705
|
+
type: z9.literal("quest/inspect"),
|
|
2684
2706
|
requestId: z9.string(),
|
|
2685
2707
|
id: z9.string().trim().min(1)
|
|
2686
2708
|
});
|
|
2687
|
-
var
|
|
2688
|
-
type: z9.literal("
|
|
2709
|
+
var QuestStopRequestSchema = z9.object({
|
|
2710
|
+
type: z9.literal("quest/stop"),
|
|
2689
2711
|
requestId: z9.string(),
|
|
2690
2712
|
id: z9.string().trim().min(1)
|
|
2691
2713
|
});
|
|
2692
|
-
var
|
|
2714
|
+
var QuestListItemSchema = z9.object({
|
|
2693
2715
|
id: z9.string(),
|
|
2694
|
-
kind:
|
|
2695
|
-
status:
|
|
2716
|
+
kind: QuestKindSchema,
|
|
2717
|
+
status: QuestStatusSchema,
|
|
2696
2718
|
cwd: z9.string(),
|
|
2697
2719
|
prompt: z9.string(),
|
|
2698
2720
|
createdAt: z9.string(),
|
|
2699
2721
|
updatedAt: z9.string()
|
|
2700
2722
|
});
|
|
2701
|
-
var
|
|
2702
|
-
type: z9.literal("
|
|
2723
|
+
var QuestRunResponseSchema = z9.object({
|
|
2724
|
+
type: z9.literal("quest/run/response"),
|
|
2725
|
+
payload: z9.object({
|
|
2726
|
+
requestId: z9.string(),
|
|
2727
|
+
quest: QuestRecordSchema.nullable(),
|
|
2728
|
+
error: z9.string().nullable()
|
|
2729
|
+
})
|
|
2730
|
+
});
|
|
2731
|
+
var QuestListResponseSchema = z9.object({
|
|
2732
|
+
type: z9.literal("quest/list/response"),
|
|
2733
|
+
payload: z9.object({
|
|
2734
|
+
requestId: z9.string(),
|
|
2735
|
+
quests: z9.array(QuestListItemSchema),
|
|
2736
|
+
error: z9.string().nullable()
|
|
2737
|
+
})
|
|
2738
|
+
});
|
|
2739
|
+
var QuestInspectResponseSchema = z9.object({
|
|
2740
|
+
type: z9.literal("quest/inspect/response"),
|
|
2741
|
+
payload: z9.object({
|
|
2742
|
+
requestId: z9.string(),
|
|
2743
|
+
quest: QuestRecordSchema.nullable(),
|
|
2744
|
+
error: z9.string().nullable()
|
|
2745
|
+
})
|
|
2746
|
+
});
|
|
2747
|
+
var QuestStopResponseSchema = z9.object({
|
|
2748
|
+
type: z9.literal("quest/stop/response"),
|
|
2749
|
+
payload: z9.object({
|
|
2750
|
+
requestId: z9.string(),
|
|
2751
|
+
quest: QuestRecordSchema.nullable(),
|
|
2752
|
+
error: z9.string().nullable()
|
|
2753
|
+
})
|
|
2754
|
+
});
|
|
2755
|
+
var QuestStreamMessageSchema = z9.object({
|
|
2756
|
+
type: z9.literal("quest/stream"),
|
|
2757
|
+
questId: z9.string(),
|
|
2758
|
+
quest: QuestRecordSchema
|
|
2759
|
+
});
|
|
2760
|
+
var RoleScopeSchema = z9.enum(["global", "project"]);
|
|
2761
|
+
var RoleEntrySchema = z9.object({
|
|
2762
|
+
id: z9.string(),
|
|
2763
|
+
scope: RoleScopeSchema,
|
|
2764
|
+
/** Category subfolder inside .roles/, or null for flat files. */
|
|
2765
|
+
category: z9.string().nullable().optional(),
|
|
2766
|
+
name: z9.string(),
|
|
2767
|
+
description: z9.string(),
|
|
2768
|
+
/** Trigger words from the `trigger-words` frontmatter key. */
|
|
2769
|
+
triggerWords: z9.array(z9.string()).optional().default([]),
|
|
2770
|
+
provider: z9.string(),
|
|
2771
|
+
model: z9.string(),
|
|
2772
|
+
mode: z9.string(),
|
|
2773
|
+
path: z9.string(),
|
|
2774
|
+
modifiedAt: z9.string(),
|
|
2775
|
+
size: z9.number()
|
|
2776
|
+
});
|
|
2777
|
+
var RoleFrontmatterSchema = z9.object({
|
|
2778
|
+
description: z9.string().optional(),
|
|
2779
|
+
triggerWords: z9.array(z9.string()).optional(),
|
|
2780
|
+
allowedTools: z9.array(z9.string()).optional(),
|
|
2781
|
+
provider: z9.string().optional(),
|
|
2782
|
+
model: z9.string().optional(),
|
|
2783
|
+
mode: z9.string().optional()
|
|
2784
|
+
});
|
|
2785
|
+
var RolesListRequestSchema = z9.object({
|
|
2786
|
+
type: z9.literal("roles/list"),
|
|
2787
|
+
requestId: z9.string(),
|
|
2788
|
+
workspaceRoot: z9.string().optional()
|
|
2789
|
+
});
|
|
2790
|
+
var RolesListResponseSchema = z9.object({
|
|
2791
|
+
type: z9.literal("roles/list/response"),
|
|
2703
2792
|
payload: z9.object({
|
|
2704
2793
|
requestId: z9.string(),
|
|
2705
|
-
|
|
2794
|
+
roles: z9.array(RoleEntrySchema),
|
|
2706
2795
|
error: z9.string().nullable()
|
|
2707
2796
|
})
|
|
2708
2797
|
});
|
|
2709
|
-
var
|
|
2710
|
-
type: z9.literal("
|
|
2798
|
+
var RolesListScopeRequestSchema = z9.object({
|
|
2799
|
+
type: z9.literal("roles/list-scope"),
|
|
2800
|
+
requestId: z9.string(),
|
|
2801
|
+
scope: RoleScopeSchema,
|
|
2802
|
+
workspaceRoot: z9.string().optional()
|
|
2803
|
+
});
|
|
2804
|
+
var RolesListScopeResponseSchema = z9.object({
|
|
2805
|
+
type: z9.literal("roles/list-scope/response"),
|
|
2711
2806
|
payload: z9.object({
|
|
2712
2807
|
requestId: z9.string(),
|
|
2713
|
-
|
|
2808
|
+
roles: z9.array(RoleEntrySchema),
|
|
2714
2809
|
error: z9.string().nullable()
|
|
2715
2810
|
})
|
|
2716
2811
|
});
|
|
2717
|
-
var
|
|
2718
|
-
type: z9.literal("
|
|
2812
|
+
var RoleCreateRequestSchema = z9.object({
|
|
2813
|
+
type: z9.literal("roles/create"),
|
|
2814
|
+
requestId: z9.string(),
|
|
2815
|
+
scope: RoleScopeSchema,
|
|
2816
|
+
name: z9.string(),
|
|
2817
|
+
category: z9.string().optional(),
|
|
2818
|
+
workspaceRoot: z9.string().optional()
|
|
2819
|
+
});
|
|
2820
|
+
var RoleCreateResponseSchema = z9.object({
|
|
2821
|
+
type: z9.literal("roles/create/response"),
|
|
2719
2822
|
payload: z9.object({
|
|
2720
2823
|
requestId: z9.string(),
|
|
2721
|
-
|
|
2824
|
+
/** Absolute path of the created .md file. Empty string when error is set. */
|
|
2825
|
+
path: z9.string(),
|
|
2722
2826
|
error: z9.string().nullable()
|
|
2723
2827
|
})
|
|
2724
2828
|
});
|
|
2725
|
-
var
|
|
2726
|
-
type: z9.literal("
|
|
2829
|
+
var RoleWriteFrontmatterRequestSchema = z9.object({
|
|
2830
|
+
type: z9.literal("roles/write-frontmatter"),
|
|
2831
|
+
requestId: z9.string(),
|
|
2832
|
+
/** Absolute path inside an allowlisted role root. */
|
|
2833
|
+
path: z9.string(),
|
|
2834
|
+
workspaceRoot: z9.string().optional(),
|
|
2835
|
+
frontmatter: RoleFrontmatterSchema
|
|
2836
|
+
});
|
|
2837
|
+
var RoleWriteFrontmatterResponseSchema = z9.object({
|
|
2838
|
+
type: z9.literal("roles/write-frontmatter/response"),
|
|
2727
2839
|
payload: z9.object({
|
|
2728
2840
|
requestId: z9.string(),
|
|
2729
|
-
|
|
2841
|
+
path: z9.string(),
|
|
2730
2842
|
error: z9.string().nullable()
|
|
2731
2843
|
})
|
|
2732
2844
|
});
|
|
2733
|
-
var
|
|
2734
|
-
type: z9.literal("
|
|
2735
|
-
|
|
2736
|
-
|
|
2845
|
+
var RoleMoveRequestSchema = z9.object({
|
|
2846
|
+
type: z9.literal("roles/move"),
|
|
2847
|
+
requestId: z9.string(),
|
|
2848
|
+
path: z9.string(),
|
|
2849
|
+
newName: z9.string().optional(),
|
|
2850
|
+
newCategory: z9.string().optional(),
|
|
2851
|
+
workspaceRoot: z9.string().optional()
|
|
2852
|
+
});
|
|
2853
|
+
var RoleMoveResponseSchema = z9.object({
|
|
2854
|
+
type: z9.literal("roles/move/response"),
|
|
2855
|
+
payload: z9.object({
|
|
2856
|
+
requestId: z9.string(),
|
|
2857
|
+
path: z9.string(),
|
|
2858
|
+
error: z9.string().nullable()
|
|
2859
|
+
})
|
|
2737
2860
|
});
|
|
2738
|
-
var
|
|
2861
|
+
var BrandScopeSchema = z9.literal("project");
|
|
2862
|
+
var BrandVariableTypeSchema = z9.enum([
|
|
2863
|
+
"color",
|
|
2864
|
+
"font",
|
|
2865
|
+
"asset",
|
|
2866
|
+
"text",
|
|
2867
|
+
"number",
|
|
2868
|
+
"select"
|
|
2869
|
+
]);
|
|
2870
|
+
var BrandSectionSchema = z9.enum(["visual", "voice"]);
|
|
2871
|
+
var BrandVariableSchema = z9.object({
|
|
2872
|
+
key: z9.string(),
|
|
2873
|
+
type: BrandVariableTypeSchema,
|
|
2874
|
+
label: z9.string(),
|
|
2875
|
+
value: z9.string(),
|
|
2876
|
+
section: BrandSectionSchema.optional(),
|
|
2877
|
+
options: z9.array(z9.string()).optional(),
|
|
2878
|
+
fileRef: z9.string().optional()
|
|
2879
|
+
});
|
|
2880
|
+
var BrandEntrySchema = z9.object({
|
|
2739
2881
|
id: z9.string(),
|
|
2740
|
-
scope:
|
|
2882
|
+
scope: BrandScopeSchema,
|
|
2741
2883
|
name: z9.string(),
|
|
2742
2884
|
description: z9.string(),
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
mode: z9.string().nullable(),
|
|
2885
|
+
tags: z9.array(z9.string()).optional().default([]),
|
|
2886
|
+
variables: z9.array(BrandVariableSchema).optional().default([]),
|
|
2746
2887
|
path: z9.string(),
|
|
2747
2888
|
modifiedAt: z9.string(),
|
|
2748
2889
|
size: z9.number()
|
|
2749
2890
|
});
|
|
2750
|
-
var
|
|
2751
|
-
|
|
2891
|
+
var BrandFrontmatterSchema = z9.object({
|
|
2892
|
+
description: z9.string().optional(),
|
|
2893
|
+
tags: z9.array(z9.string()).optional(),
|
|
2894
|
+
variables: z9.array(BrandVariableSchema).optional()
|
|
2895
|
+
});
|
|
2896
|
+
var BrandsListScopeRequestSchema = z9.object({
|
|
2897
|
+
type: z9.literal("brands/list-scope"),
|
|
2752
2898
|
requestId: z9.string(),
|
|
2753
2899
|
workspaceRoot: z9.string().optional()
|
|
2754
2900
|
});
|
|
2755
|
-
var
|
|
2756
|
-
type: z9.literal("
|
|
2901
|
+
var BrandsListScopeResponseSchema = z9.object({
|
|
2902
|
+
type: z9.literal("brands/list-scope/response"),
|
|
2903
|
+
payload: z9.object({
|
|
2904
|
+
requestId: z9.string(),
|
|
2905
|
+
brands: z9.array(BrandEntrySchema),
|
|
2906
|
+
error: z9.string().nullable()
|
|
2907
|
+
})
|
|
2908
|
+
});
|
|
2909
|
+
var BrandCreateRequestSchema = z9.object({
|
|
2910
|
+
type: z9.literal("brands/create"),
|
|
2911
|
+
requestId: z9.string(),
|
|
2912
|
+
name: z9.string(),
|
|
2913
|
+
workspaceRoot: z9.string().optional()
|
|
2914
|
+
});
|
|
2915
|
+
var BrandCreateResponseSchema = z9.object({
|
|
2916
|
+
type: z9.literal("brands/create/response"),
|
|
2757
2917
|
payload: z9.object({
|
|
2758
2918
|
requestId: z9.string(),
|
|
2759
|
-
|
|
2919
|
+
path: z9.string(),
|
|
2920
|
+
error: z9.string().nullable()
|
|
2921
|
+
})
|
|
2922
|
+
});
|
|
2923
|
+
var BrandAssetCopyRequestSchema = z9.object({
|
|
2924
|
+
type: z9.literal("brands/asset-copy"),
|
|
2925
|
+
requestId: z9.string(),
|
|
2926
|
+
workspaceRoot: z9.string(),
|
|
2927
|
+
sourcePath: z9.string(),
|
|
2928
|
+
targetName: z9.string()
|
|
2929
|
+
});
|
|
2930
|
+
var BrandAssetUploadRequestSchema = z9.object({
|
|
2931
|
+
type: z9.literal("brands/asset-upload"),
|
|
2932
|
+
requestId: z9.string(),
|
|
2933
|
+
workspaceRoot: z9.string(),
|
|
2934
|
+
targetName: z9.string(),
|
|
2935
|
+
sourceName: z9.string().optional(),
|
|
2936
|
+
dataBase64: z9.string()
|
|
2937
|
+
});
|
|
2938
|
+
var BrandAssetUploadResponseSchema = z9.object({
|
|
2939
|
+
type: z9.literal("brands/asset-upload/response"),
|
|
2940
|
+
payload: z9.object({
|
|
2941
|
+
requestId: z9.string(),
|
|
2942
|
+
relativePath: z9.string(),
|
|
2943
|
+
absolutePath: z9.string(),
|
|
2944
|
+
error: z9.string().nullable()
|
|
2945
|
+
})
|
|
2946
|
+
});
|
|
2947
|
+
var BrandAssetCopyResponseSchema = z9.object({
|
|
2948
|
+
type: z9.literal("brands/asset-copy/response"),
|
|
2949
|
+
payload: z9.object({
|
|
2950
|
+
requestId: z9.string(),
|
|
2951
|
+
relativePath: z9.string(),
|
|
2952
|
+
absolutePath: z9.string(),
|
|
2953
|
+
error: z9.string().nullable()
|
|
2954
|
+
})
|
|
2955
|
+
});
|
|
2956
|
+
var BrandWriteFrontmatterRequestSchema = z9.object({
|
|
2957
|
+
type: z9.literal("brands/write-frontmatter"),
|
|
2958
|
+
requestId: z9.string(),
|
|
2959
|
+
path: z9.string(),
|
|
2960
|
+
workspaceRoot: z9.string().optional(),
|
|
2961
|
+
frontmatter: BrandFrontmatterSchema
|
|
2962
|
+
});
|
|
2963
|
+
var BrandWriteFrontmatterResponseSchema = z9.object({
|
|
2964
|
+
type: z9.literal("brands/write-frontmatter/response"),
|
|
2965
|
+
payload: z9.object({
|
|
2966
|
+
requestId: z9.string(),
|
|
2967
|
+
path: z9.string(),
|
|
2760
2968
|
error: z9.string().nullable()
|
|
2761
2969
|
})
|
|
2762
2970
|
});
|
|
@@ -3310,6 +3518,7 @@ var UpdateAgentRequestMessageSchema = z10.object({
|
|
|
3310
3518
|
agentId: z10.string(),
|
|
3311
3519
|
name: z10.string().optional(),
|
|
3312
3520
|
labels: z10.record(z10.string()).optional(),
|
|
3521
|
+
internal: z10.boolean().optional(),
|
|
3313
3522
|
requestId: z10.string()
|
|
3314
3523
|
});
|
|
3315
3524
|
var SetVoiceModeMessageSchema = z10.object({
|
|
@@ -4099,6 +4308,25 @@ var FileDeleteRequestSchema = z10.object({
|
|
|
4099
4308
|
path: z10.string(),
|
|
4100
4309
|
requestId: z10.string()
|
|
4101
4310
|
});
|
|
4311
|
+
var FileExplorerDeleteRequestSchema = z10.object({
|
|
4312
|
+
type: z10.literal("file_explorer_delete_request"),
|
|
4313
|
+
cwd: z10.string(),
|
|
4314
|
+
path: z10.string(),
|
|
4315
|
+
requestId: z10.string()
|
|
4316
|
+
});
|
|
4317
|
+
var FileMkdirRequestSchema = z10.object({
|
|
4318
|
+
type: z10.literal("file_mkdir_request"),
|
|
4319
|
+
cwd: z10.string(),
|
|
4320
|
+
path: z10.string(),
|
|
4321
|
+
requestId: z10.string()
|
|
4322
|
+
});
|
|
4323
|
+
var FileMoveRequestSchema = z10.object({
|
|
4324
|
+
type: z10.literal("file_move_request"),
|
|
4325
|
+
cwd: z10.string(),
|
|
4326
|
+
sourcePath: z10.string(),
|
|
4327
|
+
destinationPath: z10.string(),
|
|
4328
|
+
requestId: z10.string()
|
|
4329
|
+
});
|
|
4102
4330
|
var ClearAgentAttentionMessageSchema = z10.object({
|
|
4103
4331
|
type: z10.literal("clear_agent_attention"),
|
|
4104
4332
|
agentId: z10.union([z10.string(), z10.array(z10.string())]),
|
|
@@ -4371,6 +4599,9 @@ var SessionInboundMessageSchema = z10.discriminatedUnion("type", [
|
|
|
4371
4599
|
FileExplorerRequestSchema,
|
|
4372
4600
|
FileWriteRequestSchema,
|
|
4373
4601
|
FileDeleteRequestSchema,
|
|
4602
|
+
FileExplorerDeleteRequestSchema,
|
|
4603
|
+
FileMkdirRequestSchema,
|
|
4604
|
+
FileMoveRequestSchema,
|
|
4374
4605
|
ProjectIconRequestSchema,
|
|
4375
4606
|
FileDownloadTokenRequestSchema,
|
|
4376
4607
|
ClearAgentAttentionMessageSchema,
|
|
@@ -4380,6 +4611,15 @@ var SessionInboundMessageSchema = z10.discriminatedUnion("type", [
|
|
|
4380
4611
|
ListSkillsRequestSchema,
|
|
4381
4612
|
CreateSkillRequestSchema,
|
|
4382
4613
|
WriteSkillFrontmatterRequestSchema,
|
|
4614
|
+
RolesListScopeRequestSchema,
|
|
4615
|
+
RoleCreateRequestSchema,
|
|
4616
|
+
RoleWriteFrontmatterRequestSchema,
|
|
4617
|
+
RoleMoveRequestSchema,
|
|
4618
|
+
BrandsListScopeRequestSchema,
|
|
4619
|
+
BrandCreateRequestSchema,
|
|
4620
|
+
BrandWriteFrontmatterRequestSchema,
|
|
4621
|
+
BrandAssetCopyRequestSchema,
|
|
4622
|
+
BrandAssetUploadRequestSchema,
|
|
4383
4623
|
RegisterPushTokenMessageSchema,
|
|
4384
4624
|
RegisterWebPushSubscriptionMessageSchema,
|
|
4385
4625
|
UnregisterWebPushSubscriptionMessageSchema,
|
|
@@ -4414,11 +4654,11 @@ var SessionInboundMessageSchema = z10.discriminatedUnion("type", [
|
|
|
4414
4654
|
LoopInspectRequestSchema,
|
|
4415
4655
|
LoopLogsRequestSchema,
|
|
4416
4656
|
LoopStopRequestSchema,
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4657
|
+
QuestRunRequestSchema,
|
|
4658
|
+
QuestListRequestSchema,
|
|
4659
|
+
QuestInspectRequestSchema,
|
|
4660
|
+
QuestStopRequestSchema,
|
|
4661
|
+
RolesListRequestSchema
|
|
4422
4662
|
]);
|
|
4423
4663
|
var ActivityLogPayloadSchema = z10.object({
|
|
4424
4664
|
id: z10.string(),
|
|
@@ -5544,6 +5784,34 @@ var FileDeleteResponseSchema = z10.object({
|
|
|
5544
5784
|
requestId: z10.string()
|
|
5545
5785
|
})
|
|
5546
5786
|
});
|
|
5787
|
+
var FileExplorerDeleteResponseSchema = z10.object({
|
|
5788
|
+
type: z10.literal("file_explorer_delete_response"),
|
|
5789
|
+
payload: z10.object({
|
|
5790
|
+
cwd: z10.string(),
|
|
5791
|
+
path: z10.string(),
|
|
5792
|
+
error: z10.string().nullable(),
|
|
5793
|
+
requestId: z10.string()
|
|
5794
|
+
})
|
|
5795
|
+
});
|
|
5796
|
+
var FileMkdirResponseSchema = z10.object({
|
|
5797
|
+
type: z10.literal("file_mkdir_response"),
|
|
5798
|
+
payload: z10.object({
|
|
5799
|
+
cwd: z10.string(),
|
|
5800
|
+
path: z10.string(),
|
|
5801
|
+
error: z10.string().nullable(),
|
|
5802
|
+
requestId: z10.string()
|
|
5803
|
+
})
|
|
5804
|
+
});
|
|
5805
|
+
var FileMoveResponseSchema = z10.object({
|
|
5806
|
+
type: z10.literal("file_move_response"),
|
|
5807
|
+
payload: z10.object({
|
|
5808
|
+
cwd: z10.string(),
|
|
5809
|
+
sourcePath: z10.string(),
|
|
5810
|
+
destinationPath: z10.string(),
|
|
5811
|
+
error: z10.string().nullable(),
|
|
5812
|
+
requestId: z10.string()
|
|
5813
|
+
})
|
|
5814
|
+
});
|
|
5547
5815
|
var ProjectIconSchema = z10.object({
|
|
5548
5816
|
data: z10.string(),
|
|
5549
5817
|
mimeType: z10.string()
|
|
@@ -5876,6 +6144,9 @@ var SessionOutboundMessageSchema = z10.discriminatedUnion("type", [
|
|
|
5876
6144
|
FileExplorerResponseSchema,
|
|
5877
6145
|
FileWriteResponseSchema,
|
|
5878
6146
|
FileDeleteResponseSchema,
|
|
6147
|
+
FileExplorerDeleteResponseSchema,
|
|
6148
|
+
FileMkdirResponseSchema,
|
|
6149
|
+
FileMoveResponseSchema,
|
|
5879
6150
|
ProjectIconResponseSchema,
|
|
5880
6151
|
FileDownloadTokenResponseSchema,
|
|
5881
6152
|
ListProviderModelsResponseMessageSchema,
|
|
@@ -5890,6 +6161,10 @@ var SessionOutboundMessageSchema = z10.discriminatedUnion("type", [
|
|
|
5890
6161
|
ListSkillsResponseSchema,
|
|
5891
6162
|
CreateSkillResponseSchema,
|
|
5892
6163
|
WriteSkillFrontmatterResponseSchema,
|
|
6164
|
+
RolesListScopeResponseSchema,
|
|
6165
|
+
RoleCreateResponseSchema,
|
|
6166
|
+
RoleWriteFrontmatterResponseSchema,
|
|
6167
|
+
RoleMoveResponseSchema,
|
|
5893
6168
|
ListTerminalsResponseSchema,
|
|
5894
6169
|
TerminalsChangedSchema,
|
|
5895
6170
|
CreateTerminalResponseSchema,
|
|
@@ -5916,11 +6191,16 @@ var SessionOutboundMessageSchema = z10.discriminatedUnion("type", [
|
|
|
5916
6191
|
LoopInspectResponseSchema,
|
|
5917
6192
|
LoopLogsResponseSchema,
|
|
5918
6193
|
LoopStopResponseSchema,
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
6194
|
+
QuestRunResponseSchema,
|
|
6195
|
+
QuestListResponseSchema,
|
|
6196
|
+
QuestInspectResponseSchema,
|
|
6197
|
+
QuestStopResponseSchema,
|
|
6198
|
+
RolesListResponseSchema,
|
|
6199
|
+
BrandsListScopeResponseSchema,
|
|
6200
|
+
BrandCreateResponseSchema,
|
|
6201
|
+
BrandWriteFrontmatterResponseSchema,
|
|
6202
|
+
BrandAssetCopyResponseSchema,
|
|
6203
|
+
BrandAssetUploadResponseSchema,
|
|
5924
6204
|
GetVapidPublicKeyResponseSchema,
|
|
5925
6205
|
LinkAccountResponseMessageSchema
|
|
5926
6206
|
]);
|
|
@@ -7887,6 +8167,12 @@ async function resolveEditorLaunch(input) {
|
|
|
7887
8167
|
if (!executable) {
|
|
7888
8168
|
throw new Error(`Editor target unavailable: ${target.label}`);
|
|
7889
8169
|
}
|
|
8170
|
+
if (input.editorId === "finder") {
|
|
8171
|
+
return {
|
|
8172
|
+
command: executable,
|
|
8173
|
+
args: ["-R", input.path]
|
|
8174
|
+
};
|
|
8175
|
+
}
|
|
7890
8176
|
return {
|
|
7891
8177
|
command: executable,
|
|
7892
8178
|
args: [input.path]
|
|
@@ -8318,14 +8604,14 @@ var DictationStreamManager = class {
|
|
|
8318
8604
|
PCM_CHANNELS,
|
|
8319
8605
|
PCM_BITS_PER_SAMPLE
|
|
8320
8606
|
);
|
|
8321
|
-
const
|
|
8607
|
+
const path24 = await maybePersistDictationDebugAudio(
|
|
8322
8608
|
wavBuffer,
|
|
8323
8609
|
{ sessionId: state.sessionId, dictationId: state.dictationId, format: "audio/wav" },
|
|
8324
8610
|
this.logger,
|
|
8325
8611
|
state.debugChunkWriter?.folder
|
|
8326
8612
|
);
|
|
8327
|
-
state.debugRecordingPath =
|
|
8328
|
-
return
|
|
8613
|
+
state.debugRecordingPath = path24;
|
|
8614
|
+
return path24;
|
|
8329
8615
|
}
|
|
8330
8616
|
failDictationStream(dictationId, error, retryable) {
|
|
8331
8617
|
this.emit({
|
|
@@ -9571,14 +9857,14 @@ function parseDiff(diffText) {
|
|
|
9571
9857
|
const firstLine = lines[0];
|
|
9572
9858
|
const isNew = section.includes("new file mode") || section.includes("--- /dev/null");
|
|
9573
9859
|
const isDeleted = section.includes("deleted file mode") || section.includes("+++ /dev/null");
|
|
9574
|
-
let
|
|
9860
|
+
let path24 = "unknown";
|
|
9575
9861
|
const pathMatch = firstLine.match(/a\/(.*?) b\//);
|
|
9576
9862
|
if (pathMatch) {
|
|
9577
|
-
|
|
9863
|
+
path24 = pathMatch[1];
|
|
9578
9864
|
} else {
|
|
9579
9865
|
const newFileMatch = firstLine.match(/b\/(.+)$/);
|
|
9580
9866
|
if (newFileMatch) {
|
|
9581
|
-
|
|
9867
|
+
path24 = newFileMatch[1];
|
|
9582
9868
|
}
|
|
9583
9869
|
}
|
|
9584
9870
|
const hunks = [];
|
|
@@ -9622,7 +9908,7 @@ function parseDiff(diffText) {
|
|
|
9622
9908
|
if (currentHunk) {
|
|
9623
9909
|
hunks.push(currentHunk);
|
|
9624
9910
|
}
|
|
9625
|
-
files.push({ path:
|
|
9911
|
+
files.push({ path: path24, isNew, isDeleted, additions, deletions, hunks });
|
|
9626
9912
|
}
|
|
9627
9913
|
return files;
|
|
9628
9914
|
}
|
|
@@ -9678,9 +9964,9 @@ function buildTokenLookup(lineMap, highlighted) {
|
|
|
9678
9964
|
}
|
|
9679
9965
|
return lookup2;
|
|
9680
9966
|
}
|
|
9681
|
-
function buildFullFileTokenLookup(fileContent,
|
|
9967
|
+
function buildFullFileTokenLookup(fileContent, path24) {
|
|
9682
9968
|
const lookup2 = /* @__PURE__ */ new Map();
|
|
9683
|
-
const highlighted = highlightCode(fileContent,
|
|
9969
|
+
const highlighted = highlightCode(fileContent, path24);
|
|
9684
9970
|
for (let i = 0; i < highlighted.length; i++) {
|
|
9685
9971
|
lookup2.set(i + 1, highlighted[i]);
|
|
9686
9972
|
}
|
|
@@ -11381,11 +11667,11 @@ async function listCheckoutFileChanges(cwd, ref, ignoreWhitespace = false) {
|
|
|
11381
11667
|
}
|
|
11382
11668
|
continue;
|
|
11383
11669
|
}
|
|
11384
|
-
const
|
|
11385
|
-
if (!
|
|
11670
|
+
const path24 = tabParts[1];
|
|
11671
|
+
if (!path24) continue;
|
|
11386
11672
|
const code = rawStatus[0];
|
|
11387
11673
|
changes.push({
|
|
11388
|
-
path:
|
|
11674
|
+
path: path24,
|
|
11389
11675
|
status: rawStatus,
|
|
11390
11676
|
isNew: code === "A",
|
|
11391
11677
|
isDeleted: code === "D"
|
|
@@ -11420,9 +11706,9 @@ async function listCheckoutFileChanges(cwd, ref, ignoreWhitespace = false) {
|
|
|
11420
11706
|
}
|
|
11421
11707
|
return Array.from(byPath.values());
|
|
11422
11708
|
}
|
|
11423
|
-
async function readGitFileContentAtRef(cwd, ref,
|
|
11709
|
+
async function readGitFileContentAtRef(cwd, ref, path24) {
|
|
11424
11710
|
try {
|
|
11425
|
-
const { stdout } = await runGitCommand(["show", `${ref}:${
|
|
11711
|
+
const { stdout } = await runGitCommand(["show", `${ref}:${path24}`], {
|
|
11426
11712
|
cwd,
|
|
11427
11713
|
env: READ_ONLY_GIT_ENV2
|
|
11428
11714
|
});
|
|
@@ -11483,21 +11769,21 @@ async function getTrackedNumstatByPath(cwd, ref, ignoreWhitespace = false) {
|
|
|
11483
11769
|
const additionsField = parts[0] ?? "";
|
|
11484
11770
|
const deletionsField = parts[1] ?? "";
|
|
11485
11771
|
const rawPath = parts.slice(2).join(" ");
|
|
11486
|
-
const
|
|
11487
|
-
if (!
|
|
11772
|
+
const path24 = normalizeNumstatPath(rawPath);
|
|
11773
|
+
if (!path24) {
|
|
11488
11774
|
continue;
|
|
11489
11775
|
}
|
|
11490
11776
|
if (additionsField === "-" || deletionsField === "-") {
|
|
11491
|
-
stats.set(
|
|
11777
|
+
stats.set(path24, { additions: 0, deletions: 0, isBinary: true });
|
|
11492
11778
|
continue;
|
|
11493
11779
|
}
|
|
11494
11780
|
const additions = Number.parseInt(additionsField, 10);
|
|
11495
11781
|
const deletions = Number.parseInt(deletionsField, 10);
|
|
11496
11782
|
if (Number.isNaN(additions) || Number.isNaN(deletions)) {
|
|
11497
|
-
stats.set(
|
|
11783
|
+
stats.set(path24, null);
|
|
11498
11784
|
continue;
|
|
11499
11785
|
}
|
|
11500
|
-
stats.set(
|
|
11786
|
+
stats.set(path24, { additions, deletions, isBinary: false });
|
|
11501
11787
|
}
|
|
11502
11788
|
return stats;
|
|
11503
11789
|
}
|
|
@@ -12082,10 +12368,10 @@ async function listUncommittedFiles(cwd) {
|
|
|
12082
12368
|
if (dest) results.push({ path: dest, changeType: code });
|
|
12083
12369
|
continue;
|
|
12084
12370
|
}
|
|
12085
|
-
const
|
|
12086
|
-
if (!
|
|
12371
|
+
const path24 = parts[1];
|
|
12372
|
+
if (!path24) continue;
|
|
12087
12373
|
if (code === "A" || code === "M" || code === "D") {
|
|
12088
|
-
results.push({ path:
|
|
12374
|
+
results.push({ path: path24, changeType: code });
|
|
12089
12375
|
}
|
|
12090
12376
|
}
|
|
12091
12377
|
} catch {
|
|
@@ -15129,6 +15415,14 @@ var CLAUDE_MODELS = [
|
|
|
15129
15415
|
isDefault: true,
|
|
15130
15416
|
thinkingOptions: [...CLAUDE_THINKING_OPTIONS]
|
|
15131
15417
|
},
|
|
15418
|
+
{
|
|
15419
|
+
provider: "claude",
|
|
15420
|
+
id: "claude-sonnet-4-6[1m]",
|
|
15421
|
+
label: "Sonnet 4.6 1M",
|
|
15422
|
+
description: "Sonnet 4.6 with 1M context window",
|
|
15423
|
+
thinkingOptions: [...CLAUDE_THINKING_OPTIONS],
|
|
15424
|
+
betas: ["context-1m-2025-08-07"]
|
|
15425
|
+
},
|
|
15132
15426
|
{
|
|
15133
15427
|
provider: "claude",
|
|
15134
15428
|
id: "claude-sonnet-4-6",
|
|
@@ -15146,6 +15440,9 @@ var CLAUDE_MODELS = [
|
|
|
15146
15440
|
function getClaudeModels() {
|
|
15147
15441
|
return CLAUDE_MODELS.map((model) => ({ ...model }));
|
|
15148
15442
|
}
|
|
15443
|
+
function getClaudeModelBetas(modelId) {
|
|
15444
|
+
return CLAUDE_MODELS.find((m) => m.id === modelId)?.betas;
|
|
15445
|
+
}
|
|
15149
15446
|
function normalizeClaudeRuntimeModelId(value) {
|
|
15150
15447
|
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
15151
15448
|
if (!trimmed) {
|
|
@@ -17728,11 +18025,18 @@ var ClaudeAgentSession = class {
|
|
|
17728
18025
|
}
|
|
17729
18026
|
if (this.config.model) {
|
|
17730
18027
|
base.model = this.config.model;
|
|
18028
|
+
const modelBetas = getClaudeModelBetas(this.config.model);
|
|
18029
|
+
if (modelBetas?.length) {
|
|
18030
|
+
base.betas = [...base.betas ?? [], ...modelBetas];
|
|
18031
|
+
}
|
|
17731
18032
|
}
|
|
17732
18033
|
this.lastOptionsModel = base.model ?? null;
|
|
17733
18034
|
if (this.claudeSessionId) {
|
|
17734
18035
|
base.resume = this.claudeSessionId;
|
|
17735
18036
|
}
|
|
18037
|
+
if (this.config.allowedTools?.length) {
|
|
18038
|
+
base.allowedTools = [...base.allowedTools ?? [], ...this.config.allowedTools];
|
|
18039
|
+
}
|
|
17736
18040
|
if (this.runtimeSettings?.disallowedTools?.length) {
|
|
17737
18041
|
base.disallowedTools = [
|
|
17738
18042
|
...base.disallowedTools ?? [],
|
|
@@ -19963,14 +20267,14 @@ function codexApplyPatchToUnifiedDiff(text) {
|
|
|
19963
20267
|
for (const line of lines) {
|
|
19964
20268
|
const directive = parseCodexApplyPatchDirective(line);
|
|
19965
20269
|
if (directive) {
|
|
19966
|
-
const
|
|
19967
|
-
if (
|
|
20270
|
+
const path24 = normalizeDiffHeaderPath(directive.path);
|
|
20271
|
+
if (path24.length > 0) {
|
|
19968
20272
|
if (output.length > 0 && output[output.length - 1] !== "") {
|
|
19969
20273
|
output.push("");
|
|
19970
20274
|
}
|
|
19971
|
-
const left = directive.kind === "add" ? "/dev/null" : `a/${
|
|
19972
|
-
const right = directive.kind === "delete" ? "/dev/null" : `b/${
|
|
19973
|
-
output.push(`diff --git a/${
|
|
20275
|
+
const left = directive.kind === "add" ? "/dev/null" : `a/${path24}`;
|
|
20276
|
+
const right = directive.kind === "delete" ? "/dev/null" : `b/${path24}`;
|
|
20277
|
+
output.push(`diff --git a/${path24} b/${path24}`);
|
|
19974
20278
|
output.push(`--- ${left}`);
|
|
19975
20279
|
output.push(`+++ ${right}`);
|
|
19976
20280
|
sawDiffContent = true;
|
|
@@ -20040,9 +20344,9 @@ function asEditTextFields(text) {
|
|
|
20040
20344
|
function normalizeRolloutEditInput(input) {
|
|
20041
20345
|
if (typeof input === "string") {
|
|
20042
20346
|
const textFields2 = asEditTextFields(input);
|
|
20043
|
-
const
|
|
20347
|
+
const path24 = extractPatchPrimaryFilePath(input);
|
|
20044
20348
|
return {
|
|
20045
|
-
...
|
|
20349
|
+
...path24 ? { path: path24 } : {},
|
|
20046
20350
|
...textFields2.unifiedDiff ? { patch: textFields2.unifiedDiff } : {},
|
|
20047
20351
|
...textFields2.newString ? { content: textFields2.newString } : {}
|
|
20048
20352
|
};
|
|
@@ -20190,12 +20494,12 @@ function parseFileChangeDiff(entry) {
|
|
|
20190
20494
|
]);
|
|
20191
20495
|
}
|
|
20192
20496
|
function toFileChangeEntry(entry, options, fallbackPath) {
|
|
20193
|
-
const
|
|
20194
|
-
if (!
|
|
20497
|
+
const path24 = parseFileChangePath(entry, options, fallbackPath);
|
|
20498
|
+
if (!path24) {
|
|
20195
20499
|
return null;
|
|
20196
20500
|
}
|
|
20197
20501
|
return {
|
|
20198
|
-
path:
|
|
20502
|
+
path: path24,
|
|
20199
20503
|
kind: parseFileChangeKind(entry),
|
|
20200
20504
|
diff: parseFileChangeDiff(entry)
|
|
20201
20505
|
};
|
|
@@ -20217,12 +20521,12 @@ function parseFileChangeEntries(changes, options) {
|
|
|
20217
20521
|
if (singleEntry) {
|
|
20218
20522
|
return [singleEntry];
|
|
20219
20523
|
}
|
|
20220
|
-
return Object.entries(changes).map(([
|
|
20524
|
+
return Object.entries(changes).map(([path24, value]) => {
|
|
20221
20525
|
if (isRecord2(value)) {
|
|
20222
|
-
return toFileChangeEntry(value, options,
|
|
20526
|
+
return toFileChangeEntry(value, options, path24);
|
|
20223
20527
|
}
|
|
20224
20528
|
if (typeof value === "string") {
|
|
20225
|
-
const normalizedPath = normalizeCodexFilePath(
|
|
20529
|
+
const normalizedPath = normalizeCodexFilePath(path24.trim(), options?.cwd);
|
|
20226
20530
|
if (!normalizedPath) {
|
|
20227
20531
|
return null;
|
|
20228
20532
|
}
|
|
@@ -20967,16 +21271,16 @@ function isObjectSchemaNode(schema) {
|
|
|
20967
21271
|
const type = schema.type;
|
|
20968
21272
|
return isSchemaRecord(schema.properties) || type === "object" || Array.isArray(type) && type.includes("object");
|
|
20969
21273
|
}
|
|
20970
|
-
function normalizeCodexOutputSchemaNode(schema,
|
|
21274
|
+
function normalizeCodexOutputSchemaNode(schema, path24) {
|
|
20971
21275
|
if (Array.isArray(schema)) {
|
|
20972
|
-
return schema.map((entry, index) => normalizeCodexOutputSchemaNode(entry, `${
|
|
21276
|
+
return schema.map((entry, index) => normalizeCodexOutputSchemaNode(entry, `${path24}[${index}]`));
|
|
20973
21277
|
}
|
|
20974
21278
|
if (!isSchemaRecord(schema)) {
|
|
20975
21279
|
return schema;
|
|
20976
21280
|
}
|
|
20977
21281
|
const normalized = {};
|
|
20978
21282
|
for (const [key, value] of Object.entries(schema)) {
|
|
20979
|
-
normalized[key] = normalizeCodexOutputSchemaNode(value, `${
|
|
21283
|
+
normalized[key] = normalizeCodexOutputSchemaNode(value, `${path24}.${key}`);
|
|
20980
21284
|
}
|
|
20981
21285
|
if (!isObjectSchemaNode(normalized)) {
|
|
20982
21286
|
return normalized;
|
|
@@ -20985,7 +21289,7 @@ function normalizeCodexOutputSchemaNode(schema, path23) {
|
|
|
20985
21289
|
normalized.additionalProperties = false;
|
|
20986
21290
|
} else if (normalized.additionalProperties !== false) {
|
|
20987
21291
|
throw new Error(
|
|
20988
|
-
`Codex structured outputs require ${
|
|
21292
|
+
`Codex structured outputs require ${path24} to set additionalProperties to false for object schemas.`
|
|
20989
21293
|
);
|
|
20990
21294
|
}
|
|
20991
21295
|
const properties = isSchemaRecord(normalized.properties) ? normalized.properties : null;
|
|
@@ -21747,8 +22051,8 @@ function parseCodexPatchChanges(changes) {
|
|
|
21747
22051
|
}
|
|
21748
22052
|
];
|
|
21749
22053
|
}
|
|
21750
|
-
return Object.entries(recordChanges).map(([
|
|
21751
|
-
const normalizedPath =
|
|
22054
|
+
return Object.entries(recordChanges).map(([path24, value]) => {
|
|
22055
|
+
const normalizedPath = path24.trim();
|
|
21752
22056
|
if (!normalizedPath) {
|
|
21753
22057
|
return null;
|
|
21754
22058
|
}
|
|
@@ -29497,8 +29801,8 @@ function buildZodValidator(schema, schemaName) {
|
|
|
29497
29801
|
return { ok: true, value: result.data };
|
|
29498
29802
|
}
|
|
29499
29803
|
const errors = result.error.issues.map((issue) => {
|
|
29500
|
-
const
|
|
29501
|
-
return `${
|
|
29804
|
+
const path24 = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
29805
|
+
return `${path24}: ${issue.message}`;
|
|
29502
29806
|
});
|
|
29503
29807
|
return { ok: false, errors };
|
|
29504
29808
|
}
|
|
@@ -29516,9 +29820,9 @@ function buildJsonSchemaValidator(schema) {
|
|
|
29516
29820
|
return { ok: true, value };
|
|
29517
29821
|
}
|
|
29518
29822
|
const errors = (validate.errors ?? []).map((error) => {
|
|
29519
|
-
const
|
|
29823
|
+
const path24 = error.instancePath && error.instancePath.length > 0 ? error.instancePath : "(root)";
|
|
29520
29824
|
const message = error.message ?? "is invalid";
|
|
29521
|
-
return `${
|
|
29825
|
+
return `${path24}: ${message}`;
|
|
29522
29826
|
});
|
|
29523
29827
|
return { ok: false, errors };
|
|
29524
29828
|
}
|
|
@@ -30440,6 +30744,12 @@ var IMAGE_MIME_TYPES = {
|
|
|
30440
30744
|
".webp": "image/webp",
|
|
30441
30745
|
".svg": "image/svg+xml"
|
|
30442
30746
|
};
|
|
30747
|
+
var FONT_MIME_TYPES = {
|
|
30748
|
+
".ttf": "font/ttf",
|
|
30749
|
+
".otf": "font/otf",
|
|
30750
|
+
".woff": "font/woff",
|
|
30751
|
+
".woff2": "font/woff2"
|
|
30752
|
+
};
|
|
30443
30753
|
async function listDirectoryEntries({
|
|
30444
30754
|
root,
|
|
30445
30755
|
relativePath = "."
|
|
@@ -30550,6 +30860,23 @@ async function deleteFile({ root, relativePath }) {
|
|
|
30550
30860
|
}
|
|
30551
30861
|
await fs5.unlink(filePath);
|
|
30552
30862
|
}
|
|
30863
|
+
async function deleteEntry({ root, relativePath }) {
|
|
30864
|
+
const entryPath = await resolveScopedPath({ root, relativePath });
|
|
30865
|
+
await fs5.rm(entryPath, { recursive: true, force: false });
|
|
30866
|
+
}
|
|
30867
|
+
async function createDirectory({ root, relativePath }) {
|
|
30868
|
+
const dirPath = await resolveScopedPath({ root, relativePath });
|
|
30869
|
+
await fs5.mkdir(dirPath, { recursive: true });
|
|
30870
|
+
}
|
|
30871
|
+
async function moveEntry({
|
|
30872
|
+
root,
|
|
30873
|
+
sourcePath,
|
|
30874
|
+
destinationPath
|
|
30875
|
+
}) {
|
|
30876
|
+
const src = await resolveScopedPath({ root, relativePath: sourcePath });
|
|
30877
|
+
const dest = await resolveScopedPath({ root, relativePath: destinationPath });
|
|
30878
|
+
await fs5.rename(src, dest);
|
|
30879
|
+
}
|
|
30553
30880
|
async function getDownloadableFileInfo({ root, relativePath }) {
|
|
30554
30881
|
const filePath = await resolveScopedPath({ root, relativePath });
|
|
30555
30882
|
const stats = await fs5.stat(filePath);
|
|
@@ -30559,7 +30886,9 @@ async function getDownloadableFileInfo({ root, relativePath }) {
|
|
|
30559
30886
|
const ext = path10.extname(filePath).toLowerCase();
|
|
30560
30887
|
let mimeType = "application/octet-stream";
|
|
30561
30888
|
if (ext in IMAGE_MIME_TYPES) {
|
|
30562
|
-
mimeType = IMAGE_MIME_TYPES[ext];
|
|
30889
|
+
mimeType = IMAGE_MIME_TYPES[ext] ?? mimeType;
|
|
30890
|
+
} else if (ext in FONT_MIME_TYPES) {
|
|
30891
|
+
mimeType = FONT_MIME_TYPES[ext] ?? mimeType;
|
|
30563
30892
|
} else {
|
|
30564
30893
|
const handle = await fs5.open(filePath, "r");
|
|
30565
30894
|
const sample = Buffer.alloc(8192);
|
|
@@ -30980,15 +31309,15 @@ async function getProjectIcon(projectDir) {
|
|
|
30980
31309
|
|
|
30981
31310
|
// ../server/src/utils/path.ts
|
|
30982
31311
|
import os5 from "os";
|
|
30983
|
-
function expandTilde(
|
|
30984
|
-
if (
|
|
31312
|
+
function expandTilde(path24) {
|
|
31313
|
+
if (path24.startsWith("~/")) {
|
|
30985
31314
|
const homeDir3 = process.env.HOME || os5.homedir();
|
|
30986
|
-
return
|
|
31315
|
+
return path24.replace("~", homeDir3);
|
|
30987
31316
|
}
|
|
30988
|
-
if (
|
|
31317
|
+
if (path24 === "~") {
|
|
30989
31318
|
return process.env.HOME || os5.homedir();
|
|
30990
31319
|
}
|
|
30991
|
-
return
|
|
31320
|
+
return path24;
|
|
30992
31321
|
}
|
|
30993
31322
|
|
|
30994
31323
|
// ../server/src/server/skills/scanner.ts
|
|
@@ -32166,7 +32495,7 @@ function buildChatMentionNotification(input) {
|
|
|
32166
32495
|
].join("\n");
|
|
32167
32496
|
}
|
|
32168
32497
|
|
|
32169
|
-
// ../server/src/server/
|
|
32498
|
+
// ../server/src/server/roles/scanner.ts
|
|
32170
32499
|
import fs7 from "node:fs/promises";
|
|
32171
32500
|
import os7 from "node:os";
|
|
32172
32501
|
import path14 from "node:path";
|
|
@@ -32179,11 +32508,41 @@ function resolveScopeDir2(scope, workspaceRoot) {
|
|
|
32179
32508
|
if (!workspaceRoot) {
|
|
32180
32509
|
throw new Error('workspaceRoot is required for scope "project"');
|
|
32181
32510
|
}
|
|
32182
|
-
return path14.join(workspaceRoot, ".
|
|
32511
|
+
return path14.join(workspaceRoot, ".roles");
|
|
32183
32512
|
}
|
|
32184
|
-
return path14.join(homeDir2(), ".appostle", ".
|
|
32513
|
+
return path14.join(homeDir2(), ".appostle", ".roles");
|
|
32514
|
+
}
|
|
32515
|
+
function allowedRoots2(workspaceRoot) {
|
|
32516
|
+
const roots = [path14.join(homeDir2(), ".appostle", ".roles")];
|
|
32517
|
+
if (workspaceRoot) {
|
|
32518
|
+
roots.push(path14.join(workspaceRoot, ".roles"));
|
|
32519
|
+
}
|
|
32520
|
+
return roots.map((r) => path14.resolve(r));
|
|
32521
|
+
}
|
|
32522
|
+
function isInsideAllowedRoot2(absPath, workspaceRoot) {
|
|
32523
|
+
const resolved = path14.resolve(absPath);
|
|
32524
|
+
for (const root of allowedRoots2(workspaceRoot)) {
|
|
32525
|
+
const rel = path14.relative(root, resolved);
|
|
32526
|
+
if (rel === "" || !rel.startsWith("..") && !path14.isAbsolute(rel)) {
|
|
32527
|
+
return true;
|
|
32528
|
+
}
|
|
32529
|
+
}
|
|
32530
|
+
return false;
|
|
32185
32531
|
}
|
|
32186
32532
|
var FRONTMATTER_RE2 = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
32533
|
+
function parseRoleFile(text) {
|
|
32534
|
+
const match = FRONTMATTER_RE2.exec(text);
|
|
32535
|
+
if (!match) {
|
|
32536
|
+
return { rawFrontmatterLines: [], body: text, hadFrontmatter: false };
|
|
32537
|
+
}
|
|
32538
|
+
const yamlBlock = match[1] ?? "";
|
|
32539
|
+
const body = match[2] ?? "";
|
|
32540
|
+
return {
|
|
32541
|
+
rawFrontmatterLines: yamlBlock.split(/\r?\n/),
|
|
32542
|
+
body,
|
|
32543
|
+
hadFrontmatter: true
|
|
32544
|
+
};
|
|
32545
|
+
}
|
|
32187
32546
|
function unquote(value) {
|
|
32188
32547
|
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
32189
32548
|
return value.slice(1, -1);
|
|
@@ -32191,36 +32550,165 @@ function unquote(value) {
|
|
|
32191
32550
|
return value;
|
|
32192
32551
|
}
|
|
32193
32552
|
function parseFrontmatter(text) {
|
|
32194
|
-
const match = FRONTMATTER_RE2.exec(text);
|
|
32195
32553
|
const empty = {
|
|
32196
32554
|
description: "",
|
|
32197
|
-
|
|
32198
|
-
|
|
32199
|
-
|
|
32555
|
+
triggerWords: [],
|
|
32556
|
+
allowedTools: [],
|
|
32557
|
+
provider: "",
|
|
32558
|
+
model: "",
|
|
32559
|
+
mode: ""
|
|
32200
32560
|
};
|
|
32201
|
-
|
|
32202
|
-
|
|
32203
|
-
}
|
|
32204
|
-
const lines = (match[1] ?? "").split(/\r?\n/);
|
|
32561
|
+
const { rawFrontmatterLines: lines, hadFrontmatter } = parseRoleFile(text);
|
|
32562
|
+
if (!hadFrontmatter) return empty;
|
|
32205
32563
|
const out = { ...empty };
|
|
32206
|
-
|
|
32564
|
+
let i = 0;
|
|
32565
|
+
while (i < lines.length) {
|
|
32566
|
+
const line = lines[i] ?? "";
|
|
32207
32567
|
const m = /^([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*)$/.exec(line);
|
|
32208
|
-
if (!m)
|
|
32568
|
+
if (!m) {
|
|
32569
|
+
i++;
|
|
32570
|
+
continue;
|
|
32571
|
+
}
|
|
32209
32572
|
const key = m[1];
|
|
32210
32573
|
const value = unquote((m[2] ?? "").trim());
|
|
32211
32574
|
if (key === "description") {
|
|
32212
32575
|
out.description = value;
|
|
32213
32576
|
} else if (key === "provider") {
|
|
32214
|
-
out.provider = value
|
|
32577
|
+
out.provider = value;
|
|
32215
32578
|
} else if (key === "model") {
|
|
32216
|
-
out.model = value
|
|
32579
|
+
out.model = value;
|
|
32217
32580
|
} else if (key === "mode") {
|
|
32218
|
-
out.mode = value
|
|
32581
|
+
out.mode = value;
|
|
32582
|
+
} else if (key === "trigger-words" || key === "allowed-tools") {
|
|
32583
|
+
const target = key === "trigger-words" ? "triggerWords" : "allowedTools";
|
|
32584
|
+
if (value) {
|
|
32585
|
+
out[target] = value.replace(/^\[|\]$/g, "").split(",").map((s) => unquote(s.trim())).filter((s) => s.length > 0);
|
|
32586
|
+
} else {
|
|
32587
|
+
const items = [];
|
|
32588
|
+
let j = i + 1;
|
|
32589
|
+
while (j < lines.length) {
|
|
32590
|
+
const next = lines[j] ?? "";
|
|
32591
|
+
const itemMatch = /^\s+-\s+(.+)$/.exec(next);
|
|
32592
|
+
if (!itemMatch) break;
|
|
32593
|
+
items.push(unquote(itemMatch[1].trim()));
|
|
32594
|
+
j++;
|
|
32595
|
+
}
|
|
32596
|
+
out[target] = items;
|
|
32597
|
+
i = j;
|
|
32598
|
+
continue;
|
|
32599
|
+
}
|
|
32600
|
+
}
|
|
32601
|
+
i++;
|
|
32602
|
+
}
|
|
32603
|
+
return out;
|
|
32604
|
+
}
|
|
32605
|
+
var OWNED_KEYS = [
|
|
32606
|
+
"name",
|
|
32607
|
+
"category",
|
|
32608
|
+
"description",
|
|
32609
|
+
"trigger-words",
|
|
32610
|
+
"allowed-tools",
|
|
32611
|
+
"provider",
|
|
32612
|
+
"model",
|
|
32613
|
+
"mode"
|
|
32614
|
+
];
|
|
32615
|
+
function findOwnedSpans2(lines) {
|
|
32616
|
+
const spans = [];
|
|
32617
|
+
let i = 0;
|
|
32618
|
+
while (i < lines.length) {
|
|
32619
|
+
const line = lines[i] ?? "";
|
|
32620
|
+
const keyMatch = /^([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*)$/.exec(line);
|
|
32621
|
+
if (!keyMatch) {
|
|
32622
|
+
i++;
|
|
32623
|
+
continue;
|
|
32624
|
+
}
|
|
32625
|
+
const key = keyMatch[1];
|
|
32626
|
+
const value = keyMatch[2];
|
|
32627
|
+
if (!OWNED_KEYS.includes(key)) {
|
|
32628
|
+
i++;
|
|
32629
|
+
continue;
|
|
32630
|
+
}
|
|
32631
|
+
let end = i + 1;
|
|
32632
|
+
if (value === "") {
|
|
32633
|
+
while (end < lines.length) {
|
|
32634
|
+
const next = lines[end] ?? "";
|
|
32635
|
+
if (/^\s+-\s+/.test(next) || /^\s*$/.test(next)) {
|
|
32636
|
+
end++;
|
|
32637
|
+
} else {
|
|
32638
|
+
break;
|
|
32639
|
+
}
|
|
32640
|
+
}
|
|
32641
|
+
}
|
|
32642
|
+
spans.push({ key, startLine: i, endLine: end });
|
|
32643
|
+
i = end;
|
|
32644
|
+
}
|
|
32645
|
+
return spans;
|
|
32646
|
+
}
|
|
32647
|
+
function emitFrontmatterValue2(key, value) {
|
|
32648
|
+
if (key === "trigger-words" || key === "allowed-tools") {
|
|
32649
|
+
if (!Array.isArray(value) || value.length === 0) return [];
|
|
32650
|
+
return [`${key}:`, ...value.map((v) => ` - ${v}`)];
|
|
32651
|
+
}
|
|
32652
|
+
const text = typeof value === "string" ? value : "";
|
|
32653
|
+
if (text.length === 0) return [];
|
|
32654
|
+
const needsQuote = /[:#\n]/.test(text) || text.startsWith(" ") || text.endsWith(" ");
|
|
32655
|
+
const formatted = needsQuote ? `"${text.replace(/"/g, '\\"')}"` : text;
|
|
32656
|
+
return [`${key}: ${formatted}`];
|
|
32657
|
+
}
|
|
32658
|
+
function rewriteFrontmatter2(originalLines, next) {
|
|
32659
|
+
const spans = findOwnedSpans2(originalLines);
|
|
32660
|
+
const ownedKeys = new Set(spans.map((s) => s.key));
|
|
32661
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
32662
|
+
if (next.name !== void 0) {
|
|
32663
|
+
replacements.set("name", emitFrontmatterValue2("name", next.name));
|
|
32664
|
+
}
|
|
32665
|
+
if (next.category !== void 0) {
|
|
32666
|
+
replacements.set("category", emitFrontmatterValue2("category", next.category));
|
|
32667
|
+
}
|
|
32668
|
+
if (next.description !== void 0) {
|
|
32669
|
+
replacements.set("description", emitFrontmatterValue2("description", next.description));
|
|
32670
|
+
}
|
|
32671
|
+
if (next.triggerWords !== void 0) {
|
|
32672
|
+
replacements.set("trigger-words", emitFrontmatterValue2("trigger-words", next.triggerWords));
|
|
32673
|
+
}
|
|
32674
|
+
if (next.allowedTools !== void 0) {
|
|
32675
|
+
replacements.set("allowed-tools", emitFrontmatterValue2("allowed-tools", next.allowedTools));
|
|
32676
|
+
}
|
|
32677
|
+
if (next.provider !== void 0) {
|
|
32678
|
+
replacements.set("provider", emitFrontmatterValue2("provider", next.provider));
|
|
32679
|
+
}
|
|
32680
|
+
if (next.model !== void 0) {
|
|
32681
|
+
replacements.set("model", emitFrontmatterValue2("model", next.model));
|
|
32682
|
+
}
|
|
32683
|
+
if (next.mode !== void 0) {
|
|
32684
|
+
replacements.set("mode", emitFrontmatterValue2("mode", next.mode));
|
|
32685
|
+
}
|
|
32686
|
+
const out = [];
|
|
32687
|
+
let i = 0;
|
|
32688
|
+
while (i < originalLines.length) {
|
|
32689
|
+
const span = spans.find((s) => s.startLine === i);
|
|
32690
|
+
if (span) {
|
|
32691
|
+
if (replacements.has(span.key)) {
|
|
32692
|
+
out.push(...replacements.get(span.key) ?? []);
|
|
32693
|
+
} else {
|
|
32694
|
+
for (let j = span.startLine; j < span.endLine; j++) {
|
|
32695
|
+
out.push(originalLines[j] ?? "");
|
|
32696
|
+
}
|
|
32697
|
+
}
|
|
32698
|
+
i = span.endLine;
|
|
32699
|
+
continue;
|
|
32700
|
+
}
|
|
32701
|
+
out.push(originalLines[i] ?? "");
|
|
32702
|
+
i++;
|
|
32703
|
+
}
|
|
32704
|
+
for (const key of OWNED_KEYS) {
|
|
32705
|
+
if (replacements.has(key) && !ownedKeys.has(key)) {
|
|
32706
|
+
out.push(...replacements.get(key) ?? []);
|
|
32219
32707
|
}
|
|
32220
32708
|
}
|
|
32221
32709
|
return out;
|
|
32222
32710
|
}
|
|
32223
|
-
async function readRolesFromDir(scope, dir) {
|
|
32711
|
+
async function readRolesFromDir(scope, dir, category) {
|
|
32224
32712
|
let entries;
|
|
32225
32713
|
try {
|
|
32226
32714
|
entries = await fs7.readdir(dir, { withFileTypes: true });
|
|
@@ -32246,13 +32734,23 @@ async function readRolesFromDir(scope, dir) {
|
|
|
32246
32734
|
const text = await fs7.readFile(fullPath, "utf8");
|
|
32247
32735
|
parsed = parseFrontmatter(text);
|
|
32248
32736
|
} catch {
|
|
32249
|
-
parsed = {
|
|
32737
|
+
parsed = {
|
|
32738
|
+
description: "",
|
|
32739
|
+
triggerWords: [],
|
|
32740
|
+
allowedTools: [],
|
|
32741
|
+
provider: "",
|
|
32742
|
+
model: "",
|
|
32743
|
+
mode: ""
|
|
32744
|
+
};
|
|
32250
32745
|
}
|
|
32746
|
+
const id = category ? `${scope}:${category}/${name}` : `${scope}:${name}`;
|
|
32251
32747
|
results.push({
|
|
32252
|
-
id
|
|
32748
|
+
id,
|
|
32253
32749
|
scope,
|
|
32750
|
+
category,
|
|
32254
32751
|
name,
|
|
32255
32752
|
description: parsed.description,
|
|
32753
|
+
triggerWords: parsed.triggerWords,
|
|
32256
32754
|
provider: parsed.provider,
|
|
32257
32755
|
model: parsed.model,
|
|
32258
32756
|
mode: parsed.mode,
|
|
@@ -32261,16 +32759,620 @@ async function readRolesFromDir(scope, dir) {
|
|
|
32261
32759
|
size: stat5.size
|
|
32262
32760
|
});
|
|
32263
32761
|
}
|
|
32762
|
+
results.sort((a, b) => a.name.localeCompare(b.name));
|
|
32264
32763
|
return results;
|
|
32265
32764
|
}
|
|
32266
|
-
async function
|
|
32267
|
-
|
|
32268
|
-
|
|
32269
|
-
|
|
32270
|
-
|
|
32271
|
-
|
|
32765
|
+
async function readRolesFromScopeDir(scope, scopeDir) {
|
|
32766
|
+
let topEntries;
|
|
32767
|
+
try {
|
|
32768
|
+
topEntries = await fs7.readdir(scopeDir, { withFileTypes: true });
|
|
32769
|
+
} catch {
|
|
32770
|
+
return [];
|
|
32771
|
+
}
|
|
32772
|
+
const flat = await readRolesFromDir(scope, scopeDir, null);
|
|
32773
|
+
const categoryResults = await Promise.all(
|
|
32774
|
+
topEntries.filter((e) => e.isDirectory() && NAME_REGEX2.test(e.name)).map((e) => readRolesFromDir(scope, path14.join(scopeDir, e.name), e.name))
|
|
32775
|
+
);
|
|
32776
|
+
const all = [...flat, ...categoryResults.flat()];
|
|
32777
|
+
all.sort((a, b) => {
|
|
32778
|
+
const catA = a.category ?? "";
|
|
32779
|
+
const catB = b.category ?? "";
|
|
32780
|
+
if (catA !== catB) return catA.localeCompare(catB);
|
|
32781
|
+
return a.name.localeCompare(b.name);
|
|
32782
|
+
});
|
|
32783
|
+
return all;
|
|
32784
|
+
}
|
|
32785
|
+
async function listRoles(args) {
|
|
32786
|
+
if (args.scope === "project") {
|
|
32787
|
+
return readRolesFromScopeDir("project", resolveScopeDir2("project", args.workspaceRoot));
|
|
32788
|
+
}
|
|
32789
|
+
if (args.scope === "global") {
|
|
32790
|
+
return readRolesFromScopeDir("global", resolveScopeDir2("global"));
|
|
32791
|
+
}
|
|
32792
|
+
const project = args.workspaceRoot ? await readRolesFromScopeDir("project", resolveScopeDir2("project", args.workspaceRoot)) : [];
|
|
32793
|
+
const global = await readRolesFromScopeDir("global", resolveScopeDir2("global"));
|
|
32794
|
+
const projectIds = new Set(project.map((r) => r.id));
|
|
32795
|
+
const merged = [...project, ...global.filter((r) => !projectIds.has(r.id))];
|
|
32796
|
+
merged.sort((a, b) => {
|
|
32797
|
+
const catA = a.category ?? "";
|
|
32798
|
+
const catB = b.category ?? "";
|
|
32799
|
+
if (catA !== catB) return catA.localeCompare(catB);
|
|
32800
|
+
return a.name.localeCompare(b.name);
|
|
32801
|
+
});
|
|
32272
32802
|
return merged;
|
|
32273
32803
|
}
|
|
32804
|
+
async function createRole(args) {
|
|
32805
|
+
if (!NAME_REGEX2.test(args.name)) {
|
|
32806
|
+
throw new Error(
|
|
32807
|
+
`Invalid role name "${args.name}". Use letters, digits, dot, underscore, dash.`
|
|
32808
|
+
);
|
|
32809
|
+
}
|
|
32810
|
+
if (args.name.includes("/") || args.name.includes("\\") || args.name.includes("..")) {
|
|
32811
|
+
throw new Error(`Role name must not contain path separators or "..".`);
|
|
32812
|
+
}
|
|
32813
|
+
const scopeDir = resolveScopeDir2(args.scope, args.workspaceRoot);
|
|
32814
|
+
const dir = args.category ? path14.join(scopeDir, args.category) : scopeDir;
|
|
32815
|
+
await fs7.mkdir(dir, { recursive: true });
|
|
32816
|
+
const filePath = path14.join(dir, `${args.name}.md`);
|
|
32817
|
+
try {
|
|
32818
|
+
await fs7.access(filePath);
|
|
32819
|
+
throw new Error(`A role named "${args.name}" already exists at ${filePath}`);
|
|
32820
|
+
} catch (err) {
|
|
32821
|
+
if (err && typeof err === "object" && "code" in err && err.code !== "ENOENT") {
|
|
32822
|
+
throw err;
|
|
32823
|
+
}
|
|
32824
|
+
if (err instanceof Error && err.message.includes("already exists")) {
|
|
32825
|
+
throw err;
|
|
32826
|
+
}
|
|
32827
|
+
}
|
|
32828
|
+
const initial = buildStarterRole(args.name);
|
|
32829
|
+
await fs7.writeFile(filePath, initial, "utf8");
|
|
32830
|
+
return { path: filePath };
|
|
32831
|
+
}
|
|
32832
|
+
function buildStarterRole(name) {
|
|
32833
|
+
return `---
|
|
32834
|
+
name: ${name}
|
|
32835
|
+
description: ""
|
|
32836
|
+
trigger-words: []
|
|
32837
|
+
allowed-tools: []
|
|
32838
|
+
provider: claude/opus
|
|
32839
|
+
mode: default
|
|
32840
|
+
---
|
|
32841
|
+
|
|
32842
|
+
# ${name}
|
|
32843
|
+
|
|
32844
|
+
You are a ${name}. Describe the role's behavior, scope, and any constraints
|
|
32845
|
+
here. The body of this file is loaded as the agent's system prompt when
|
|
32846
|
+
the role is invoked.
|
|
32847
|
+
`;
|
|
32848
|
+
}
|
|
32849
|
+
async function writeRoleFrontmatter(args, workspaceRoot) {
|
|
32850
|
+
if (!path14.isAbsolute(args.path)) {
|
|
32851
|
+
throw new Error(`writeRoleFrontmatter expects an absolute path; got "${args.path}"`);
|
|
32852
|
+
}
|
|
32853
|
+
if (!isInsideAllowedRoot2(args.path, workspaceRoot)) {
|
|
32854
|
+
throw new Error(`Path "${args.path}" is not inside an allowlisted role root`);
|
|
32855
|
+
}
|
|
32856
|
+
let original;
|
|
32857
|
+
try {
|
|
32858
|
+
original = await fs7.readFile(args.path, "utf8");
|
|
32859
|
+
} catch (err) {
|
|
32860
|
+
throw new Error(
|
|
32861
|
+
`Failed to read role file: ${err instanceof Error ? err.message : String(err)}`
|
|
32862
|
+
);
|
|
32863
|
+
}
|
|
32864
|
+
const parsed = parseRoleFile(original);
|
|
32865
|
+
const newLines = rewriteFrontmatter2(parsed.rawFrontmatterLines, args.frontmatter);
|
|
32866
|
+
const nextFrontmatter = ["---", ...newLines, "---"].join("\n");
|
|
32867
|
+
const nextContent = parsed.hadFrontmatter ? `${nextFrontmatter}
|
|
32868
|
+
${parsed.body}` : `${nextFrontmatter}
|
|
32869
|
+
|
|
32870
|
+
${original}`;
|
|
32871
|
+
await fs7.writeFile(args.path, nextContent, "utf8");
|
|
32872
|
+
}
|
|
32873
|
+
async function moveRole(args, workspaceRoot) {
|
|
32874
|
+
if (!path14.isAbsolute(args.path)) {
|
|
32875
|
+
throw new Error(`moveRole expects an absolute path; got "${args.path}"`);
|
|
32876
|
+
}
|
|
32877
|
+
if (!isInsideAllowedRoot2(args.path, workspaceRoot)) {
|
|
32878
|
+
throw new Error(`Path "${args.path}" is not inside an allowlisted role root`);
|
|
32879
|
+
}
|
|
32880
|
+
const oldDir = path14.dirname(args.path);
|
|
32881
|
+
const oldFilename = path14.basename(args.path, ".md");
|
|
32882
|
+
const roots = allowedRoots2(workspaceRoot);
|
|
32883
|
+
const rolesRoot = roots.find((r) => path14.resolve(args.path).startsWith(r));
|
|
32884
|
+
if (!rolesRoot) {
|
|
32885
|
+
throw new Error(`Cannot determine roles root for "${args.path}"`);
|
|
32886
|
+
}
|
|
32887
|
+
const relFromRoot = path14.relative(rolesRoot, path14.dirname(args.path));
|
|
32888
|
+
const currentCategory = relFromRoot && relFromRoot !== "." ? relFromRoot : "";
|
|
32889
|
+
const newName = args.newName ?? oldFilename;
|
|
32890
|
+
const newCategory = args.newCategory !== void 0 ? args.newCategory : currentCategory;
|
|
32891
|
+
if (!NAME_REGEX2.test(newName)) {
|
|
32892
|
+
throw new Error(`Invalid role name: "${newName}"`);
|
|
32893
|
+
}
|
|
32894
|
+
if (newCategory && !NAME_REGEX2.test(newCategory)) {
|
|
32895
|
+
throw new Error(`Invalid category name: "${newCategory}"`);
|
|
32896
|
+
}
|
|
32897
|
+
const newDir = newCategory ? path14.join(rolesRoot, newCategory) : rolesRoot;
|
|
32898
|
+
const newPath = path14.join(newDir, `${newName}.md`);
|
|
32899
|
+
if (path14.resolve(newPath) === path14.resolve(args.path)) {
|
|
32900
|
+
return { path: args.path };
|
|
32901
|
+
}
|
|
32902
|
+
await fs7.mkdir(newDir, { recursive: true });
|
|
32903
|
+
try {
|
|
32904
|
+
await fs7.access(newPath);
|
|
32905
|
+
throw new Error(`A role already exists at "${newPath}"`);
|
|
32906
|
+
} catch (err) {
|
|
32907
|
+
if (err.code !== "ENOENT") throw err;
|
|
32908
|
+
}
|
|
32909
|
+
await fs7.rename(args.path, newPath);
|
|
32910
|
+
const frontmatterPatch = {};
|
|
32911
|
+
if (newName !== oldFilename) {
|
|
32912
|
+
frontmatterPatch.description = void 0;
|
|
32913
|
+
}
|
|
32914
|
+
await writeRoleFrontmatter(
|
|
32915
|
+
{
|
|
32916
|
+
path: newPath,
|
|
32917
|
+
frontmatter: {
|
|
32918
|
+
...newName !== oldFilename ? { name: newName } : {}
|
|
32919
|
+
}
|
|
32920
|
+
},
|
|
32921
|
+
workspaceRoot
|
|
32922
|
+
);
|
|
32923
|
+
if (oldDir !== rolesRoot) {
|
|
32924
|
+
try {
|
|
32925
|
+
const remaining = await fs7.readdir(oldDir);
|
|
32926
|
+
if (remaining.length === 0) {
|
|
32927
|
+
await fs7.rmdir(oldDir);
|
|
32928
|
+
}
|
|
32929
|
+
} catch {
|
|
32930
|
+
}
|
|
32931
|
+
}
|
|
32932
|
+
return { path: newPath };
|
|
32933
|
+
}
|
|
32934
|
+
|
|
32935
|
+
// ../server/src/server/brands/scanner.ts
|
|
32936
|
+
import fs8 from "node:fs/promises";
|
|
32937
|
+
import path15 from "node:path";
|
|
32938
|
+
var NAME_REGEX3 = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
32939
|
+
function resolveScopeDir3(scope, workspaceRoot) {
|
|
32940
|
+
if (scope === "project") {
|
|
32941
|
+
if (!workspaceRoot) {
|
|
32942
|
+
throw new Error('workspaceRoot is required for scope "project"');
|
|
32943
|
+
}
|
|
32944
|
+
return path15.join(workspaceRoot, ".brand");
|
|
32945
|
+
}
|
|
32946
|
+
throw new Error(`Unknown scope: ${scope}`);
|
|
32947
|
+
}
|
|
32948
|
+
function allowedRoots3(workspaceRoot) {
|
|
32949
|
+
const roots = [];
|
|
32950
|
+
if (workspaceRoot) {
|
|
32951
|
+
roots.push(path15.join(workspaceRoot, ".brand"));
|
|
32952
|
+
}
|
|
32953
|
+
return roots.map((r) => path15.resolve(r));
|
|
32954
|
+
}
|
|
32955
|
+
function isInsideAllowedRoot3(absPath, workspaceRoot) {
|
|
32956
|
+
const resolved = path15.resolve(absPath);
|
|
32957
|
+
for (const root of allowedRoots3(workspaceRoot)) {
|
|
32958
|
+
const rel = path15.relative(root, resolved);
|
|
32959
|
+
if (rel === "" || !rel.startsWith("..") && !path15.isAbsolute(rel)) {
|
|
32960
|
+
return true;
|
|
32961
|
+
}
|
|
32962
|
+
}
|
|
32963
|
+
return false;
|
|
32964
|
+
}
|
|
32965
|
+
var FRONTMATTER_RE3 = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
32966
|
+
function parseBrandFile(text) {
|
|
32967
|
+
const match = FRONTMATTER_RE3.exec(text);
|
|
32968
|
+
if (!match) {
|
|
32969
|
+
return { rawFrontmatterLines: [], body: text, hadFrontmatter: false };
|
|
32970
|
+
}
|
|
32971
|
+
return {
|
|
32972
|
+
rawFrontmatterLines: (match[1] ?? "").split(/\r?\n/),
|
|
32973
|
+
body: match[2] ?? "",
|
|
32974
|
+
hadFrontmatter: true
|
|
32975
|
+
};
|
|
32976
|
+
}
|
|
32977
|
+
function unquote2(value) {
|
|
32978
|
+
const trimmed = value.trim();
|
|
32979
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
32980
|
+
return trimmed.slice(1, -1);
|
|
32981
|
+
}
|
|
32982
|
+
return trimmed;
|
|
32983
|
+
}
|
|
32984
|
+
function quoteIfNeeded(value) {
|
|
32985
|
+
if (/[:#\n\[\]]/.test(value) || value.startsWith(" ") || value.endsWith(" ")) {
|
|
32986
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
32987
|
+
}
|
|
32988
|
+
return value;
|
|
32989
|
+
}
|
|
32990
|
+
function parseFrontmatter2(lines) {
|
|
32991
|
+
const result = {
|
|
32992
|
+
description: "",
|
|
32993
|
+
tags: [],
|
|
32994
|
+
variables: []
|
|
32995
|
+
};
|
|
32996
|
+
let i = 0;
|
|
32997
|
+
while (i < lines.length) {
|
|
32998
|
+
const line = lines[i] ?? "";
|
|
32999
|
+
const keyMatch = /^([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*)$/.exec(line);
|
|
33000
|
+
if (!keyMatch) {
|
|
33001
|
+
i++;
|
|
33002
|
+
continue;
|
|
33003
|
+
}
|
|
33004
|
+
const key = keyMatch[1];
|
|
33005
|
+
const rawValue = (keyMatch[2] ?? "").trim();
|
|
33006
|
+
if (key === "description") {
|
|
33007
|
+
result.description = unquote2(rawValue);
|
|
33008
|
+
i++;
|
|
33009
|
+
} else if (key === "tags") {
|
|
33010
|
+
if (rawValue) {
|
|
33011
|
+
result.tags = rawValue.replace(/^\[|\]$/g, "").split(",").map((s) => unquote2(s)).filter((s) => s.length > 0);
|
|
33012
|
+
} else {
|
|
33013
|
+
const items = [];
|
|
33014
|
+
let j = i + 1;
|
|
33015
|
+
while (j < lines.length) {
|
|
33016
|
+
const next = lines[j] ?? "";
|
|
33017
|
+
const m = /^\s+-\s+(.+)$/.exec(next);
|
|
33018
|
+
if (!m) break;
|
|
33019
|
+
items.push(unquote2(m[1]));
|
|
33020
|
+
j++;
|
|
33021
|
+
}
|
|
33022
|
+
result.tags = items;
|
|
33023
|
+
i = j;
|
|
33024
|
+
continue;
|
|
33025
|
+
}
|
|
33026
|
+
i++;
|
|
33027
|
+
} else if (key === "variables") {
|
|
33028
|
+
const vars = [];
|
|
33029
|
+
let j = i + 1;
|
|
33030
|
+
while (j < lines.length) {
|
|
33031
|
+
const next = lines[j] ?? "";
|
|
33032
|
+
if (/^\s+-\s+key\s*:\s*/.test(next)) {
|
|
33033
|
+
const keyVal = unquote2((/^\s+-\s+key\s*:\s*(.*)$/.exec(next) ?? [])[1] ?? "");
|
|
33034
|
+
const varObj = { key: keyVal, type: "text", label: "", value: "" };
|
|
33035
|
+
j++;
|
|
33036
|
+
while (j < lines.length) {
|
|
33037
|
+
const sub = lines[j] ?? "";
|
|
33038
|
+
if (/^\s+-\s+/.test(sub) && !/^\s{4,}-\s+/.test(sub)) break;
|
|
33039
|
+
const subMatch = /^\s+(\w+)\s*:\s*(.*)$/.exec(sub);
|
|
33040
|
+
if (!subMatch) {
|
|
33041
|
+
j++;
|
|
33042
|
+
break;
|
|
33043
|
+
}
|
|
33044
|
+
const subKey = subMatch[1];
|
|
33045
|
+
const subVal = unquote2(subMatch[2] ?? "");
|
|
33046
|
+
if (subKey === "type") {
|
|
33047
|
+
varObj.type = subVal;
|
|
33048
|
+
} else if (subKey === "label") {
|
|
33049
|
+
varObj.label = subVal;
|
|
33050
|
+
} else if (subKey === "value") {
|
|
33051
|
+
varObj.value = subVal;
|
|
33052
|
+
} else if (subKey === "section") {
|
|
33053
|
+
varObj.section = subVal;
|
|
33054
|
+
} else if (subKey === "options") {
|
|
33055
|
+
varObj.options = subVal.replace(/^\[|\]$/g, "").split(",").map((s) => unquote2(s)).filter((s) => s.length > 0);
|
|
33056
|
+
} else if (subKey === "fileRef") {
|
|
33057
|
+
varObj.fileRef = subVal;
|
|
33058
|
+
}
|
|
33059
|
+
j++;
|
|
33060
|
+
}
|
|
33061
|
+
vars.push(varObj);
|
|
33062
|
+
} else if (/^[A-Za-z]/.test(next)) {
|
|
33063
|
+
break;
|
|
33064
|
+
} else {
|
|
33065
|
+
j++;
|
|
33066
|
+
}
|
|
33067
|
+
}
|
|
33068
|
+
result.variables = vars;
|
|
33069
|
+
i = j;
|
|
33070
|
+
continue;
|
|
33071
|
+
} else {
|
|
33072
|
+
i++;
|
|
33073
|
+
}
|
|
33074
|
+
}
|
|
33075
|
+
return result;
|
|
33076
|
+
}
|
|
33077
|
+
function serializeVariables(variables) {
|
|
33078
|
+
if (variables.length === 0) return ["variables: []"];
|
|
33079
|
+
const lines = ["variables:"];
|
|
33080
|
+
for (const v of variables) {
|
|
33081
|
+
lines.push(` - key: ${quoteIfNeeded(v.key)}`);
|
|
33082
|
+
lines.push(` type: ${v.type}`);
|
|
33083
|
+
lines.push(` label: ${quoteIfNeeded(v.label)}`);
|
|
33084
|
+
lines.push(` value: ${quoteIfNeeded(v.value)}`);
|
|
33085
|
+
if (v.section) {
|
|
33086
|
+
lines.push(` section: ${v.section}`);
|
|
33087
|
+
}
|
|
33088
|
+
if (v.options && v.options.length > 0) {
|
|
33089
|
+
lines.push(` options: [${v.options.map(quoteIfNeeded).join(", ")}]`);
|
|
33090
|
+
}
|
|
33091
|
+
if (v.fileRef) {
|
|
33092
|
+
lines.push(` fileRef: ${quoteIfNeeded(v.fileRef)}`);
|
|
33093
|
+
}
|
|
33094
|
+
}
|
|
33095
|
+
return lines;
|
|
33096
|
+
}
|
|
33097
|
+
var OWNED_KEYS2 = ["description", "tags", "variables"];
|
|
33098
|
+
function findOwnedSpans3(lines) {
|
|
33099
|
+
const spans = [];
|
|
33100
|
+
let i = 0;
|
|
33101
|
+
while (i < lines.length) {
|
|
33102
|
+
const line = lines[i] ?? "";
|
|
33103
|
+
const keyMatch = /^([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*)$/.exec(line);
|
|
33104
|
+
if (!keyMatch) {
|
|
33105
|
+
i++;
|
|
33106
|
+
continue;
|
|
33107
|
+
}
|
|
33108
|
+
const key = keyMatch[1];
|
|
33109
|
+
const rawValue = keyMatch[2] ?? "";
|
|
33110
|
+
if (!OWNED_KEYS2.includes(key)) {
|
|
33111
|
+
i++;
|
|
33112
|
+
continue;
|
|
33113
|
+
}
|
|
33114
|
+
let end = i + 1;
|
|
33115
|
+
if (rawValue.trim() === "" || rawValue.trim() === "[]") {
|
|
33116
|
+
while (end < lines.length) {
|
|
33117
|
+
const next = lines[end] ?? "";
|
|
33118
|
+
if (/^\s+/.test(next)) {
|
|
33119
|
+
end++;
|
|
33120
|
+
} else {
|
|
33121
|
+
break;
|
|
33122
|
+
}
|
|
33123
|
+
}
|
|
33124
|
+
}
|
|
33125
|
+
spans.push({ key, startLine: i, endLine: end });
|
|
33126
|
+
i = end;
|
|
33127
|
+
}
|
|
33128
|
+
return spans;
|
|
33129
|
+
}
|
|
33130
|
+
function rewriteFrontmatter3(originalLines, next) {
|
|
33131
|
+
const spans = findOwnedSpans3(originalLines);
|
|
33132
|
+
const ownedKeys = new Set(spans.map((s) => s.key));
|
|
33133
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
33134
|
+
if (next.description !== void 0) {
|
|
33135
|
+
const v = next.description;
|
|
33136
|
+
replacements.set("description", v.length > 0 ? [`description: ${quoteIfNeeded(v)}`] : []);
|
|
33137
|
+
}
|
|
33138
|
+
if (next.tags !== void 0) {
|
|
33139
|
+
if (next.tags.length === 0) {
|
|
33140
|
+
replacements.set("tags", []);
|
|
33141
|
+
} else {
|
|
33142
|
+
replacements.set("tags", [`tags: [${next.tags.map(quoteIfNeeded).join(", ")}]`]);
|
|
33143
|
+
}
|
|
33144
|
+
}
|
|
33145
|
+
if (next.variables !== void 0) {
|
|
33146
|
+
replacements.set("variables", serializeVariables(next.variables));
|
|
33147
|
+
}
|
|
33148
|
+
const out = [];
|
|
33149
|
+
let i = 0;
|
|
33150
|
+
while (i < originalLines.length) {
|
|
33151
|
+
const span = spans.find((s) => s.startLine === i);
|
|
33152
|
+
if (span) {
|
|
33153
|
+
if (replacements.has(span.key)) {
|
|
33154
|
+
out.push(...replacements.get(span.key) ?? []);
|
|
33155
|
+
} else {
|
|
33156
|
+
for (let j = span.startLine; j < span.endLine; j++) {
|
|
33157
|
+
out.push(originalLines[j] ?? "");
|
|
33158
|
+
}
|
|
33159
|
+
}
|
|
33160
|
+
i = span.endLine;
|
|
33161
|
+
continue;
|
|
33162
|
+
}
|
|
33163
|
+
out.push(originalLines[i] ?? "");
|
|
33164
|
+
i++;
|
|
33165
|
+
}
|
|
33166
|
+
for (const key of OWNED_KEYS2) {
|
|
33167
|
+
if (replacements.has(key) && !ownedKeys.has(key)) {
|
|
33168
|
+
out.push(...replacements.get(key) ?? []);
|
|
33169
|
+
}
|
|
33170
|
+
}
|
|
33171
|
+
return out;
|
|
33172
|
+
}
|
|
33173
|
+
async function readBrandsFromDir(scope, dir) {
|
|
33174
|
+
let entries;
|
|
33175
|
+
try {
|
|
33176
|
+
entries = await fs8.readdir(dir, { withFileTypes: true });
|
|
33177
|
+
} catch {
|
|
33178
|
+
return [];
|
|
33179
|
+
}
|
|
33180
|
+
const results = [];
|
|
33181
|
+
for (const entry of entries) {
|
|
33182
|
+
if (!entry.isFile()) continue;
|
|
33183
|
+
if (!entry.name.endsWith(".md")) continue;
|
|
33184
|
+
const name = entry.name.slice(0, -".md".length);
|
|
33185
|
+
if (!name || !NAME_REGEX3.test(name)) continue;
|
|
33186
|
+
const fullPath = path15.join(dir, entry.name);
|
|
33187
|
+
let stat5;
|
|
33188
|
+
try {
|
|
33189
|
+
const s = await fs8.stat(fullPath);
|
|
33190
|
+
stat5 = { mtime: s.mtime, size: s.size };
|
|
33191
|
+
} catch {
|
|
33192
|
+
continue;
|
|
33193
|
+
}
|
|
33194
|
+
let parsed;
|
|
33195
|
+
try {
|
|
33196
|
+
const text = await fs8.readFile(fullPath, "utf8");
|
|
33197
|
+
const { rawFrontmatterLines, hadFrontmatter } = parseBrandFile(text);
|
|
33198
|
+
parsed = hadFrontmatter ? parseFrontmatter2(rawFrontmatterLines) : { description: "", tags: [], variables: [] };
|
|
33199
|
+
} catch {
|
|
33200
|
+
parsed = { description: "", tags: [], variables: [] };
|
|
33201
|
+
}
|
|
33202
|
+
results.push({
|
|
33203
|
+
id: `${scope}:${name}`,
|
|
33204
|
+
scope,
|
|
33205
|
+
name,
|
|
33206
|
+
description: parsed.description,
|
|
33207
|
+
tags: parsed.tags,
|
|
33208
|
+
variables: parsed.variables,
|
|
33209
|
+
path: fullPath,
|
|
33210
|
+
modifiedAt: stat5.mtime.toISOString(),
|
|
33211
|
+
size: stat5.size
|
|
33212
|
+
});
|
|
33213
|
+
}
|
|
33214
|
+
results.sort((a, b) => a.name.localeCompare(b.name));
|
|
33215
|
+
return results;
|
|
33216
|
+
}
|
|
33217
|
+
async function listBrands(args) {
|
|
33218
|
+
return readBrandsFromDir("project", resolveScopeDir3("project", args.workspaceRoot));
|
|
33219
|
+
}
|
|
33220
|
+
async function createBrand(args) {
|
|
33221
|
+
if (!NAME_REGEX3.test(args.name)) {
|
|
33222
|
+
throw new Error(
|
|
33223
|
+
`Invalid brand name "${args.name}". Use letters, digits, dot, underscore, dash.`
|
|
33224
|
+
);
|
|
33225
|
+
}
|
|
33226
|
+
if (args.name.includes("/") || args.name.includes("\\") || args.name.includes("..")) {
|
|
33227
|
+
throw new Error(`Brand name must not contain path separators or "..".`);
|
|
33228
|
+
}
|
|
33229
|
+
const dir = resolveScopeDir3("project", args.workspaceRoot);
|
|
33230
|
+
await fs8.mkdir(dir, { recursive: true });
|
|
33231
|
+
const filePath = path15.join(dir, `${args.name}.md`);
|
|
33232
|
+
try {
|
|
33233
|
+
await fs8.access(filePath);
|
|
33234
|
+
throw new Error(`A brand named "${args.name}" already exists at ${filePath}`);
|
|
33235
|
+
} catch (err) {
|
|
33236
|
+
if (err && typeof err === "object" && "code" in err && err.code !== "ENOENT") {
|
|
33237
|
+
throw err;
|
|
33238
|
+
}
|
|
33239
|
+
if (err instanceof Error && err.message.includes("already exists")) {
|
|
33240
|
+
throw err;
|
|
33241
|
+
}
|
|
33242
|
+
}
|
|
33243
|
+
await fs8.writeFile(filePath, buildStarterBrand(args.name), "utf8");
|
|
33244
|
+
return { path: filePath };
|
|
33245
|
+
}
|
|
33246
|
+
function buildStarterBrand(name) {
|
|
33247
|
+
return `---
|
|
33248
|
+
name: ${name}
|
|
33249
|
+
description: ""
|
|
33250
|
+
tags: []
|
|
33251
|
+
variables:
|
|
33252
|
+
- key: color.primary
|
|
33253
|
+
type: color
|
|
33254
|
+
label: Primary Color
|
|
33255
|
+
value: "#000000"
|
|
33256
|
+
- key: color.accent
|
|
33257
|
+
type: color
|
|
33258
|
+
label: Accent Color
|
|
33259
|
+
value: "#ffffff"
|
|
33260
|
+
- key: font.heading
|
|
33261
|
+
type: font
|
|
33262
|
+
label: Heading Font
|
|
33263
|
+
value: ""
|
|
33264
|
+
- key: font.body
|
|
33265
|
+
type: font
|
|
33266
|
+
label: Body Font
|
|
33267
|
+
value: ""
|
|
33268
|
+
- key: logo
|
|
33269
|
+
type: asset
|
|
33270
|
+
label: Logo
|
|
33271
|
+
value: ""
|
|
33272
|
+
- key: tone
|
|
33273
|
+
type: text
|
|
33274
|
+
label: Tone of Voice
|
|
33275
|
+
value: ""
|
|
33276
|
+
---
|
|
33277
|
+
|
|
33278
|
+
# ${name}
|
|
33279
|
+
|
|
33280
|
+
Describe this brand's identity, design philosophy, and usage guidelines here.
|
|
33281
|
+
`;
|
|
33282
|
+
}
|
|
33283
|
+
var TARGET_NAME_REGEX = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
33284
|
+
async function copyBrandAsset(args) {
|
|
33285
|
+
if (!args.workspaceRoot) {
|
|
33286
|
+
throw new Error("workspaceRoot is required to copy a brand asset");
|
|
33287
|
+
}
|
|
33288
|
+
if (!args.sourcePath || !path15.isAbsolute(args.sourcePath)) {
|
|
33289
|
+
throw new Error(`copyBrandAsset expects an absolute sourcePath; got "${args.sourcePath}"`);
|
|
33290
|
+
}
|
|
33291
|
+
if (!TARGET_NAME_REGEX.test(args.targetName) || args.targetName.includes("..")) {
|
|
33292
|
+
throw new Error(
|
|
33293
|
+
`Invalid targetName "${args.targetName}". Use letters, digits, dot, underscore, dash.`
|
|
33294
|
+
);
|
|
33295
|
+
}
|
|
33296
|
+
const stats = await fs8.stat(args.sourcePath);
|
|
33297
|
+
if (!stats.isFile()) {
|
|
33298
|
+
throw new Error(`Source path is not a regular file: ${args.sourcePath}`);
|
|
33299
|
+
}
|
|
33300
|
+
const ext = path15.extname(args.sourcePath).toLowerCase();
|
|
33301
|
+
const fileName = `${args.targetName}${ext}`;
|
|
33302
|
+
const assetsDir = path15.join(args.workspaceRoot, ".brand", "assets");
|
|
33303
|
+
const destAbs = path15.resolve(assetsDir, fileName);
|
|
33304
|
+
const rel = path15.relative(path15.resolve(assetsDir), destAbs);
|
|
33305
|
+
if (rel.startsWith("..") || path15.isAbsolute(rel)) {
|
|
33306
|
+
throw new Error(`Refusing to write outside of .brand/assets: ${destAbs}`);
|
|
33307
|
+
}
|
|
33308
|
+
await fs8.mkdir(assetsDir, { recursive: true });
|
|
33309
|
+
await fs8.copyFile(args.sourcePath, destAbs);
|
|
33310
|
+
return {
|
|
33311
|
+
relativePath: `assets/${fileName}`,
|
|
33312
|
+
absolutePath: destAbs
|
|
33313
|
+
};
|
|
33314
|
+
}
|
|
33315
|
+
async function uploadBrandAsset(args) {
|
|
33316
|
+
if (!args.workspaceRoot) {
|
|
33317
|
+
throw new Error("workspaceRoot is required to upload a brand asset");
|
|
33318
|
+
}
|
|
33319
|
+
if (!TARGET_NAME_REGEX.test(args.targetName) || args.targetName.includes("..")) {
|
|
33320
|
+
throw new Error(
|
|
33321
|
+
`Invalid targetName "${args.targetName}". Use letters, digits, dot, underscore, dash.`
|
|
33322
|
+
);
|
|
33323
|
+
}
|
|
33324
|
+
if (!args.dataBase64 || args.dataBase64.trim().length === 0) {
|
|
33325
|
+
throw new Error("No file data provided for brand asset upload");
|
|
33326
|
+
}
|
|
33327
|
+
const extFromSource = args.sourceName ? path15.extname(args.sourceName).toLowerCase() : "";
|
|
33328
|
+
const ext = extFromSource || ".png";
|
|
33329
|
+
const fileName = `${args.targetName}${ext}`;
|
|
33330
|
+
const assetsDir = path15.join(args.workspaceRoot, ".brand", "assets");
|
|
33331
|
+
const destAbs = path15.resolve(assetsDir, fileName);
|
|
33332
|
+
const rel = path15.relative(path15.resolve(assetsDir), destAbs);
|
|
33333
|
+
if (rel.startsWith("..") || path15.isAbsolute(rel)) {
|
|
33334
|
+
throw new Error(`Refusing to write outside of .brand/assets: ${destAbs}`);
|
|
33335
|
+
}
|
|
33336
|
+
let data;
|
|
33337
|
+
try {
|
|
33338
|
+
data = Buffer.from(args.dataBase64, "base64");
|
|
33339
|
+
} catch {
|
|
33340
|
+
throw new Error("Failed to decode uploaded brand asset");
|
|
33341
|
+
}
|
|
33342
|
+
if (data.length === 0) {
|
|
33343
|
+
throw new Error("Uploaded brand asset is empty");
|
|
33344
|
+
}
|
|
33345
|
+
await fs8.mkdir(assetsDir, { recursive: true });
|
|
33346
|
+
await fs8.writeFile(destAbs, data);
|
|
33347
|
+
return {
|
|
33348
|
+
relativePath: `assets/${fileName}`,
|
|
33349
|
+
absolutePath: destAbs
|
|
33350
|
+
};
|
|
33351
|
+
}
|
|
33352
|
+
async function writeBrandFrontmatter(args, workspaceRoot) {
|
|
33353
|
+
if (!path15.isAbsolute(args.path)) {
|
|
33354
|
+
throw new Error(`writeBrandFrontmatter expects an absolute path; got "${args.path}"`);
|
|
33355
|
+
}
|
|
33356
|
+
if (!isInsideAllowedRoot3(args.path, workspaceRoot)) {
|
|
33357
|
+
throw new Error(`Path "${args.path}" is not inside an allowlisted brand root`);
|
|
33358
|
+
}
|
|
33359
|
+
let original;
|
|
33360
|
+
try {
|
|
33361
|
+
original = await fs8.readFile(args.path, "utf8");
|
|
33362
|
+
} catch (err) {
|
|
33363
|
+
throw new Error(
|
|
33364
|
+
`Failed to read brand file: ${err instanceof Error ? err.message : String(err)}`
|
|
33365
|
+
);
|
|
33366
|
+
}
|
|
33367
|
+
const parsed = parseBrandFile(original);
|
|
33368
|
+
const newLines = rewriteFrontmatter3(parsed.rawFrontmatterLines, args.frontmatter);
|
|
33369
|
+
const nextFrontmatter = ["---", ...newLines, "---"].join("\n");
|
|
33370
|
+
const nextContent = parsed.hadFrontmatter ? `${nextFrontmatter}
|
|
33371
|
+
${parsed.body}` : `${nextFrontmatter}
|
|
33372
|
+
|
|
33373
|
+
${original}`;
|
|
33374
|
+
await fs8.writeFile(args.path, nextContent, "utf8");
|
|
33375
|
+
}
|
|
32274
33376
|
|
|
32275
33377
|
// ../server/src/services/oauth-service.ts
|
|
32276
33378
|
import { createHash as createHash3, randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -32517,57 +33619,57 @@ async function fetchGitLabUsername(fetchImpl, accessToken) {
|
|
|
32517
33619
|
return null;
|
|
32518
33620
|
}
|
|
32519
33621
|
}
|
|
32520
|
-
async function readCredential(
|
|
33622
|
+
async function readCredential(path24, log2) {
|
|
32521
33623
|
try {
|
|
32522
|
-
const raw = await readFile3(
|
|
33624
|
+
const raw = await readFile3(path24, "utf8");
|
|
32523
33625
|
const parsed = JSON.parse(raw);
|
|
32524
33626
|
return parsed.gitlab ?? null;
|
|
32525
33627
|
} catch (error) {
|
|
32526
33628
|
if (isNotFound(error)) return null;
|
|
32527
|
-
log2.warn({ err: error, path:
|
|
33629
|
+
log2.warn({ err: error, path: path24 }, "oauth.credentials.read_failed");
|
|
32528
33630
|
return null;
|
|
32529
33631
|
}
|
|
32530
33632
|
}
|
|
32531
|
-
async function persistCredential(
|
|
32532
|
-
await mkdir4(dirname4(
|
|
33633
|
+
async function persistCredential(path24, credential, log2) {
|
|
33634
|
+
await mkdir4(dirname4(path24), { recursive: true });
|
|
32533
33635
|
let current = {};
|
|
32534
33636
|
try {
|
|
32535
|
-
const raw = await readFile3(
|
|
33637
|
+
const raw = await readFile3(path24, "utf8");
|
|
32536
33638
|
current = JSON.parse(raw);
|
|
32537
33639
|
} catch (error) {
|
|
32538
33640
|
if (!isNotFound(error)) {
|
|
32539
|
-
log2.warn({ err: error, path:
|
|
33641
|
+
log2.warn({ err: error, path: path24 }, "oauth.credentials.read_failed_overwriting");
|
|
32540
33642
|
}
|
|
32541
33643
|
}
|
|
32542
33644
|
const next = { ...current, gitlab: credential };
|
|
32543
|
-
const tmpPath = `${
|
|
33645
|
+
const tmpPath = `${path24}.tmp-${process.pid}-${Date.now()}`;
|
|
32544
33646
|
await writeFile4(tmpPath, JSON.stringify(next, null, 2), { mode: 384 });
|
|
32545
|
-
await rename(tmpPath,
|
|
33647
|
+
await rename(tmpPath, path24);
|
|
32546
33648
|
}
|
|
32547
|
-
async function deleteCredential(
|
|
33649
|
+
async function deleteCredential(path24, log2) {
|
|
32548
33650
|
let current = {};
|
|
32549
33651
|
try {
|
|
32550
|
-
const raw = await readFile3(
|
|
33652
|
+
const raw = await readFile3(path24, "utf8");
|
|
32551
33653
|
current = JSON.parse(raw);
|
|
32552
33654
|
} catch (error) {
|
|
32553
33655
|
if (isNotFound(error)) return;
|
|
32554
|
-
log2.warn({ err: error, path:
|
|
33656
|
+
log2.warn({ err: error, path: path24 }, "oauth.credentials.delete_read_failed");
|
|
32555
33657
|
return;
|
|
32556
33658
|
}
|
|
32557
33659
|
delete current.gitlab;
|
|
32558
33660
|
if (Object.keys(current).length === 0) {
|
|
32559
33661
|
try {
|
|
32560
|
-
await unlink(
|
|
33662
|
+
await unlink(path24);
|
|
32561
33663
|
} catch (error) {
|
|
32562
33664
|
if (!isNotFound(error)) {
|
|
32563
|
-
log2.warn({ err: error, path:
|
|
33665
|
+
log2.warn({ err: error, path: path24 }, "oauth.credentials.unlink_failed");
|
|
32564
33666
|
}
|
|
32565
33667
|
}
|
|
32566
33668
|
return;
|
|
32567
33669
|
}
|
|
32568
|
-
const tmpPath = `${
|
|
33670
|
+
const tmpPath = `${path24}.tmp-${process.pid}-${Date.now()}`;
|
|
32569
33671
|
await writeFile4(tmpPath, JSON.stringify(current, null, 2), { mode: 384 });
|
|
32570
|
-
await rename(tmpPath,
|
|
33672
|
+
await rename(tmpPath, path24);
|
|
32571
33673
|
}
|
|
32572
33674
|
function defaultGlabConfigPath() {
|
|
32573
33675
|
const home = homedir4();
|
|
@@ -32582,15 +33684,15 @@ function defaultGlabConfigPath() {
|
|
|
32582
33684
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
32583
33685
|
return join9(xdg && xdg.length > 0 ? xdg : join9(home, ".config"), "glab-cli", "config.yml");
|
|
32584
33686
|
}
|
|
32585
|
-
async function writeGlabConfig(
|
|
32586
|
-
await mkdir4(dirname4(
|
|
33687
|
+
async function writeGlabConfig(path24, credential, log2) {
|
|
33688
|
+
await mkdir4(dirname4(path24), { recursive: true });
|
|
32587
33689
|
let doc;
|
|
32588
33690
|
try {
|
|
32589
|
-
const raw = await readFile3(
|
|
33691
|
+
const raw = await readFile3(path24, "utf8");
|
|
32590
33692
|
doc = YAML.parseDocument(raw);
|
|
32591
33693
|
if (doc.errors.length > 0) {
|
|
32592
33694
|
log2.warn(
|
|
32593
|
-
{ errors: doc.errors.map((e) => e.message), path:
|
|
33695
|
+
{ errors: doc.errors.map((e) => e.message), path: path24 },
|
|
32594
33696
|
"oauth.glab.parse_errors_replacing"
|
|
32595
33697
|
);
|
|
32596
33698
|
doc = YAML.parseDocument("{}");
|
|
@@ -32599,7 +33701,7 @@ async function writeGlabConfig(path23, credential, log2) {
|
|
|
32599
33701
|
if (isNotFound(error)) {
|
|
32600
33702
|
doc = YAML.parseDocument("{}");
|
|
32601
33703
|
} else {
|
|
32602
|
-
log2.warn({ err: error, path:
|
|
33704
|
+
log2.warn({ err: error, path: path24 }, "oauth.glab.read_failed_replacing");
|
|
32603
33705
|
doc = YAML.parseDocument("{}");
|
|
32604
33706
|
}
|
|
32605
33707
|
}
|
|
@@ -32612,18 +33714,18 @@ async function writeGlabConfig(path23, credential, log2) {
|
|
|
32612
33714
|
if (credential.username) {
|
|
32613
33715
|
hostEntry.set("user", credential.username);
|
|
32614
33716
|
}
|
|
32615
|
-
const tmpPath = `${
|
|
33717
|
+
const tmpPath = `${path24}.tmp-${process.pid}-${Date.now()}`;
|
|
32616
33718
|
await writeFile4(tmpPath, doc.toString(), { mode: 384 });
|
|
32617
|
-
await rename(tmpPath,
|
|
33719
|
+
await rename(tmpPath, path24);
|
|
32618
33720
|
}
|
|
32619
|
-
async function removeGlabHost(
|
|
33721
|
+
async function removeGlabHost(path24, log2) {
|
|
32620
33722
|
let doc;
|
|
32621
33723
|
try {
|
|
32622
|
-
const raw = await readFile3(
|
|
33724
|
+
const raw = await readFile3(path24, "utf8");
|
|
32623
33725
|
doc = YAML.parseDocument(raw);
|
|
32624
33726
|
} catch (error) {
|
|
32625
33727
|
if (isNotFound(error)) return;
|
|
32626
|
-
log2.warn({ err: error, path:
|
|
33728
|
+
log2.warn({ err: error, path: path24 }, "oauth.glab.remove_read_failed");
|
|
32627
33729
|
return;
|
|
32628
33730
|
}
|
|
32629
33731
|
const hosts = doc.get("hosts");
|
|
@@ -32632,9 +33734,9 @@ async function removeGlabHost(path23, log2) {
|
|
|
32632
33734
|
if (hosts.items.length === 0) {
|
|
32633
33735
|
doc.delete("hosts");
|
|
32634
33736
|
}
|
|
32635
|
-
const tmpPath = `${
|
|
33737
|
+
const tmpPath = `${path24}.tmp-${process.pid}-${Date.now()}`;
|
|
32636
33738
|
await writeFile4(tmpPath, doc.toString(), { mode: 384 });
|
|
32637
|
-
await rename(tmpPath,
|
|
33739
|
+
await rename(tmpPath, path24);
|
|
32638
33740
|
}
|
|
32639
33741
|
function ensureMap(doc, key) {
|
|
32640
33742
|
const existing = doc.get(key);
|
|
@@ -33735,7 +34837,7 @@ var Session = class _Session {
|
|
|
33735
34837
|
chatService,
|
|
33736
34838
|
scheduleService,
|
|
33737
34839
|
loopService,
|
|
33738
|
-
|
|
34840
|
+
questService,
|
|
33739
34841
|
checkoutDiffManager,
|
|
33740
34842
|
github,
|
|
33741
34843
|
gitlab,
|
|
@@ -33782,7 +34884,7 @@ var Session = class _Session {
|
|
|
33782
34884
|
this.chatService = chatService;
|
|
33783
34885
|
this.scheduleService = scheduleService;
|
|
33784
34886
|
this.loopService = loopService;
|
|
33785
|
-
this.
|
|
34887
|
+
this.questService = questService;
|
|
33786
34888
|
this.checkoutDiffManager = checkoutDiffManager;
|
|
33787
34889
|
this.github = github ?? createGitHubService();
|
|
33788
34890
|
this.gitlab = gitlab ?? createGitLabService();
|
|
@@ -34361,7 +35463,13 @@ var Session = class _Session {
|
|
|
34361
35463
|
await this.handleCloseItemsRequest(msg);
|
|
34362
35464
|
break;
|
|
34363
35465
|
case "update_agent_request":
|
|
34364
|
-
await this.handleUpdateAgentRequest(
|
|
35466
|
+
await this.handleUpdateAgentRequest(
|
|
35467
|
+
msg.agentId,
|
|
35468
|
+
msg.name,
|
|
35469
|
+
msg.labels,
|
|
35470
|
+
msg.requestId,
|
|
35471
|
+
msg.internal
|
|
35472
|
+
);
|
|
34365
35473
|
break;
|
|
34366
35474
|
case "set_voice_mode":
|
|
34367
35475
|
await this.handleSetVoiceMode(msg.enabled, msg.agentId, msg.requestId);
|
|
@@ -34591,6 +35699,15 @@ var Session = class _Session {
|
|
|
34591
35699
|
case "file_delete_request":
|
|
34592
35700
|
await this.handleFileDeleteRequest(msg);
|
|
34593
35701
|
break;
|
|
35702
|
+
case "file_explorer_delete_request":
|
|
35703
|
+
await this.handleFileExplorerDeleteRequest(msg);
|
|
35704
|
+
break;
|
|
35705
|
+
case "file_mkdir_request":
|
|
35706
|
+
await this.handleFileMkdirRequest(msg);
|
|
35707
|
+
break;
|
|
35708
|
+
case "file_move_request":
|
|
35709
|
+
await this.handleFileMoveRequest(msg);
|
|
35710
|
+
break;
|
|
34594
35711
|
case "project_icon_request":
|
|
34595
35712
|
await this.handleProjectIconRequest(msg);
|
|
34596
35713
|
break;
|
|
@@ -34751,20 +35868,47 @@ var Session = class _Session {
|
|
|
34751
35868
|
case "loop/stop":
|
|
34752
35869
|
await this.handleLoopStopRequest(msg);
|
|
34753
35870
|
break;
|
|
34754
|
-
case "
|
|
34755
|
-
await this.
|
|
35871
|
+
case "quest/run":
|
|
35872
|
+
await this.handleQuestRunRequest(msg);
|
|
35873
|
+
break;
|
|
35874
|
+
case "quest/list":
|
|
35875
|
+
await this.handleQuestListRequest(msg);
|
|
35876
|
+
break;
|
|
35877
|
+
case "quest/inspect":
|
|
35878
|
+
await this.handleQuestInspectRequest(msg);
|
|
35879
|
+
break;
|
|
35880
|
+
case "quest/stop":
|
|
35881
|
+
await this.handleQuestStopRequest(msg);
|
|
35882
|
+
break;
|
|
35883
|
+
case "roles/list":
|
|
35884
|
+
await this.handleRolesListRequest(msg);
|
|
35885
|
+
break;
|
|
35886
|
+
case "roles/list-scope":
|
|
35887
|
+
await this.handleRolesListScopeRequest(msg);
|
|
35888
|
+
break;
|
|
35889
|
+
case "roles/create":
|
|
35890
|
+
await this.handleRoleCreateRequest(msg);
|
|
35891
|
+
break;
|
|
35892
|
+
case "roles/write-frontmatter":
|
|
35893
|
+
await this.handleRoleWriteFrontmatterRequest(msg);
|
|
35894
|
+
break;
|
|
35895
|
+
case "roles/move":
|
|
35896
|
+
await this.handleRoleMoveRequest(msg);
|
|
35897
|
+
break;
|
|
35898
|
+
case "brands/list-scope":
|
|
35899
|
+
await this.handleBrandsListScopeRequest(msg);
|
|
34756
35900
|
break;
|
|
34757
|
-
case "
|
|
34758
|
-
await this.
|
|
35901
|
+
case "brands/create":
|
|
35902
|
+
await this.handleBrandCreateRequest(msg);
|
|
34759
35903
|
break;
|
|
34760
|
-
case "
|
|
34761
|
-
await this.
|
|
35904
|
+
case "brands/write-frontmatter":
|
|
35905
|
+
await this.handleBrandWriteFrontmatterRequest(msg);
|
|
34762
35906
|
break;
|
|
34763
|
-
case "
|
|
34764
|
-
await this.
|
|
35907
|
+
case "brands/asset-copy":
|
|
35908
|
+
await this.handleBrandAssetCopyRequest(msg);
|
|
34765
35909
|
break;
|
|
34766
|
-
case "
|
|
34767
|
-
await this.
|
|
35910
|
+
case "brands/asset-upload":
|
|
35911
|
+
await this.handleBrandAssetUploadRequest(msg);
|
|
34768
35912
|
break;
|
|
34769
35913
|
}
|
|
34770
35914
|
} catch (error) {
|
|
@@ -35196,26 +36340,27 @@ var Session = class _Session {
|
|
|
35196
36340
|
}
|
|
35197
36341
|
await unarchiveAgentState(this.agentStorage, this.agentManager, matched.id);
|
|
35198
36342
|
}
|
|
35199
|
-
async handleUpdateAgentRequest(agentId, name, labels, requestId) {
|
|
36343
|
+
async handleUpdateAgentRequest(agentId, name, labels, requestId, internal) {
|
|
35200
36344
|
this.sessionLogger.info(
|
|
35201
36345
|
{
|
|
35202
36346
|
agentId,
|
|
35203
36347
|
requestId,
|
|
35204
36348
|
hasName: typeof name === "string",
|
|
35205
|
-
labelCount: labels ? Object.keys(labels).length : 0
|
|
36349
|
+
labelCount: labels ? Object.keys(labels).length : 0,
|
|
36350
|
+
internal
|
|
35206
36351
|
},
|
|
35207
36352
|
"session: update_agent_request"
|
|
35208
36353
|
);
|
|
35209
36354
|
const normalizedName = name?.trim();
|
|
35210
36355
|
const normalizedLabels = labels && Object.keys(labels).length > 0 ? labels : void 0;
|
|
35211
|
-
if (!normalizedName && !normalizedLabels) {
|
|
36356
|
+
if (!normalizedName && !normalizedLabels && internal === void 0) {
|
|
35212
36357
|
this.emit({
|
|
35213
36358
|
type: "update_agent_response",
|
|
35214
36359
|
payload: {
|
|
35215
36360
|
requestId,
|
|
35216
36361
|
agentId,
|
|
35217
36362
|
accepted: false,
|
|
35218
|
-
error: "Nothing to update (provide name and/or
|
|
36363
|
+
error: "Nothing to update (provide name, labels, and/or internal)"
|
|
35219
36364
|
}
|
|
35220
36365
|
});
|
|
35221
36366
|
return;
|
|
@@ -35223,7 +36368,8 @@ var Session = class _Session {
|
|
|
35223
36368
|
try {
|
|
35224
36369
|
await this.agentManager.updateAgentMetadata(agentId, {
|
|
35225
36370
|
...normalizedName ? { title: normalizedName } : {},
|
|
35226
|
-
...normalizedLabels ? { labels: normalizedLabels } : {}
|
|
36371
|
+
...normalizedLabels ? { labels: normalizedLabels } : {},
|
|
36372
|
+
...internal !== void 0 ? { internal } : {}
|
|
35227
36373
|
});
|
|
35228
36374
|
this.emit({
|
|
35229
36375
|
type: "update_agent_response",
|
|
@@ -37118,7 +38264,7 @@ var Session = class _Session {
|
|
|
37118
38264
|
homeDir: process.env.HOME ?? homedir5(),
|
|
37119
38265
|
query: query2,
|
|
37120
38266
|
limit
|
|
37121
|
-
})).map((
|
|
38267
|
+
})).map((path24) => ({ path: path24, kind: "directory" }));
|
|
37122
38268
|
const directories = entries.filter((entry) => entry.kind === "directory").map((entry) => entry.path);
|
|
37123
38269
|
this.emit({
|
|
37124
38270
|
type: "directory_suggestions_response",
|
|
@@ -38015,6 +39161,104 @@ ${details}`.trim());
|
|
|
38015
39161
|
});
|
|
38016
39162
|
}
|
|
38017
39163
|
}
|
|
39164
|
+
async handleFileExplorerDeleteRequest(request) {
|
|
39165
|
+
const { cwd: workspaceCwd, path: requestedPath, requestId } = request;
|
|
39166
|
+
const cwd = workspaceCwd.trim();
|
|
39167
|
+
if (!cwd) {
|
|
39168
|
+
this.emit({
|
|
39169
|
+
type: "file_explorer_delete_response",
|
|
39170
|
+
payload: { cwd: workspaceCwd, path: requestedPath, error: "cwd is required", requestId }
|
|
39171
|
+
});
|
|
39172
|
+
return;
|
|
39173
|
+
}
|
|
39174
|
+
try {
|
|
39175
|
+
await deleteEntry({ root: cwd, relativePath: requestedPath });
|
|
39176
|
+
this.emit({
|
|
39177
|
+
type: "file_explorer_delete_response",
|
|
39178
|
+
payload: { cwd, path: requestedPath, error: null, requestId }
|
|
39179
|
+
});
|
|
39180
|
+
} catch (error) {
|
|
39181
|
+
this.sessionLogger.error(
|
|
39182
|
+
{ err: error, cwd, path: requestedPath },
|
|
39183
|
+
`Failed to delete entry ${requestedPath} in workspace ${cwd}`
|
|
39184
|
+
);
|
|
39185
|
+
this.emit({
|
|
39186
|
+
type: "file_explorer_delete_response",
|
|
39187
|
+
payload: { cwd, path: requestedPath, error: error?.message ?? "delete failed", requestId }
|
|
39188
|
+
});
|
|
39189
|
+
}
|
|
39190
|
+
}
|
|
39191
|
+
async handleFileMkdirRequest(request) {
|
|
39192
|
+
const { cwd: workspaceCwd, path: requestedPath, requestId } = request;
|
|
39193
|
+
const cwd = workspaceCwd.trim();
|
|
39194
|
+
if (!cwd) {
|
|
39195
|
+
this.emit({
|
|
39196
|
+
type: "file_mkdir_response",
|
|
39197
|
+
payload: { cwd: workspaceCwd, path: requestedPath, error: "cwd is required", requestId }
|
|
39198
|
+
});
|
|
39199
|
+
return;
|
|
39200
|
+
}
|
|
39201
|
+
try {
|
|
39202
|
+
await createDirectory({ root: cwd, relativePath: requestedPath });
|
|
39203
|
+
this.emit({
|
|
39204
|
+
type: "file_mkdir_response",
|
|
39205
|
+
payload: { cwd, path: requestedPath, error: null, requestId }
|
|
39206
|
+
});
|
|
39207
|
+
} catch (error) {
|
|
39208
|
+
this.sessionLogger.error(
|
|
39209
|
+
{ err: error, cwd, path: requestedPath },
|
|
39210
|
+
`Failed to create directory ${requestedPath} in workspace ${cwd}`
|
|
39211
|
+
);
|
|
39212
|
+
this.emit({
|
|
39213
|
+
type: "file_mkdir_response",
|
|
39214
|
+
payload: {
|
|
39215
|
+
cwd,
|
|
39216
|
+
path: requestedPath,
|
|
39217
|
+
error: error?.message ?? "mkdir failed",
|
|
39218
|
+
requestId
|
|
39219
|
+
}
|
|
39220
|
+
});
|
|
39221
|
+
}
|
|
39222
|
+
}
|
|
39223
|
+
async handleFileMoveRequest(request) {
|
|
39224
|
+
const { cwd: workspaceCwd, sourcePath, destinationPath, requestId } = request;
|
|
39225
|
+
const cwd = workspaceCwd.trim();
|
|
39226
|
+
if (!cwd) {
|
|
39227
|
+
this.emit({
|
|
39228
|
+
type: "file_move_response",
|
|
39229
|
+
payload: {
|
|
39230
|
+
cwd: workspaceCwd,
|
|
39231
|
+
sourcePath,
|
|
39232
|
+
destinationPath,
|
|
39233
|
+
error: "cwd is required",
|
|
39234
|
+
requestId
|
|
39235
|
+
}
|
|
39236
|
+
});
|
|
39237
|
+
return;
|
|
39238
|
+
}
|
|
39239
|
+
try {
|
|
39240
|
+
await moveEntry({ root: cwd, sourcePath, destinationPath });
|
|
39241
|
+
this.emit({
|
|
39242
|
+
type: "file_move_response",
|
|
39243
|
+
payload: { cwd, sourcePath, destinationPath, error: null, requestId }
|
|
39244
|
+
});
|
|
39245
|
+
} catch (error) {
|
|
39246
|
+
this.sessionLogger.error(
|
|
39247
|
+
{ err: error, cwd, sourcePath, destinationPath },
|
|
39248
|
+
`Failed to move ${sourcePath} to ${destinationPath} in workspace ${cwd}`
|
|
39249
|
+
);
|
|
39250
|
+
this.emit({
|
|
39251
|
+
type: "file_move_response",
|
|
39252
|
+
payload: {
|
|
39253
|
+
cwd,
|
|
39254
|
+
sourcePath,
|
|
39255
|
+
destinationPath,
|
|
39256
|
+
error: error?.message ?? "move failed",
|
|
39257
|
+
requestId
|
|
39258
|
+
}
|
|
39259
|
+
});
|
|
39260
|
+
}
|
|
39261
|
+
}
|
|
38018
39262
|
/**
|
|
38019
39263
|
* Handle project icon request for a given cwd
|
|
38020
39264
|
*/
|
|
@@ -40676,17 +41920,17 @@ ${details}`.trim());
|
|
|
40676
41920
|
this.emitLoopRpcError(request, error);
|
|
40677
41921
|
}
|
|
40678
41922
|
}
|
|
40679
|
-
|
|
41923
|
+
emitQuestRpcError(request, error) {
|
|
40680
41924
|
const message = error instanceof Error ? error.message : String(error);
|
|
40681
41925
|
const responseType = `${request.type}/response`;
|
|
40682
|
-
if (responseType === "
|
|
41926
|
+
if (responseType === "quest/list/response") {
|
|
40683
41927
|
this.emit({
|
|
40684
41928
|
type: responseType,
|
|
40685
|
-
payload: { requestId: request.requestId,
|
|
41929
|
+
payload: { requestId: request.requestId, quests: [], error: message }
|
|
40686
41930
|
});
|
|
40687
41931
|
return;
|
|
40688
41932
|
}
|
|
40689
|
-
if (responseType === "
|
|
41933
|
+
if (responseType === "roles/list/response") {
|
|
40690
41934
|
this.emit({
|
|
40691
41935
|
type: responseType,
|
|
40692
41936
|
payload: { requestId: request.requestId, roles: [], error: message }
|
|
@@ -40695,12 +41939,12 @@ ${details}`.trim());
|
|
|
40695
41939
|
}
|
|
40696
41940
|
this.emit({
|
|
40697
41941
|
type: responseType,
|
|
40698
|
-
payload: { requestId: request.requestId,
|
|
41942
|
+
payload: { requestId: request.requestId, quest: null, error: message }
|
|
40699
41943
|
});
|
|
40700
41944
|
}
|
|
40701
|
-
async
|
|
41945
|
+
async handleQuestRunRequest(request) {
|
|
40702
41946
|
try {
|
|
40703
|
-
const
|
|
41947
|
+
const quest = await this.questService.run({
|
|
40704
41948
|
kind: request.kind,
|
|
40705
41949
|
cwd: request.cwd,
|
|
40706
41950
|
prompt: request.prompt,
|
|
@@ -40711,16 +41955,16 @@ ${details}`.trim());
|
|
|
40711
41955
|
summarizerEnabled: request.summarizerEnabled
|
|
40712
41956
|
});
|
|
40713
41957
|
this.emit({
|
|
40714
|
-
type: "
|
|
40715
|
-
payload: { requestId: request.requestId,
|
|
41958
|
+
type: "quest/run/response",
|
|
41959
|
+
payload: { requestId: request.requestId, quest, error: null }
|
|
40716
41960
|
});
|
|
40717
41961
|
} catch (error) {
|
|
40718
|
-
this.
|
|
41962
|
+
this.emitQuestRpcError(request, error);
|
|
40719
41963
|
}
|
|
40720
41964
|
}
|
|
40721
|
-
async
|
|
41965
|
+
async handleQuestListRequest(request) {
|
|
40722
41966
|
try {
|
|
40723
|
-
const
|
|
41967
|
+
const quests = this.questService.list().map((w) => ({
|
|
40724
41968
|
id: w.id,
|
|
40725
41969
|
kind: w.kind,
|
|
40726
41970
|
status: w.status,
|
|
@@ -40730,44 +41974,247 @@ ${details}`.trim());
|
|
|
40730
41974
|
updatedAt: w.updatedAt
|
|
40731
41975
|
}));
|
|
40732
41976
|
this.emit({
|
|
40733
|
-
type: "
|
|
40734
|
-
payload: { requestId: request.requestId,
|
|
41977
|
+
type: "quest/list/response",
|
|
41978
|
+
payload: { requestId: request.requestId, quests, error: null }
|
|
40735
41979
|
});
|
|
40736
41980
|
} catch (error) {
|
|
40737
|
-
this.
|
|
41981
|
+
this.emitQuestRpcError(request, error);
|
|
40738
41982
|
}
|
|
40739
41983
|
}
|
|
40740
|
-
async
|
|
41984
|
+
async handleQuestInspectRequest(request) {
|
|
40741
41985
|
try {
|
|
40742
|
-
const
|
|
41986
|
+
const quest = this.questService.inspect(request.id);
|
|
40743
41987
|
this.emit({
|
|
40744
|
-
type: "
|
|
40745
|
-
payload: { requestId: request.requestId,
|
|
41988
|
+
type: "quest/inspect/response",
|
|
41989
|
+
payload: { requestId: request.requestId, quest, error: null }
|
|
40746
41990
|
});
|
|
40747
41991
|
} catch (error) {
|
|
40748
|
-
this.
|
|
41992
|
+
this.emitQuestRpcError(request, error);
|
|
40749
41993
|
}
|
|
40750
41994
|
}
|
|
40751
|
-
async
|
|
41995
|
+
async handleQuestStopRequest(request) {
|
|
40752
41996
|
try {
|
|
40753
|
-
const
|
|
41997
|
+
const quest = await this.questService.stop(request.id);
|
|
40754
41998
|
this.emit({
|
|
40755
|
-
type: "
|
|
40756
|
-
payload: { requestId: request.requestId,
|
|
41999
|
+
type: "quest/stop/response",
|
|
42000
|
+
payload: { requestId: request.requestId, quest, error: null }
|
|
40757
42001
|
});
|
|
40758
42002
|
} catch (error) {
|
|
40759
|
-
this.
|
|
42003
|
+
this.emitQuestRpcError(request, error);
|
|
40760
42004
|
}
|
|
40761
42005
|
}
|
|
40762
|
-
async
|
|
42006
|
+
async handleRolesListRequest(request) {
|
|
40763
42007
|
try {
|
|
40764
|
-
const roles = await
|
|
42008
|
+
const roles = await listRoles({ workspaceRoot: request.workspaceRoot });
|
|
40765
42009
|
this.emit({
|
|
40766
|
-
type: "
|
|
42010
|
+
type: "roles/list/response",
|
|
40767
42011
|
payload: { requestId: request.requestId, roles, error: null }
|
|
40768
42012
|
});
|
|
40769
42013
|
} catch (error) {
|
|
40770
|
-
this.
|
|
42014
|
+
this.emitQuestRpcError(request, error);
|
|
42015
|
+
}
|
|
42016
|
+
}
|
|
42017
|
+
async handleRolesListScopeRequest(request) {
|
|
42018
|
+
const { scope, workspaceRoot, requestId } = request;
|
|
42019
|
+
try {
|
|
42020
|
+
const roles = await listRoles({
|
|
42021
|
+
scope,
|
|
42022
|
+
...workspaceRoot ? { workspaceRoot: expandTilde(workspaceRoot) } : {}
|
|
42023
|
+
});
|
|
42024
|
+
this.emit({
|
|
42025
|
+
type: "roles/list-scope/response",
|
|
42026
|
+
payload: { requestId, roles, error: null }
|
|
42027
|
+
});
|
|
42028
|
+
} catch (error) {
|
|
42029
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42030
|
+
this.sessionLogger.error({ err: error, scope }, "Failed to list roles by scope");
|
|
42031
|
+
this.emit({
|
|
42032
|
+
type: "roles/list-scope/response",
|
|
42033
|
+
payload: { requestId, roles: [], error: message }
|
|
42034
|
+
});
|
|
42035
|
+
}
|
|
42036
|
+
}
|
|
42037
|
+
async handleRoleCreateRequest(request) {
|
|
42038
|
+
const { scope, name, category, workspaceRoot, requestId } = request;
|
|
42039
|
+
try {
|
|
42040
|
+
const result = await createRole({
|
|
42041
|
+
scope,
|
|
42042
|
+
name,
|
|
42043
|
+
...category ? { category } : {},
|
|
42044
|
+
...workspaceRoot ? { workspaceRoot: expandTilde(workspaceRoot) } : {}
|
|
42045
|
+
});
|
|
42046
|
+
this.emit({
|
|
42047
|
+
type: "roles/create/response",
|
|
42048
|
+
payload: { requestId, path: result.path, error: null }
|
|
42049
|
+
});
|
|
42050
|
+
} catch (error) {
|
|
42051
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42052
|
+
this.sessionLogger.error({ err: error, scope, name }, "Failed to create role");
|
|
42053
|
+
this.emit({
|
|
42054
|
+
type: "roles/create/response",
|
|
42055
|
+
payload: { requestId, path: "", error: message }
|
|
42056
|
+
});
|
|
42057
|
+
}
|
|
42058
|
+
}
|
|
42059
|
+
async handleRoleWriteFrontmatterRequest(request) {
|
|
42060
|
+
const { path: rolePath, workspaceRoot, frontmatter, requestId } = request;
|
|
42061
|
+
try {
|
|
42062
|
+
await writeRoleFrontmatter(
|
|
42063
|
+
{ path: rolePath, frontmatter },
|
|
42064
|
+
workspaceRoot ? expandTilde(workspaceRoot) : void 0
|
|
42065
|
+
);
|
|
42066
|
+
this.emit({
|
|
42067
|
+
type: "roles/write-frontmatter/response",
|
|
42068
|
+
payload: { requestId, path: rolePath, error: null }
|
|
42069
|
+
});
|
|
42070
|
+
} catch (error) {
|
|
42071
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42072
|
+
this.sessionLogger.error({ err: error, path: rolePath }, "Failed to write role frontmatter");
|
|
42073
|
+
this.emit({
|
|
42074
|
+
type: "roles/write-frontmatter/response",
|
|
42075
|
+
payload: { requestId, path: rolePath, error: message }
|
|
42076
|
+
});
|
|
42077
|
+
}
|
|
42078
|
+
}
|
|
42079
|
+
async handleRoleMoveRequest(request) {
|
|
42080
|
+
const { path: rolePath, newName, newCategory, workspaceRoot, requestId } = request;
|
|
42081
|
+
try {
|
|
42082
|
+
const result = await moveRole(
|
|
42083
|
+
{ path: rolePath, newName, newCategory },
|
|
42084
|
+
workspaceRoot ? expandTilde(workspaceRoot) : void 0
|
|
42085
|
+
);
|
|
42086
|
+
this.emit({
|
|
42087
|
+
type: "roles/move/response",
|
|
42088
|
+
payload: { requestId, path: result.path, error: null }
|
|
42089
|
+
});
|
|
42090
|
+
} catch (error) {
|
|
42091
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42092
|
+
this.sessionLogger.error({ err: error, path: rolePath }, "Failed to move role");
|
|
42093
|
+
this.emit({
|
|
42094
|
+
type: "roles/move/response",
|
|
42095
|
+
payload: { requestId, path: rolePath, error: message }
|
|
42096
|
+
});
|
|
42097
|
+
}
|
|
42098
|
+
}
|
|
42099
|
+
async handleBrandsListScopeRequest(request) {
|
|
42100
|
+
const { workspaceRoot, requestId } = request;
|
|
42101
|
+
try {
|
|
42102
|
+
const brands = await listBrands({
|
|
42103
|
+
...workspaceRoot ? { workspaceRoot: expandTilde(workspaceRoot) } : {}
|
|
42104
|
+
});
|
|
42105
|
+
this.emit({
|
|
42106
|
+
type: "brands/list-scope/response",
|
|
42107
|
+
payload: { requestId, brands, error: null }
|
|
42108
|
+
});
|
|
42109
|
+
} catch (error) {
|
|
42110
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42111
|
+
this.sessionLogger.error({ err: error }, "Failed to list brands");
|
|
42112
|
+
this.emit({
|
|
42113
|
+
type: "brands/list-scope/response",
|
|
42114
|
+
payload: { requestId, brands: [], error: message }
|
|
42115
|
+
});
|
|
42116
|
+
}
|
|
42117
|
+
}
|
|
42118
|
+
async handleBrandCreateRequest(request) {
|
|
42119
|
+
const { name, workspaceRoot, requestId } = request;
|
|
42120
|
+
try {
|
|
42121
|
+
const result = await createBrand({
|
|
42122
|
+
name,
|
|
42123
|
+
...workspaceRoot ? { workspaceRoot: expandTilde(workspaceRoot) } : {}
|
|
42124
|
+
});
|
|
42125
|
+
this.emit({
|
|
42126
|
+
type: "brands/create/response",
|
|
42127
|
+
payload: { requestId, path: result.path, error: null }
|
|
42128
|
+
});
|
|
42129
|
+
} catch (error) {
|
|
42130
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42131
|
+
this.sessionLogger.error({ err: error, name }, "Failed to create brand");
|
|
42132
|
+
this.emit({
|
|
42133
|
+
type: "brands/create/response",
|
|
42134
|
+
payload: { requestId, path: "", error: message }
|
|
42135
|
+
});
|
|
42136
|
+
}
|
|
42137
|
+
}
|
|
42138
|
+
async handleBrandWriteFrontmatterRequest(request) {
|
|
42139
|
+
const { path: brandPath, workspaceRoot, frontmatter, requestId } = request;
|
|
42140
|
+
try {
|
|
42141
|
+
await writeBrandFrontmatter(
|
|
42142
|
+
{ path: brandPath, frontmatter },
|
|
42143
|
+
workspaceRoot ? expandTilde(workspaceRoot) : void 0
|
|
42144
|
+
);
|
|
42145
|
+
this.emit({
|
|
42146
|
+
type: "brands/write-frontmatter/response",
|
|
42147
|
+
payload: { requestId, path: brandPath, error: null }
|
|
42148
|
+
});
|
|
42149
|
+
} catch (error) {
|
|
42150
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42151
|
+
this.sessionLogger.error(
|
|
42152
|
+
{ err: error, path: brandPath },
|
|
42153
|
+
"Failed to write brand frontmatter"
|
|
42154
|
+
);
|
|
42155
|
+
this.emit({
|
|
42156
|
+
type: "brands/write-frontmatter/response",
|
|
42157
|
+
payload: { requestId, path: brandPath, error: message }
|
|
42158
|
+
});
|
|
42159
|
+
}
|
|
42160
|
+
}
|
|
42161
|
+
async handleBrandAssetCopyRequest(request) {
|
|
42162
|
+
const { workspaceRoot, sourcePath, targetName, requestId } = request;
|
|
42163
|
+
try {
|
|
42164
|
+
const result = await copyBrandAsset({
|
|
42165
|
+
workspaceRoot: expandTilde(workspaceRoot),
|
|
42166
|
+
sourcePath: expandTilde(sourcePath),
|
|
42167
|
+
targetName
|
|
42168
|
+
});
|
|
42169
|
+
this.emit({
|
|
42170
|
+
type: "brands/asset-copy/response",
|
|
42171
|
+
payload: {
|
|
42172
|
+
requestId,
|
|
42173
|
+
relativePath: result.relativePath,
|
|
42174
|
+
absolutePath: result.absolutePath,
|
|
42175
|
+
error: null
|
|
42176
|
+
}
|
|
42177
|
+
});
|
|
42178
|
+
} catch (error) {
|
|
42179
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42180
|
+
this.sessionLogger.error(
|
|
42181
|
+
{ err: error, sourcePath, targetName },
|
|
42182
|
+
"Failed to copy brand asset"
|
|
42183
|
+
);
|
|
42184
|
+
this.emit({
|
|
42185
|
+
type: "brands/asset-copy/response",
|
|
42186
|
+
payload: { requestId, relativePath: "", absolutePath: "", error: message }
|
|
42187
|
+
});
|
|
42188
|
+
}
|
|
42189
|
+
}
|
|
42190
|
+
async handleBrandAssetUploadRequest(request) {
|
|
42191
|
+
const { workspaceRoot, targetName, sourceName, dataBase64, requestId } = request;
|
|
42192
|
+
try {
|
|
42193
|
+
const result = await uploadBrandAsset({
|
|
42194
|
+
workspaceRoot: expandTilde(workspaceRoot),
|
|
42195
|
+
targetName,
|
|
42196
|
+
sourceName,
|
|
42197
|
+
dataBase64
|
|
42198
|
+
});
|
|
42199
|
+
this.emit({
|
|
42200
|
+
type: "brands/asset-upload/response",
|
|
42201
|
+
payload: {
|
|
42202
|
+
requestId,
|
|
42203
|
+
relativePath: result.relativePath,
|
|
42204
|
+
absolutePath: result.absolutePath,
|
|
42205
|
+
error: null
|
|
42206
|
+
}
|
|
42207
|
+
});
|
|
42208
|
+
} catch (error) {
|
|
42209
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42210
|
+
this.sessionLogger.error(
|
|
42211
|
+
{ err: error, targetName, sourceName },
|
|
42212
|
+
"Failed to upload brand asset"
|
|
42213
|
+
);
|
|
42214
|
+
this.emit({
|
|
42215
|
+
type: "brands/asset-upload/response",
|
|
42216
|
+
payload: { requestId, relativePath: "", absolutePath: "", error: message }
|
|
42217
|
+
});
|
|
40771
42218
|
}
|
|
40772
42219
|
}
|
|
40773
42220
|
emitTerminalsChangedSnapshot(input) {
|
|
@@ -41593,11 +43040,11 @@ var LoopRecordSchema2 = z39.object({
|
|
|
41593
43040
|
});
|
|
41594
43041
|
var StoredLoopsSchema = z39.array(LoopRecordSchema2);
|
|
41595
43042
|
|
|
41596
|
-
// ../server/src/server/
|
|
43043
|
+
// ../server/src/server/quest/store.ts
|
|
41597
43044
|
import { z as z40 } from "zod";
|
|
41598
|
-
var
|
|
43045
|
+
var StoredQuestsSchema = z40.array(QuestRecordSchema);
|
|
41599
43046
|
|
|
41600
|
-
// ../server/src/server/
|
|
43047
|
+
// ../server/src/server/quest/runner-ralph.ts
|
|
41601
43048
|
import { promisify as promisify4 } from "node:util";
|
|
41602
43049
|
import { execFile as execFile3 } from "node:child_process";
|
|
41603
43050
|
var execFileAsync3 = promisify4(execFile3);
|
|
@@ -41643,16 +43090,16 @@ function isRelayClientWebSocketUrl(url) {
|
|
|
41643
43090
|
}
|
|
41644
43091
|
|
|
41645
43092
|
// ../server/src/server/config.ts
|
|
41646
|
-
import
|
|
43093
|
+
import path17 from "node:path";
|
|
41647
43094
|
import { z as z45 } from "zod";
|
|
41648
43095
|
|
|
41649
43096
|
// ../server/src/server/speech/speech-config-resolver.ts
|
|
41650
43097
|
import { z as z44 } from "zod";
|
|
41651
43098
|
|
|
41652
43099
|
// ../server/src/server/speech/providers/local/config.ts
|
|
41653
|
-
import
|
|
43100
|
+
import path16 from "node:path";
|
|
41654
43101
|
import { z as z42 } from "zod";
|
|
41655
|
-
var DEFAULT_LOCAL_MODELS_SUBDIR =
|
|
43102
|
+
var DEFAULT_LOCAL_MODELS_SUBDIR = path16.join("models", "local-speech");
|
|
41656
43103
|
var NumberLikeSchema2 = z42.union([z42.number(), z42.string().trim().min(1)]);
|
|
41657
43104
|
var OptionalFiniteNumberSchema2 = NumberLikeSchema2.pipe(z42.coerce.number().finite()).optional();
|
|
41658
43105
|
var OptionalIntegerSchema = NumberLikeSchema2.pipe(z42.coerce.number().int()).optional();
|
|
@@ -41679,7 +43126,7 @@ function resolveLocalSpeechConfig(params) {
|
|
|
41679
43126
|
const includeProviderConfig = shouldIncludeLocalProviderConfig(params);
|
|
41680
43127
|
const parsed = LocalSpeechResolutionSchema.parse({
|
|
41681
43128
|
includeProviderConfig,
|
|
41682
|
-
modelsDir: params.env.APPOSTLE_LOCAL_MODELS_DIR ?? params.persisted.providers?.local?.modelsDir ??
|
|
43129
|
+
modelsDir: params.env.APPOSTLE_LOCAL_MODELS_DIR ?? params.persisted.providers?.local?.modelsDir ?? path16.join(params.appostleHome, DEFAULT_LOCAL_MODELS_SUBDIR),
|
|
41683
43130
|
dictationLocalSttModel: params.env.APPOSTLE_DICTATION_LOCAL_STT_MODEL ?? persistedLocalFeatureModel(
|
|
41684
43131
|
params.providers.dictationStt.provider,
|
|
41685
43132
|
params.providers.dictationStt.enabled,
|
|
@@ -41935,7 +43382,7 @@ function loadConfig(appostleHome, options) {
|
|
|
41935
43382
|
chromeEnabled,
|
|
41936
43383
|
mcpDebug: env.MCP_DEBUG === "1",
|
|
41937
43384
|
daemonIcon,
|
|
41938
|
-
agentStoragePath:
|
|
43385
|
+
agentStoragePath: path17.join(appostleHome, "agents"),
|
|
41939
43386
|
staticDir: "public",
|
|
41940
43387
|
agentClients: {},
|
|
41941
43388
|
relayEnabled,
|
|
@@ -43153,12 +44600,12 @@ var DaemonClient = class {
|
|
|
43153
44600
|
timeout: 1e4
|
|
43154
44601
|
});
|
|
43155
44602
|
}
|
|
43156
|
-
async openInEditor(
|
|
44603
|
+
async openInEditor(path24, editorId, requestId) {
|
|
43157
44604
|
return this.sendCorrelatedSessionRequest({
|
|
43158
44605
|
requestId,
|
|
43159
44606
|
message: {
|
|
43160
44607
|
type: "open_in_editor_request",
|
|
43161
|
-
path:
|
|
44608
|
+
path: path24,
|
|
43162
44609
|
editorId
|
|
43163
44610
|
},
|
|
43164
44611
|
responseType: "open_in_editor_response",
|
|
@@ -43367,6 +44814,7 @@ var DaemonClient = class {
|
|
|
43367
44814
|
agentId,
|
|
43368
44815
|
...updates.name !== void 0 ? { name: updates.name } : {},
|
|
43369
44816
|
...updates.labels && Object.keys(updates.labels).length > 0 ? { labels: updates.labels } : {},
|
|
44817
|
+
...updates.internal !== void 0 ? { internal: updates.internal } : {},
|
|
43370
44818
|
requestId
|
|
43371
44819
|
});
|
|
43372
44820
|
const payload = await this.sendRequest({
|
|
@@ -44419,13 +45867,13 @@ var DaemonClient = class {
|
|
|
44419
45867
|
// ============================================================================
|
|
44420
45868
|
// File Explorer
|
|
44421
45869
|
// ============================================================================
|
|
44422
|
-
async exploreFileSystem(cwd,
|
|
45870
|
+
async exploreFileSystem(cwd, path24, mode = "list", requestId) {
|
|
44423
45871
|
return this.sendCorrelatedSessionRequest({
|
|
44424
45872
|
requestId,
|
|
44425
45873
|
message: {
|
|
44426
45874
|
type: "file_explorer_request",
|
|
44427
45875
|
cwd,
|
|
44428
|
-
path:
|
|
45876
|
+
path: path24,
|
|
44429
45877
|
mode
|
|
44430
45878
|
},
|
|
44431
45879
|
responseType: "file_explorer_response",
|
|
@@ -44437,13 +45885,13 @@ var DaemonClient = class {
|
|
|
44437
45885
|
* allowlists extensions (currently `.md` only) — callers don't need to
|
|
44438
45886
|
* re-check. Used by the plan-todos UI to rewrite plan-file frontmatter.
|
|
44439
45887
|
*/
|
|
44440
|
-
async writeFile(cwd,
|
|
45888
|
+
async writeFile(cwd, path24, content, requestId) {
|
|
44441
45889
|
return this.sendCorrelatedSessionRequest({
|
|
44442
45890
|
requestId,
|
|
44443
45891
|
message: {
|
|
44444
45892
|
type: "file_write_request",
|
|
44445
45893
|
cwd,
|
|
44446
|
-
path:
|
|
45894
|
+
path: path24,
|
|
44447
45895
|
content
|
|
44448
45896
|
},
|
|
44449
45897
|
responseType: "file_write_response",
|
|
@@ -44456,30 +45904,54 @@ var DaemonClient = class {
|
|
|
44456
45904
|
* action is the only consumer). Returns the daemon's structured response
|
|
44457
45905
|
* so callers can surface the error in the UI.
|
|
44458
45906
|
*/
|
|
44459
|
-
async deleteFile(cwd,
|
|
45907
|
+
async deleteFile(cwd, path24, requestId) {
|
|
44460
45908
|
return this.sendCorrelatedSessionRequest({
|
|
44461
45909
|
requestId,
|
|
44462
45910
|
message: {
|
|
44463
45911
|
type: "file_delete_request",
|
|
44464
45912
|
cwd,
|
|
44465
|
-
path:
|
|
45913
|
+
path: path24
|
|
44466
45914
|
},
|
|
44467
45915
|
responseType: "file_delete_response",
|
|
44468
45916
|
timeout: 1e4
|
|
44469
45917
|
});
|
|
44470
45918
|
}
|
|
44471
|
-
async requestDownloadToken(cwd,
|
|
45919
|
+
async requestDownloadToken(cwd, path24, requestId) {
|
|
44472
45920
|
return this.sendCorrelatedSessionRequest({
|
|
44473
45921
|
requestId,
|
|
44474
45922
|
message: {
|
|
44475
45923
|
type: "file_download_token_request",
|
|
44476
45924
|
cwd,
|
|
44477
|
-
path:
|
|
45925
|
+
path: path24
|
|
44478
45926
|
},
|
|
44479
45927
|
responseType: "file_download_token_response",
|
|
44480
45928
|
timeout: 1e4
|
|
44481
45929
|
});
|
|
44482
45930
|
}
|
|
45931
|
+
async explorerDeleteEntry(cwd, path24, requestId) {
|
|
45932
|
+
return this.sendCorrelatedSessionRequest({
|
|
45933
|
+
requestId,
|
|
45934
|
+
message: { type: "file_explorer_delete_request", cwd, path: path24 },
|
|
45935
|
+
responseType: "file_explorer_delete_response",
|
|
45936
|
+
timeout: 1e4
|
|
45937
|
+
});
|
|
45938
|
+
}
|
|
45939
|
+
async explorerMkdir(cwd, path24, requestId) {
|
|
45940
|
+
return this.sendCorrelatedSessionRequest({
|
|
45941
|
+
requestId,
|
|
45942
|
+
message: { type: "file_mkdir_request", cwd, path: path24 },
|
|
45943
|
+
responseType: "file_mkdir_response",
|
|
45944
|
+
timeout: 1e4
|
|
45945
|
+
});
|
|
45946
|
+
}
|
|
45947
|
+
async explorerMoveEntry(cwd, sourcePath, destinationPath, requestId) {
|
|
45948
|
+
return this.sendCorrelatedSessionRequest({
|
|
45949
|
+
requestId,
|
|
45950
|
+
message: { type: "file_move_request", cwd, sourcePath, destinationPath },
|
|
45951
|
+
responseType: "file_move_response",
|
|
45952
|
+
timeout: 1e4
|
|
45953
|
+
});
|
|
45954
|
+
}
|
|
44483
45955
|
async requestProjectIcon(cwd, requestId) {
|
|
44484
45956
|
return this.sendCorrelatedSessionRequest({
|
|
44485
45957
|
requestId,
|
|
@@ -45214,61 +46686,177 @@ var DaemonClient = class {
|
|
|
45214
46686
|
timeout: 1e4
|
|
45215
46687
|
});
|
|
45216
46688
|
}
|
|
45217
|
-
async
|
|
46689
|
+
async questRun(options) {
|
|
45218
46690
|
return this.sendCorrelatedSessionRequest({
|
|
45219
46691
|
requestId: options.requestId,
|
|
45220
46692
|
message: {
|
|
45221
|
-
type: "
|
|
46693
|
+
type: "quest/run",
|
|
45222
46694
|
kind: options.kind,
|
|
45223
46695
|
cwd: options.cwd,
|
|
45224
46696
|
prompt: options.prompt,
|
|
45225
46697
|
...options.defaultProvider ? { defaultProvider: options.defaultProvider } : {},
|
|
45226
|
-
...options.defaultModel
|
|
46698
|
+
...options.defaultModel ? { defaultModel: options.defaultModel } : {},
|
|
45227
46699
|
termination: options.termination,
|
|
45228
46700
|
...options.cards ? { cards: [...options.cards] } : {},
|
|
45229
46701
|
...typeof options.summarizerEnabled === "boolean" ? { summarizerEnabled: options.summarizerEnabled } : {}
|
|
45230
46702
|
},
|
|
45231
|
-
responseType: "
|
|
46703
|
+
responseType: "quest/run/response",
|
|
45232
46704
|
timeout: 15e3
|
|
45233
46705
|
});
|
|
45234
46706
|
}
|
|
45235
|
-
async
|
|
46707
|
+
async questList(requestId) {
|
|
45236
46708
|
return this.sendCorrelatedSessionRequest({
|
|
45237
46709
|
requestId,
|
|
45238
|
-
message: { type: "
|
|
45239
|
-
responseType: "
|
|
46710
|
+
message: { type: "quest/list" },
|
|
46711
|
+
responseType: "quest/list/response",
|
|
45240
46712
|
timeout: 1e4
|
|
45241
46713
|
});
|
|
45242
46714
|
}
|
|
45243
|
-
async
|
|
46715
|
+
async questInspect(options) {
|
|
45244
46716
|
const normalized = typeof options === "string" ? { id: options } : options;
|
|
45245
46717
|
return this.sendCorrelatedSessionRequest({
|
|
45246
46718
|
requestId: normalized.requestId,
|
|
45247
|
-
message: { type: "
|
|
45248
|
-
responseType: "
|
|
46719
|
+
message: { type: "quest/inspect", id: normalized.id },
|
|
46720
|
+
responseType: "quest/inspect/response",
|
|
45249
46721
|
timeout: 1e4
|
|
45250
46722
|
});
|
|
45251
46723
|
}
|
|
45252
|
-
async
|
|
46724
|
+
async questStop(options) {
|
|
45253
46725
|
const normalized = typeof options === "string" ? { id: options } : options;
|
|
45254
46726
|
return this.sendCorrelatedSessionRequest({
|
|
45255
46727
|
requestId: normalized.requestId,
|
|
45256
|
-
message: { type: "
|
|
45257
|
-
responseType: "
|
|
46728
|
+
message: { type: "quest/stop", id: normalized.id },
|
|
46729
|
+
responseType: "quest/stop/response",
|
|
46730
|
+
timeout: 1e4
|
|
46731
|
+
});
|
|
46732
|
+
}
|
|
46733
|
+
async rolesList(options = {}) {
|
|
46734
|
+
return this.sendCorrelatedSessionRequest({
|
|
46735
|
+
requestId: options.requestId,
|
|
46736
|
+
message: {
|
|
46737
|
+
type: "roles/list",
|
|
46738
|
+
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
46739
|
+
},
|
|
46740
|
+
responseType: "roles/list/response",
|
|
45258
46741
|
timeout: 1e4
|
|
45259
46742
|
});
|
|
45260
46743
|
}
|
|
45261
|
-
async
|
|
46744
|
+
async rolesListScope(options) {
|
|
45262
46745
|
return this.sendCorrelatedSessionRequest({
|
|
45263
46746
|
requestId: options.requestId,
|
|
45264
46747
|
message: {
|
|
45265
|
-
type: "
|
|
46748
|
+
type: "roles/list-scope",
|
|
46749
|
+
scope: options.scope,
|
|
45266
46750
|
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
45267
46751
|
},
|
|
45268
|
-
responseType: "
|
|
46752
|
+
responseType: "roles/list-scope/response",
|
|
45269
46753
|
timeout: 1e4
|
|
45270
46754
|
});
|
|
45271
46755
|
}
|
|
46756
|
+
async rolesCreate(options) {
|
|
46757
|
+
return this.sendCorrelatedSessionRequest({
|
|
46758
|
+
requestId: options.requestId,
|
|
46759
|
+
message: {
|
|
46760
|
+
type: "roles/create",
|
|
46761
|
+
scope: options.scope,
|
|
46762
|
+
name: options.name,
|
|
46763
|
+
...options.category ? { category: options.category } : {},
|
|
46764
|
+
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
46765
|
+
},
|
|
46766
|
+
responseType: "roles/create/response",
|
|
46767
|
+
timeout: 1e4
|
|
46768
|
+
});
|
|
46769
|
+
}
|
|
46770
|
+
async rolesWriteFrontmatter(options) {
|
|
46771
|
+
return this.sendCorrelatedSessionRequest({
|
|
46772
|
+
requestId: options.requestId,
|
|
46773
|
+
message: {
|
|
46774
|
+
type: "roles/write-frontmatter",
|
|
46775
|
+
path: options.path,
|
|
46776
|
+
frontmatter: options.frontmatter,
|
|
46777
|
+
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
46778
|
+
},
|
|
46779
|
+
responseType: "roles/write-frontmatter/response",
|
|
46780
|
+
timeout: 1e4
|
|
46781
|
+
});
|
|
46782
|
+
}
|
|
46783
|
+
async rolesMove(options) {
|
|
46784
|
+
return this.sendCorrelatedSessionRequest({
|
|
46785
|
+
requestId: options.requestId,
|
|
46786
|
+
message: {
|
|
46787
|
+
type: "roles/move",
|
|
46788
|
+
path: options.path,
|
|
46789
|
+
...options.newName ? { newName: options.newName } : {},
|
|
46790
|
+
...options.newCategory !== void 0 ? { newCategory: options.newCategory } : {},
|
|
46791
|
+
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
46792
|
+
},
|
|
46793
|
+
responseType: "roles/move/response",
|
|
46794
|
+
timeout: 1e4
|
|
46795
|
+
});
|
|
46796
|
+
}
|
|
46797
|
+
async brandsListScope(options) {
|
|
46798
|
+
return this.sendCorrelatedSessionRequest({
|
|
46799
|
+
requestId: options.requestId,
|
|
46800
|
+
message: {
|
|
46801
|
+
type: "brands/list-scope",
|
|
46802
|
+
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
46803
|
+
},
|
|
46804
|
+
responseType: "brands/list-scope/response",
|
|
46805
|
+
timeout: 1e4
|
|
46806
|
+
});
|
|
46807
|
+
}
|
|
46808
|
+
async brandsCreate(options) {
|
|
46809
|
+
return this.sendCorrelatedSessionRequest({
|
|
46810
|
+
requestId: options.requestId,
|
|
46811
|
+
message: {
|
|
46812
|
+
type: "brands/create",
|
|
46813
|
+
name: options.name,
|
|
46814
|
+
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
46815
|
+
},
|
|
46816
|
+
responseType: "brands/create/response",
|
|
46817
|
+
timeout: 1e4
|
|
46818
|
+
});
|
|
46819
|
+
}
|
|
46820
|
+
async brandsWriteFrontmatter(options) {
|
|
46821
|
+
return this.sendCorrelatedSessionRequest({
|
|
46822
|
+
requestId: options.requestId,
|
|
46823
|
+
message: {
|
|
46824
|
+
type: "brands/write-frontmatter",
|
|
46825
|
+
path: options.path,
|
|
46826
|
+
frontmatter: options.frontmatter,
|
|
46827
|
+
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
46828
|
+
},
|
|
46829
|
+
responseType: "brands/write-frontmatter/response",
|
|
46830
|
+
timeout: 1e4
|
|
46831
|
+
});
|
|
46832
|
+
}
|
|
46833
|
+
async brandsAssetCopy(options) {
|
|
46834
|
+
return this.sendCorrelatedSessionRequest({
|
|
46835
|
+
requestId: options.requestId,
|
|
46836
|
+
message: {
|
|
46837
|
+
type: "brands/asset-copy",
|
|
46838
|
+
workspaceRoot: options.workspaceRoot,
|
|
46839
|
+
sourcePath: options.sourcePath,
|
|
46840
|
+
targetName: options.targetName
|
|
46841
|
+
},
|
|
46842
|
+
responseType: "brands/asset-copy/response",
|
|
46843
|
+
timeout: 15e3
|
|
46844
|
+
});
|
|
46845
|
+
}
|
|
46846
|
+
async brandsAssetUpload(options) {
|
|
46847
|
+
return this.sendCorrelatedSessionRequest({
|
|
46848
|
+
requestId: options.requestId,
|
|
46849
|
+
message: {
|
|
46850
|
+
type: "brands/asset-upload",
|
|
46851
|
+
workspaceRoot: options.workspaceRoot,
|
|
46852
|
+
targetName: options.targetName,
|
|
46853
|
+
...options.sourceName ? { sourceName: options.sourceName } : {},
|
|
46854
|
+
dataBase64: options.dataBase64
|
|
46855
|
+
},
|
|
46856
|
+
responseType: "brands/asset-upload/response",
|
|
46857
|
+
timeout: 2e4
|
|
46858
|
+
});
|
|
46859
|
+
}
|
|
45272
46860
|
onTerminalStreamEvent(handler) {
|
|
45273
46861
|
this.terminalStreamListeners.add(handler);
|
|
45274
46862
|
return () => {
|
|
@@ -45741,7 +47329,7 @@ function resolveAgentConfig(options) {
|
|
|
45741
47329
|
}
|
|
45742
47330
|
|
|
45743
47331
|
// ../cli/src/utils/client.ts
|
|
45744
|
-
import
|
|
47332
|
+
import path18 from "node:path";
|
|
45745
47333
|
import WebSocket3 from "ws";
|
|
45746
47334
|
|
|
45747
47335
|
// ../cli/src/utils/client-id.ts
|
|
@@ -45817,7 +47405,7 @@ function isTcpDaemonHost(host) {
|
|
|
45817
47405
|
return host !== null && !isIpcDaemonHost(host);
|
|
45818
47406
|
}
|
|
45819
47407
|
function readPidSocketTarget(appostleHome) {
|
|
45820
|
-
const pidPath =
|
|
47408
|
+
const pidPath = path18.join(appostleHome, PID_FILENAME);
|
|
45821
47409
|
if (!existsSync10(pidPath)) {
|
|
45822
47410
|
return null;
|
|
45823
47411
|
}
|
|
@@ -46286,12 +47874,12 @@ function relativeTime(date) {
|
|
|
46286
47874
|
if (seconds < 86400) return `${Math.floor(seconds / 3600)} hours ago`;
|
|
46287
47875
|
return `${Math.floor(seconds / 86400)} days ago`;
|
|
46288
47876
|
}
|
|
46289
|
-
function shortenPath(
|
|
47877
|
+
function shortenPath(path24) {
|
|
46290
47878
|
const home = process.env.HOME;
|
|
46291
|
-
if (home &&
|
|
46292
|
-
return "~" +
|
|
47879
|
+
if (home && path24.startsWith(home)) {
|
|
47880
|
+
return "~" + path24.slice(home.length);
|
|
46293
47881
|
}
|
|
46294
|
-
return
|
|
47882
|
+
return path24;
|
|
46295
47883
|
}
|
|
46296
47884
|
function normalizeModelId(modelId) {
|
|
46297
47885
|
if (typeof modelId !== "string") return null;
|
|
@@ -47148,10 +48736,10 @@ function addSendOptions(cmd) {
|
|
|
47148
48736
|
}
|
|
47149
48737
|
async function readImageFiles(imagePaths) {
|
|
47150
48738
|
const images = [];
|
|
47151
|
-
for (const
|
|
48739
|
+
for (const path24 of imagePaths) {
|
|
47152
48740
|
try {
|
|
47153
|
-
const buffer = await readFile5(
|
|
47154
|
-
const ext = extname3(
|
|
48741
|
+
const buffer = await readFile5(path24);
|
|
48742
|
+
const ext = extname3(path24).toLowerCase();
|
|
47155
48743
|
let mimeType = "image/jpeg";
|
|
47156
48744
|
switch (ext) {
|
|
47157
48745
|
case ".png":
|
|
@@ -47179,7 +48767,7 @@ async function readImageFiles(imagePaths) {
|
|
|
47179
48767
|
const message = err instanceof Error ? err.message : String(err);
|
|
47180
48768
|
const error = {
|
|
47181
48769
|
code: "IMAGE_READ_ERROR",
|
|
47182
|
-
message: `Failed to read image file: ${
|
|
48770
|
+
message: `Failed to read image file: ${path24}`,
|
|
47183
48771
|
details: message
|
|
47184
48772
|
};
|
|
47185
48773
|
throw error;
|
|
@@ -47352,12 +48940,12 @@ function createInspectSchema(agent) {
|
|
|
47352
48940
|
serialize: (_item) => agent
|
|
47353
48941
|
};
|
|
47354
48942
|
}
|
|
47355
|
-
function shortenPath2(
|
|
48943
|
+
function shortenPath2(path24) {
|
|
47356
48944
|
const home = process.env.HOME;
|
|
47357
|
-
if (home &&
|
|
47358
|
-
return "~" +
|
|
48945
|
+
if (home && path24.startsWith(home)) {
|
|
48946
|
+
return "~" + path24.slice(home.length);
|
|
47359
48947
|
}
|
|
47360
|
-
return
|
|
48948
|
+
return path24;
|
|
47361
48949
|
}
|
|
47362
48950
|
function formatCost(costUsd) {
|
|
47363
48951
|
if (costUsd === 0) return "$0.00";
|
|
@@ -48325,7 +49913,7 @@ import chalk3 from "chalk";
|
|
|
48325
49913
|
import { spawn as spawn7, spawnSync } from "node:child_process";
|
|
48326
49914
|
import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
|
|
48327
49915
|
import { createRequire as createRequire3 } from "node:module";
|
|
48328
|
-
import
|
|
49916
|
+
import path19 from "node:path";
|
|
48329
49917
|
import { fileURLToPath } from "node:url";
|
|
48330
49918
|
var DETACHED_STARTUP_GRACE_MS = 1200;
|
|
48331
49919
|
var PID_POLL_INTERVAL_MS = 100;
|
|
@@ -48376,7 +49964,7 @@ function buildChildEnv(options) {
|
|
|
48376
49964
|
function resolveDaemonRunnerEntry() {
|
|
48377
49965
|
try {
|
|
48378
49966
|
const here = fileURLToPath(import.meta.url);
|
|
48379
|
-
const sibling =
|
|
49967
|
+
const sibling = path19.join(path19.dirname(here), "supervisor-entrypoint.js");
|
|
48380
49968
|
if (existsSync11(sibling)) {
|
|
48381
49969
|
return sibling;
|
|
48382
49970
|
}
|
|
@@ -48390,23 +49978,23 @@ function resolveDaemonRunnerEntry() {
|
|
|
48390
49978
|
"Unable to resolve @appostle/server package root for daemon runner (and no sibling supervisor-entrypoint.js was bundled)"
|
|
48391
49979
|
);
|
|
48392
49980
|
}
|
|
48393
|
-
let currentDir =
|
|
49981
|
+
let currentDir = path19.dirname(serverExportPath);
|
|
48394
49982
|
while (true) {
|
|
48395
|
-
const packageJsonPath =
|
|
49983
|
+
const packageJsonPath = path19.join(currentDir, "package.json");
|
|
48396
49984
|
if (existsSync11(packageJsonPath)) {
|
|
48397
49985
|
try {
|
|
48398
49986
|
const packageJson = JSON.parse(readFileSync8(packageJsonPath, "utf-8"));
|
|
48399
49987
|
if (packageJson.name === "@appostle/server") {
|
|
48400
|
-
const distRunner =
|
|
49988
|
+
const distRunner = path19.join(currentDir, "dist", "scripts", "supervisor-entrypoint.js");
|
|
48401
49989
|
if (existsSync11(distRunner)) {
|
|
48402
49990
|
return distRunner;
|
|
48403
49991
|
}
|
|
48404
|
-
return
|
|
49992
|
+
return path19.join(currentDir, "scripts", "supervisor-entrypoint.ts");
|
|
48405
49993
|
}
|
|
48406
49994
|
} catch {
|
|
48407
49995
|
}
|
|
48408
49996
|
}
|
|
48409
|
-
const parentDir =
|
|
49997
|
+
const parentDir = path19.dirname(currentDir);
|
|
48410
49998
|
if (parentDir === currentDir) {
|
|
48411
49999
|
break;
|
|
48412
50000
|
}
|
|
@@ -48415,7 +50003,7 @@ function resolveDaemonRunnerEntry() {
|
|
|
48415
50003
|
throw new Error("Unable to resolve @appostle/server package root for daemon runner");
|
|
48416
50004
|
}
|
|
48417
50005
|
function pidFilePath(appostleHome) {
|
|
48418
|
-
return
|
|
50006
|
+
return path19.join(appostleHome, DAEMON_PID_FILENAME);
|
|
48419
50007
|
}
|
|
48420
50008
|
function readPidFile(pidPath) {
|
|
48421
50009
|
try {
|
|
@@ -48557,7 +50145,7 @@ function resolveLocalDaemonState(options = {}) {
|
|
|
48557
50145
|
const home = resolveAppostleHome(env);
|
|
48558
50146
|
const config = loadConfig(home, { env });
|
|
48559
50147
|
const pidPath = pidFilePath(home);
|
|
48560
|
-
const logPath =
|
|
50148
|
+
const logPath = path19.join(home, DAEMON_LOG_FILENAME);
|
|
48561
50149
|
const pidInfo = existsSync11(pidPath) ? readPidFile(pidPath) : null;
|
|
48562
50150
|
const running = pidInfo ? isProcessRunning(pidInfo.pid) : false;
|
|
48563
50151
|
const listen = pidInfo?.listen ?? config.listen;
|
|
@@ -48572,7 +50160,7 @@ function resolveLocalDaemonState(options = {}) {
|
|
|
48572
50160
|
};
|
|
48573
50161
|
}
|
|
48574
50162
|
function tailDaemonLog(home, lines = 30) {
|
|
48575
|
-
const logPath =
|
|
50163
|
+
const logPath = path19.join(resolveLocalAppostleHome(home), DAEMON_LOG_FILENAME);
|
|
48576
50164
|
return tailFile(logPath, lines);
|
|
48577
50165
|
}
|
|
48578
50166
|
async function startLocalDaemonDetached(options) {
|
|
@@ -48581,7 +50169,7 @@ async function startLocalDaemonDetached(options) {
|
|
|
48581
50169
|
}
|
|
48582
50170
|
const childEnv = buildChildEnv(options);
|
|
48583
50171
|
const appostleHome = resolveAppostleHome(childEnv);
|
|
48584
|
-
const logPath =
|
|
50172
|
+
const logPath = path19.join(appostleHome, DAEMON_LOG_FILENAME);
|
|
48585
50173
|
const daemonRunnerEntry = resolveDaemonRunnerEntry();
|
|
48586
50174
|
const child = spawn7(
|
|
48587
50175
|
process.execPath,
|
|
@@ -51307,15 +52895,15 @@ import { Command as Command13 } from "commander";
|
|
|
51307
52895
|
// ../cli/src/commands/worktree/ls.ts
|
|
51308
52896
|
import { homedir as homedir7 } from "node:os";
|
|
51309
52897
|
import { basename as basename7, join as join11, sep as sep3 } from "node:path";
|
|
51310
|
-
function shortenPath3(
|
|
52898
|
+
function shortenPath3(path24) {
|
|
51311
52899
|
const home = process.env.HOME;
|
|
51312
|
-
if (home &&
|
|
51313
|
-
return "~" +
|
|
52900
|
+
if (home && path24.startsWith(home)) {
|
|
52901
|
+
return "~" + path24.slice(home.length);
|
|
51314
52902
|
}
|
|
51315
|
-
return
|
|
52903
|
+
return path24;
|
|
51316
52904
|
}
|
|
51317
|
-
function extractWorktreeName(
|
|
51318
|
-
return basename7(
|
|
52905
|
+
function extractWorktreeName(path24) {
|
|
52906
|
+
return basename7(path24);
|
|
51319
52907
|
}
|
|
51320
52908
|
function resolveAppostleHomePath() {
|
|
51321
52909
|
return process.env.APPOSTLE_HOME ?? join11(homedir7(), ".appostle");
|
|
@@ -51395,7 +52983,7 @@ async function runLsCommand7(options, _command) {
|
|
|
51395
52983
|
}
|
|
51396
52984
|
|
|
51397
52985
|
// ../cli/src/commands/worktree/archive.ts
|
|
51398
|
-
import
|
|
52986
|
+
import path20 from "path";
|
|
51399
52987
|
var archiveSchema2 = {
|
|
51400
52988
|
idField: "name",
|
|
51401
52989
|
columns: [
|
|
@@ -51439,7 +53027,7 @@ async function runArchiveCommand2(nameArg, options, _command) {
|
|
|
51439
53027
|
throw error;
|
|
51440
53028
|
}
|
|
51441
53029
|
const worktree = listResponse.worktrees.find((wt) => {
|
|
51442
|
-
const name =
|
|
53030
|
+
const name = path20.basename(wt.worktreePath);
|
|
51443
53031
|
return name === nameArg || wt.branchName === nameArg;
|
|
51444
53032
|
});
|
|
51445
53033
|
if (!worktree) {
|
|
@@ -51461,7 +53049,7 @@ async function runArchiveCommand2(nameArg, options, _command) {
|
|
|
51461
53049
|
};
|
|
51462
53050
|
throw error;
|
|
51463
53051
|
}
|
|
51464
|
-
const worktreeName =
|
|
53052
|
+
const worktreeName = path20.basename(worktree.worktreePath) || nameArg;
|
|
51465
53053
|
return {
|
|
51466
53054
|
type: "single",
|
|
51467
53055
|
data: {
|
|
@@ -51502,7 +53090,7 @@ function createWorktreeCommand() {
|
|
|
51502
53090
|
import { cancel, confirm, intro, isCancel, log, note, outro, spinner } from "@clack/prompts";
|
|
51503
53091
|
import { Command as Command14, Option as Option4 } from "commander";
|
|
51504
53092
|
import { writeFileSync as writeFileSync5 } from "node:fs";
|
|
51505
|
-
import
|
|
53093
|
+
import path21 from "node:path";
|
|
51506
53094
|
var DEFAULT_READY_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
51507
53095
|
var OnboardCancelledError = class extends Error {
|
|
51508
53096
|
};
|
|
@@ -51545,7 +53133,7 @@ function toCliOverrides(options) {
|
|
|
51545
53133
|
return cliOverrides;
|
|
51546
53134
|
}
|
|
51547
53135
|
function savePersistedConfig2(appostleHome, config) {
|
|
51548
|
-
const configPath =
|
|
53136
|
+
const configPath = path21.join(appostleHome, "config.json");
|
|
51549
53137
|
writeFileSync5(configPath, `${JSON.stringify(config, null, 2)}
|
|
51550
53138
|
`);
|
|
51551
53139
|
}
|
|
@@ -51666,7 +53254,7 @@ ${recentLogs}` : null
|
|
|
51666
53254
|
);
|
|
51667
53255
|
}
|
|
51668
53256
|
function printNextSteps(pairingUrl, appostleHome, richUi) {
|
|
51669
|
-
const daemonLogPath =
|
|
53257
|
+
const daemonLogPath = path21.join(appostleHome, "daemon.log");
|
|
51670
53258
|
const nextStepsLines = [
|
|
51671
53259
|
pairingUrl ? "1. Open Appostle and scan the QR code above, or paste the pairing link." : "1. Open Appostle and connect to your daemon.",
|
|
51672
53260
|
"2. Web app: https://appostle.app",
|
|
@@ -51920,18 +53508,18 @@ function createCli() {
|
|
|
51920
53508
|
// ../cli/src/classify.ts
|
|
51921
53509
|
import { existsSync as existsSync12, statSync as statSync3 } from "node:fs";
|
|
51922
53510
|
import { homedir as homedir8 } from "node:os";
|
|
51923
|
-
import
|
|
53511
|
+
import path22 from "node:path";
|
|
51924
53512
|
function expandUserPath2(inputPath) {
|
|
51925
53513
|
if (inputPath === "~") {
|
|
51926
53514
|
return homedir8();
|
|
51927
53515
|
}
|
|
51928
53516
|
if (inputPath.startsWith("~/")) {
|
|
51929
|
-
return
|
|
53517
|
+
return path22.join(homedir8(), inputPath.slice(2));
|
|
51930
53518
|
}
|
|
51931
53519
|
return inputPath;
|
|
51932
53520
|
}
|
|
51933
53521
|
function isExistingDirectory(input) {
|
|
51934
|
-
const resolvedPath =
|
|
53522
|
+
const resolvedPath = path22.resolve(input.cwd, expandUserPath2(input.pathArg));
|
|
51935
53523
|
if (!existsSync12(resolvedPath)) {
|
|
51936
53524
|
return false;
|
|
51937
53525
|
}
|
|
@@ -51951,7 +53539,7 @@ function classifyInvocation(input) {
|
|
|
51951
53539
|
if (isExistingDirectory({ pathArg: firstArg, cwd: input.cwd })) {
|
|
51952
53540
|
return {
|
|
51953
53541
|
kind: "open-project",
|
|
51954
|
-
resolvedPath:
|
|
53542
|
+
resolvedPath: path22.resolve(input.cwd, expandUserPath2(firstArg))
|
|
51955
53543
|
};
|
|
51956
53544
|
}
|
|
51957
53545
|
return { kind: "cli", argv: input.argv };
|
|
@@ -51961,12 +53549,12 @@ function classifyInvocation(input) {
|
|
|
51961
53549
|
import { existsSync as existsSync13 } from "node:fs";
|
|
51962
53550
|
import { spawn as spawn8 } from "node:child_process";
|
|
51963
53551
|
import { homedir as homedir9 } from "node:os";
|
|
51964
|
-
import
|
|
53552
|
+
import path23 from "node:path";
|
|
51965
53553
|
function findDesktopApp() {
|
|
51966
53554
|
if (process.platform === "darwin") {
|
|
51967
53555
|
const candidates = [
|
|
51968
53556
|
"/Applications/Appostle.app",
|
|
51969
|
-
|
|
53557
|
+
path23.join(homedir9(), "Applications", "Appostle.app")
|
|
51970
53558
|
];
|
|
51971
53559
|
for (const candidate of candidates) {
|
|
51972
53560
|
if (existsSync13(candidate)) {
|
|
@@ -51979,7 +53567,7 @@ function findDesktopApp() {
|
|
|
51979
53567
|
const candidates = [
|
|
51980
53568
|
"/usr/bin/Appostle",
|
|
51981
53569
|
"/opt/Appostle/Appostle",
|
|
51982
|
-
|
|
53570
|
+
path23.join(homedir9(), "Applications", "Appostle.AppImage")
|
|
51983
53571
|
];
|
|
51984
53572
|
for (const candidate of candidates) {
|
|
51985
53573
|
if (existsSync13(candidate)) {
|
|
@@ -51993,7 +53581,7 @@ function findDesktopApp() {
|
|
|
51993
53581
|
if (!localAppData) {
|
|
51994
53582
|
return null;
|
|
51995
53583
|
}
|
|
51996
|
-
const candidate =
|
|
53584
|
+
const candidate = path23.join(localAppData, "Programs", "Appostle", "Appostle.exe");
|
|
51997
53585
|
return existsSync13(candidate) ? candidate : null;
|
|
51998
53586
|
}
|
|
51999
53587
|
return null;
|