newtype-profile 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -2253,7 +2253,7 @@ var require_picocolors = __commonJS((exports, module) => {
2253
2253
  var require_package = __commonJS((exports, module) => {
2254
2254
  module.exports = {
2255
2255
  name: "newtype-profile",
2256
- version: "1.0.6",
2256
+ version: "1.0.8",
2257
2257
  description: "AI Agent Collaboration System for Content Creation - Based on oh-my-opencode",
2258
2258
  main: "dist/index.js",
2259
2259
  types: "dist/index.d.ts",
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Output summarizer for chief_task results
3
+ *
4
+ * Extracts key information and truncates verbose output to reduce
5
+ * context window consumption while preserving actionable insights.
6
+ */
7
+ export interface SummaryConfig {
8
+ /** Max characters for summary (default: 800) */
9
+ maxLength?: number;
10
+ /** Category of the task (affects max length) */
11
+ category?: string;
12
+ }
13
+ export interface SummarizedOutput {
14
+ /** Truncated summary of the output */
15
+ summary: string;
16
+ /** Session ID for follow-up queries */
17
+ sessionId: string;
18
+ /** Agent that executed the task */
19
+ agent: string;
20
+ /** Duration of the task */
21
+ duration: string;
22
+ /** Whether output was truncated */
23
+ wasTruncated: boolean;
24
+ /** Original character count */
25
+ originalLength: number;
26
+ }
27
+ /**
28
+ * Extract session ID from chief_task output
29
+ */
30
+ export declare function extractSessionId(output: string): string;
31
+ /**
32
+ * Extract agent name from chief_task output
33
+ */
34
+ export declare function extractAgent(output: string): string;
35
+ /**
36
+ * Extract duration from chief_task output
37
+ */
38
+ export declare function extractDuration(output: string): string;
39
+ /**
40
+ * Extract the main content from chief_task output (after the --- separator)
41
+ */
42
+ export declare function extractMainContent(output: string): string;
43
+ /**
44
+ * Intelligently truncate text while preserving structure
45
+ *
46
+ * - Tries to break at paragraph boundaries
47
+ * - Preserves markdown headers
48
+ * - Adds truncation indicator
49
+ */
50
+ export declare function smartTruncate(text: string, maxLength: number): {
51
+ text: string;
52
+ wasTruncated: boolean;
53
+ };
54
+ /**
55
+ * Summarize chief_task output to reduce context window consumption
56
+ */
57
+ export declare function summarizeOutput(output: string, config?: SummaryConfig): SummarizedOutput;
58
+ /**
59
+ * Format summarized output for Chief's context
60
+ */
61
+ export declare function formatSummarizedOutput(result: SummarizedOutput): string;
@@ -0,0 +1,23 @@
1
+ export type TaskStatus = "pending" | "running" | "completed" | "failed";
2
+ export interface TaskProgress {
3
+ id: string;
4
+ agent: string;
5
+ category?: string;
6
+ description: string;
7
+ status: TaskStatus;
8
+ startTime: Date;
9
+ endTime?: Date;
10
+ duration?: string;
11
+ sessionId?: string;
12
+ }
13
+ export interface TaskProgressTracker {
14
+ addTask(task: Omit<TaskProgress, "status" | "startTime">): void;
15
+ completeTask(id: string, sessionId?: string): void;
16
+ failTask(id: string, error?: string): void;
17
+ getProgress(): TaskProgress[];
18
+ formatProgress(): string;
19
+ clear(): void;
20
+ }
21
+ export declare function createTaskProgressTracker(): TaskProgressTracker;
22
+ export declare function getTrackerForSession(sessionId: string): TaskProgressTracker;
23
+ export declare function clearTrackerForSession(sessionId: string): void;
package/dist/index.js CHANGED
@@ -22733,6 +22733,167 @@ ${contextInfo}`;
22733
22733
  import { execSync as execSync2 } from "child_process";
22734
22734
  import { existsSync as existsSync39, readdirSync as readdirSync14 } from "fs";
22735
22735
  import { join as join47 } from "path";
22736
+
22737
+ // src/hooks/chief-orchestrator/output-summarizer.ts
22738
+ var VERBOSE_CATEGORIES = ["research", "archive", "writing"];
22739
+ var DEFAULT_MAX_LENGTH = 800;
22740
+ var VERBOSE_MAX_LENGTH = 1500;
22741
+ function extractSessionId2(output) {
22742
+ const match = output.match(/Session ID:\s*(ses_[a-zA-Z0-9]+)/);
22743
+ return match?.[1] ?? "";
22744
+ }
22745
+ function extractAgent(output) {
22746
+ const match = output.match(/Agent:\s*(\w+)(?:\s*\(category:\s*(\w+)\))?/);
22747
+ if (match) {
22748
+ return match[2] ?? match[1];
22749
+ }
22750
+ return "unknown";
22751
+ }
22752
+ function extractDuration(output) {
22753
+ const match = output.match(/completed in\s+([\d\w\s]+)\./i);
22754
+ return match?.[1]?.trim() ?? "";
22755
+ }
22756
+ function extractMainContent(output) {
22757
+ const separatorIndex = output.indexOf("---");
22758
+ if (separatorIndex === -1)
22759
+ return output;
22760
+ const content = output.slice(separatorIndex + 3).trim();
22761
+ return content;
22762
+ }
22763
+ function smartTruncate(text, maxLength) {
22764
+ if (text.length <= maxLength) {
22765
+ return { text, wasTruncated: false };
22766
+ }
22767
+ let breakPoint = maxLength;
22768
+ const paragraphBreak = text.lastIndexOf(`
22769
+
22770
+ `, maxLength);
22771
+ if (paragraphBreak > maxLength * 0.6) {
22772
+ breakPoint = paragraphBreak;
22773
+ } else {
22774
+ const sentenceBreak = text.lastIndexOf(". ", maxLength);
22775
+ if (sentenceBreak > maxLength * 0.7) {
22776
+ breakPoint = sentenceBreak + 1;
22777
+ } else {
22778
+ const wordBreak = text.lastIndexOf(" ", maxLength);
22779
+ if (wordBreak > maxLength * 0.8) {
22780
+ breakPoint = wordBreak;
22781
+ }
22782
+ }
22783
+ }
22784
+ const truncated = text.slice(0, breakPoint).trim();
22785
+ return {
22786
+ text: truncated + "\n\n[... output truncated, use `resume` with session_id for full details]",
22787
+ wasTruncated: true
22788
+ };
22789
+ }
22790
+ function summarizeOutput(output, config) {
22791
+ const category = config?.category;
22792
+ const maxLength = config?.maxLength ?? (category && VERBOSE_CATEGORIES.includes(category) ? VERBOSE_MAX_LENGTH : DEFAULT_MAX_LENGTH);
22793
+ const sessionId = extractSessionId2(output);
22794
+ const agent = extractAgent(output);
22795
+ const duration = extractDuration(output);
22796
+ const mainContent = extractMainContent(output);
22797
+ const { text: summary, wasTruncated } = smartTruncate(mainContent, maxLength);
22798
+ return {
22799
+ summary,
22800
+ sessionId,
22801
+ agent,
22802
+ duration,
22803
+ wasTruncated,
22804
+ originalLength: mainContent.length
22805
+ };
22806
+ }
22807
+ function formatSummarizedOutput(result) {
22808
+ const header = `## Subagent Result: ${result.agent}`;
22809
+ const meta = [
22810
+ `**Duration:** ${result.duration || "N/A"}`,
22811
+ `**Session:** \`${result.sessionId || "N/A"}\``,
22812
+ result.wasTruncated ? `**Note:** Output truncated (${result.originalLength} \u2192 ${result.summary.length} chars)` : null
22813
+ ].filter(Boolean).join(" | ");
22814
+ return `${header}
22815
+ ${meta}
22816
+
22817
+ ${result.summary}`;
22818
+ }
22819
+
22820
+ // src/hooks/chief-orchestrator/task-progress-tracker.ts
22821
+ function formatDuration(startTime, endTime) {
22822
+ const duration = (endTime ?? new Date).getTime() - startTime.getTime();
22823
+ const seconds = Math.floor(duration / 1000);
22824
+ const minutes = Math.floor(seconds / 60);
22825
+ if (minutes > 0)
22826
+ return `${minutes}m ${seconds % 60}s`;
22827
+ return `${seconds}s`;
22828
+ }
22829
+ function createTaskProgressTracker() {
22830
+ const tasks = new Map;
22831
+ return {
22832
+ addTask(task) {
22833
+ tasks.set(task.id, {
22834
+ ...task,
22835
+ status: "running",
22836
+ startTime: new Date
22837
+ });
22838
+ },
22839
+ completeTask(id, sessionId) {
22840
+ const task = tasks.get(id);
22841
+ if (task) {
22842
+ task.status = "completed";
22843
+ task.endTime = new Date;
22844
+ task.duration = formatDuration(task.startTime, task.endTime);
22845
+ if (sessionId) {
22846
+ task.sessionId = sessionId;
22847
+ }
22848
+ }
22849
+ },
22850
+ failTask(id, error) {
22851
+ const task = tasks.get(id);
22852
+ if (task) {
22853
+ task.status = "failed";
22854
+ task.endTime = new Date;
22855
+ task.duration = formatDuration(task.startTime, task.endTime);
22856
+ if (error) {
22857
+ task.description = `${task.description} (${error})`;
22858
+ }
22859
+ }
22860
+ },
22861
+ getProgress() {
22862
+ return Array.from(tasks.values());
22863
+ },
22864
+ formatProgress() {
22865
+ const taskList = Array.from(tasks.values());
22866
+ if (taskList.length === 0)
22867
+ return "";
22868
+ const lines = ["## \uD83D\uDCCB Task Progress"];
22869
+ for (const task of taskList) {
22870
+ const icon = task.status === "completed" ? "\u2705" : task.status === "failed" ? "\u274C" : "\u23F3";
22871
+ const agentLabel = task.category ?? task.agent;
22872
+ const durationStr = task.duration ? ` (${task.duration})` : "";
22873
+ lines.push(`- ${icon} **${agentLabel}**: ${task.description}${durationStr}`);
22874
+ }
22875
+ return lines.join(`
22876
+ `);
22877
+ },
22878
+ clear() {
22879
+ tasks.clear();
22880
+ }
22881
+ };
22882
+ }
22883
+ var sessionTrackers = new Map;
22884
+ function getTrackerForSession(sessionId) {
22885
+ let tracker = sessionTrackers.get(sessionId);
22886
+ if (!tracker) {
22887
+ tracker = createTaskProgressTracker();
22888
+ sessionTrackers.set(sessionId, tracker);
22889
+ }
22890
+ return tracker;
22891
+ }
22892
+ function clearTrackerForSession(sessionId) {
22893
+ sessionTrackers.delete(sessionId);
22894
+ }
22895
+
22896
+ // src/hooks/chief-orchestrator/index.ts
22736
22897
  var HOOK_NAME6 = "chief-orchestrator";
22737
22898
  var ALLOWED_PATH_PREFIX2 = ".chief/";
22738
22899
  var WRITE_EDIT_TOOLS = ["Write", "Edit", "write", "edit"];
@@ -23168,12 +23329,20 @@ function createChiefOrchestratorHook(ctx, options) {
23168
23329
  const sessionInfo = props?.info;
23169
23330
  if (sessionInfo?.id) {
23170
23331
  sessions.delete(sessionInfo.id);
23332
+ clearTrackerForSession(sessionInfo.id);
23171
23333
  log(`[${HOOK_NAME6}] Session deleted: cleaned up`, { sessionID: sessionInfo.id });
23172
23334
  }
23173
23335
  return;
23174
23336
  }
23175
23337
  },
23176
23338
  "tool.execute.before": async (input, output) => {
23339
+ if (input.tool === "chief_task") {
23340
+ log(`[${HOOK_NAME6}] chief_task detected`, {
23341
+ sessionID: input.sessionID,
23342
+ callID: input.callID,
23343
+ isOrchestrator: isCallerOrchestrator(input.sessionID)
23344
+ });
23345
+ }
23177
23346
  if (!isCallerOrchestrator(input.sessionID)) {
23178
23347
  return;
23179
23348
  }
@@ -23202,6 +23371,24 @@ function createChiefOrchestratorHook(ctx, options) {
23202
23371
  sessionID: input.sessionID
23203
23372
  });
23204
23373
  }
23374
+ if (input.sessionID && input.callID) {
23375
+ const tracker = getTrackerForSession(input.sessionID);
23376
+ const description = output.args.description ?? "Task";
23377
+ const category = output.args.category;
23378
+ const agent = output.args.subagent_type ?? "deputy";
23379
+ tracker.addTask({
23380
+ id: input.callID,
23381
+ agent,
23382
+ category,
23383
+ description
23384
+ });
23385
+ log(`[${HOOK_NAME6}] Task started`, {
23386
+ sessionID: input.sessionID,
23387
+ callID: input.callID,
23388
+ agent,
23389
+ category
23390
+ });
23391
+ }
23205
23392
  }
23206
23393
  },
23207
23394
  "tool.execute.after": async (input, output) => {
@@ -23234,10 +23421,21 @@ function createChiefOrchestratorHook(ctx, options) {
23234
23421
  if (isBackgroundLaunch) {
23235
23422
  return;
23236
23423
  }
23424
+ if (input.sessionID && input.callID) {
23425
+ const tracker = getTrackerForSession(input.sessionID);
23426
+ const subagentSessionId = extractSessionIdFromOutput(outputStr);
23427
+ const isError = outputStr.includes("\u274C");
23428
+ if (isError) {
23429
+ tracker.failTask(input.callID);
23430
+ } else {
23431
+ tracker.completeTask(input.callID, subagentSessionId);
23432
+ }
23433
+ }
23237
23434
  if (output.output && typeof output.output === "string") {
23238
23435
  const gitStats = getGitDiffStats(ctx.directory);
23239
23436
  const fileChanges = formatFileChanges(gitStats);
23240
23437
  const subagentSessionId = extractSessionIdFromOutput(output.output);
23438
+ const progressTable = input.sessionID ? getTrackerForSession(input.sessionID).formatProgress() : "";
23241
23439
  const boulderState = readBoulderState(ctx.directory);
23242
23440
  if (boulderState) {
23243
23441
  const progress = getPlanProgress(boulderState.active_plan);
@@ -23251,6 +23449,8 @@ function createChiefOrchestratorHook(ctx, options) {
23251
23449
  output.output = `
23252
23450
  ## SUBAGENT WORK COMPLETED
23253
23451
 
23452
+ ${progressTable}
23453
+
23254
23454
  ${fileChanges}
23255
23455
  <system-reminder>
23256
23456
  ${buildOrchestratorReminder(boulderState.plan_name, progress, subagentSessionId)}
@@ -23261,12 +23461,24 @@ ${buildOrchestratorReminder(boulderState.plan_name, progress, subagentSessionId)
23261
23461
  fileCount: gitStats.length
23262
23462
  });
23263
23463
  } else {
23264
- output.output += `
23464
+ const categoryMatch = output.output.match(/category:\s*(\w+)/);
23465
+ const category = categoryMatch?.[1];
23466
+ const summarized = summarizeOutput(output.output, { category });
23467
+ const formattedSummary = formatSummarizedOutput(summarized);
23468
+ output.output = `${formattedSummary}
23469
+
23470
+ ${progressTable}
23471
+
23472
+ ${fileChanges ? `
23473
+ ${fileChanges}` : ""}
23265
23474
  <system-reminder>
23266
23475
  ${buildStandaloneVerificationReminder(subagentSessionId)}
23267
23476
  </system-reminder>`;
23268
- log(`[${HOOK_NAME6}] Verification reminder appended for orchestrator`, {
23477
+ log(`[${HOOK_NAME6}] Output summarized for orchestrator`, {
23269
23478
  sessionID: input.sessionID,
23479
+ originalLength: summarized.originalLength,
23480
+ summaryLength: summarized.summary.length,
23481
+ wasTruncated: summarized.wasTruncated,
23270
23482
  fileCount: gitStats.length
23271
23483
  });
23272
23484
  }
@@ -43751,7 +43963,7 @@ var BACKGROUND_OUTPUT_DESCRIPTION = `Get output from background task. System not
43751
43963
  var BACKGROUND_CANCEL_DESCRIPTION = `Cancel running background task(s). Use all=true to cancel ALL before final answer.`;
43752
43964
 
43753
43965
  // src/tools/background-task/tools.ts
43754
- function formatDuration(start, end) {
43966
+ function formatDuration2(start, end) {
43755
43967
  const duration3 = (end ?? new Date).getTime() - start.getTime();
43756
43968
  const seconds = Math.floor(duration3 / 1000);
43757
43969
  const minutes = Math.floor(seconds / 60);
@@ -43773,7 +43985,7 @@ function truncateText(text, maxLength) {
43773
43985
  return text.slice(0, maxLength) + "...";
43774
43986
  }
43775
43987
  function formatTaskStatus(task) {
43776
- const duration3 = formatDuration(task.startedAt, task.completedAt);
43988
+ const duration3 = formatDuration2(task.startedAt, task.completedAt);
43777
43989
  const promptPreview = truncateText(task.prompt, 500);
43778
43990
  let progressSection = "";
43779
43991
  if (task.progress?.lastTool) {
@@ -43832,7 +44044,7 @@ async function formatTaskResult(task, client2) {
43832
44044
 
43833
44045
  Task ID: ${task.id}
43834
44046
  Description: ${task.description}
43835
- Duration: ${formatDuration(task.startedAt, task.completedAt)}
44047
+ Duration: ${formatDuration2(task.startedAt, task.completedAt)}
43836
44048
  Session ID: ${task.sessionID}
43837
44049
 
43838
44050
  ---
@@ -43845,7 +44057,7 @@ Session ID: ${task.sessionID}
43845
44057
 
43846
44058
  Task ID: ${task.id}
43847
44059
  Description: ${task.description}
43848
- Duration: ${formatDuration(task.startedAt, task.completedAt)}
44060
+ Duration: ${formatDuration2(task.startedAt, task.completedAt)}
43849
44061
  Session ID: ${task.sessionID}
43850
44062
 
43851
44063
  ---
@@ -43856,7 +44068,7 @@ Session ID: ${task.sessionID}
43856
44068
  const textParts = lastMessage?.parts?.filter((p2) => p2.type === "text") ?? [];
43857
44069
  const textContent = textParts.map((p2) => p2.text ?? "").filter((text) => text.length > 0).join(`
43858
44070
  `);
43859
- const duration3 = formatDuration(task.startedAt, task.completedAt);
44071
+ const duration3 = formatDuration2(task.startedAt, task.completedAt);
43860
44072
  return `Task Result
43861
44073
 
43862
44074
  Task ID: ${task.id}
@@ -44586,7 +44798,7 @@ function getMessageDir12(sessionID) {
44586
44798
  }
44587
44799
  return null;
44588
44800
  }
44589
- function formatDuration2(start, end) {
44801
+ function formatDuration3(start, end) {
44590
44802
  const duration3 = (end ?? new Date).getTime() - start.getTime();
44591
44803
  const seconds = Math.floor(duration3 / 1000);
44592
44804
  const minutes = Math.floor(seconds / 60);
@@ -44756,7 +44968,7 @@ Session ID: ${args.resume}`;
44756
44968
  const textParts = lastMessage?.parts?.filter((p2) => p2.type === "text") ?? [];
44757
44969
  const textContent = textParts.map((p2) => p2.text ?? "").filter(Boolean).join(`
44758
44970
  `);
44759
- const duration3 = formatDuration2(startTime);
44971
+ const duration3 = formatDuration3(startTime);
44760
44972
  return `Task resumed and completed in ${duration3}.
44761
44973
 
44762
44974
  Session ID: ${args.resume}
@@ -44927,7 +45139,7 @@ Session ID: ${sessionID}`;
44927
45139
  const textParts = lastMessage?.parts?.filter((p2) => p2.type === "text") ?? [];
44928
45140
  const textContent = textParts.map((p2) => p2.text ?? "").filter(Boolean).join(`
44929
45141
  `);
44930
- const duration3 = formatDuration2(startTime);
45142
+ const duration3 = formatDuration3(startTime);
44931
45143
  if (toastManager) {
44932
45144
  toastManager.removeTask(taskId);
44933
45145
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newtype-profile",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "AI Agent Collaboration System for Content Creation - Based on oh-my-opencode",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",