Edit in JSFiddle

var Project = function(){
    var _projectName = "";
    var _projectDescription = "";
    var _projectTeam = [];
    var _developmentBudget = 0;
    var _serverBudget = 0;
    var _softwareBudget = 0;
    
    return {
        projectName: _projectName,
        projectDescription: _projectDescription,
        projectTeam: _projectTeam,
        developmentBudget: _developmentBudget,
        serverBudget: _serverBudget,
        softwareBudget: _softwareBudget
    }

};

var TeamMember = function (options) {
    var options = options || {};

    this.teamMemberName = ko.observable(options.teamMemberName || "");
    this.startDate = ko.observable(options.startDate || moment().format("MM/DD/YYYY"));
    this.id = 0;
};

var BudgetViewModel = function(){
    var _developmentBudget = ko.observable();
    var _serverBudget = ko.observable();
    var _softwareBudget = ko.observable();
    
    //    New pipe and filter function
    var fetchBudgetFilter = function(pipeline){
        pipeline.project.developmentBudget = _developmentBudget();
        pipeline.project.serverBudget = _serverBudget();
        pipeline.project.softwareBudget = _softwareBudget();
        
        pipeline.index++;
        
        postal.publish({
            channel: "pipenfilter",
            topic: pipeline.filters[pipeline.index],
            data: pipeline
        });
    };
    
    //    Subscriptions
    //    //    New pipe and filter subscription
    var fetchBudgetSubscription = postal.subscribe({
        channel: "pipenfilter",
        topic: "edit.fetchBudget",
        callback: function(pipeline, env){
            fetchBudgetFilter(pipeline);
        }
    });
    
    return {
        developmentBudget: _developmentBudget,
        serverBudget: _serverBudget,
        softwareBudget: _softwareBudget
    };
};

var ProjectViewModel = function () {
    var _projectName = ko.observable();
    
    //    We need to trigger PostalJS and send a message.  We'll use Knockout for that
    _projectName.subscribe(function(newValue){
        
        //    Now use PostalJS to push message out
        postal.publish({
            channel: "project",
            topic: "edit.projectNameChange",
            data: {
                projectName: _projectName()
            }
        });
    });
    
    var _projectDescription = ko.observable("");
    
    //    teamSize has changed to a KnockoutJS observable.  This will be updated
    //    by our PostalJS subscription now
    var _teamSize = ko.observable(0);
    
    //    New pipe and filter function
    var fetchProjectInfoFilter = function(pipeline){
        pipeline.project.projectName = _projectName();
        pipeline.project.projectDescription = _projectDescription();
        
        pipeline.index++;
        
        postal.publish({
            channel: "pipenfilter",
            topic: pipeline.filters[pipeline.index],
            data: pipeline
        });
    };
    
    //    PostalJS Subscriptions.  Respond to changes in projectTeam, update teamSize
    var teamUpdateSubscription = postal.subscribe({
        channel: "project",
        topic: "edit.teamUpdate",
        callback: function(data, envelope) {
            _teamSize(data.projectTeam.length);
        }
    });
    
    //    New pipe and filter subscription
    var fetchProjectInfoSubscription = postal.subscribe({
        channel: "pipenfilter",
        topic: "edit.fetchProjectInfo",
        callback: function(pipeline, env){
            fetchProjectInfoFilter(pipeline);
        }
    });
    
    
    return {
        //    We also have eliminated our public functions in ProjectViewModel!  
        //    Just have our observables now
        projectName: _projectName,
        projectDescription: _projectDescription,
        teamSize: _teamSize
    };
};

var TeamViewModel = function(){
    var _projectName = ko.observable();
    var _projectTeam = ko.observableArray();    
    
    //    This is a Knockout subscription - NOT a Postaljs.
    //    We use Knockout to trigger the postaljs publish event
    _projectTeam.subscribe(function(){
        //    this is how postaljs publishes events
        postal.publish({
            channel: "project",
            topic: "edit.teamUpdate",
            data: {
                projectTeam: ko.toJS(_projectTeam)
            }
        });
        
    });
    
    var _currentTeamMember = new TeamMember({
        teamMemberName: "Jethro",
        startDate: moment().format("MM/DD/YYYY")
    });
    
    var addTeamMember = function () {
        var newbie = new TeamMember({
            teamMemberName: _currentTeamMember.teamMemberName(),
            startDate: _currentTeamMember.startDate()
        });
        newbie.id = _projectTeam().length + 1;

        console.log(newbie);

        _projectTeam.push(newbie);
        _currentTeamMember.teamMemberName("");
    };
    
    //    New pipe and filter function
    var fetchProjectTeamFilter = function(pipeline){
        pipeline.project.projectTeam = ko.toJS(_projectTeam);
        pipeline.index ++;
        
        postal.publish({
            channel: "pipenfilter",
            topic: pipeline.filters[pipeline.index],
            data: pipeline
        });
    };
    
    //    PostalJS subscriptions
    var projectNameChangeSubscription = postal.subscribe({
        channel: "project",
        topic: "edit.projectNameChange",
        callback: function(data, envelope) {
            _projectName(data.projectName);
        }
    });
    
    //    New pipe and filter subscription
    var fetchProjectTeamSubscription = postal.subscribe({
        channel: "pipenfilter",
        topic: "edit.fetchProjectTeam",
        callback: function(pipeline, env){
            fetchProjectTeamFilter(pipeline);
        }
    });
    
    return {
        projectTeam: _projectTeam,
        projectName: _projectName,
        currentTeamMember: _currentTeamMember,
        
        //    public functions
        addTeamMember: addTeamMember
    };
    
};

var TimelineViewModel = function(){
    //    Look mom - no observables!
    var _calendar;

    var initCalendar = function () {
        if (!_calendar) {
            _calendar = $('#calendar').fullCalendar({
                allDayText: 'Items',
                defaultView: "month",
                defaultEventMinutes: 30,
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    ignoreTimeZone: false,
                },
                events: [{title: "test", start: moment().format()}]
            });
        }
    };

    var populateCalendar = function (entries) {
        var length = entries.length;
        
        _calendar.fullCalendar("removeEvents");
        
        for (var i = 0; i < length; i++) {
            var event = {};
            var entry = entries[i];

            event.title = entry.teamMemberName + " starts";
            event.start = moment(entry.startDate);
            event.allDay = true;
            
            _calendar.fullCalendar("renderEvent", event, true);
            console.log(event);
        }
    };

    var refreshCalendar = function () {
        initCalendar();
        
        //    Bootstrap tab hinders calendar rendering - need to nudge it to render
        $('.fc-today-button').click();
        $("#calendar").fullCalendar('rerenderEvents');
    };
    
    //    PostalJS subscriptions
    var teamUpdateSubscription = postal.subscribe({
        channel: "project",
        topic: "edit.teamUpdate",
        callback: function(data, envelope) {
            populateCalendar(data.projectTeam);
        }
    });
    
    //    public functions
    return {
        refreshCalendar: refreshCalendar
    };
};

$(document).ready(function () {
    var projectViewModel = new ProjectViewModel();
    var budgetViewModel = new BudgetViewModel();
    var teamViewModel = new TeamViewModel();
    var timelineViewModel = new TimelineViewModel();
    
    ko.applyBindings(projectViewModel, $("#project-info")[0]);
    ko.applyBindings(budgetViewModel, $("#budget")[0]);
    ko.applyBindings(teamViewModel, $("#team")[0]);
    
    //    New pipe and filter subscription - this is the endpoint
    var assembledProjectChangesSubscription = postal.subscribe({
            channel: "pipenfilter",
            topic: "edit.assembledProjectChanges",
            callback: function (pipeline, env) {
                $("#projectJson").text(ko.toJSON(pipeline.project));
                $(".well").fadeIn("slow");
            }
        });
    
    var pipeline = {
        index: 0,
        filters: ["edit.fetchProjectInfo","edit.fetchBudget","edit.fetchProjectTeam","edit.assembledProjectChanges"],
        project: new Project()
    };
    
    var saveProject = function(){
        //    Zero out index to rerun pipeline
        pipeline.index = 0    
        
        postal.publish({
            channel: "pipenfilter",
            topic: pipeline.filters[pipeline.index],
            data: pipeline
        });
    };

    timelineViewModel.refreshCalendar();

    $("#apparea").on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
        timelineViewModel.refreshCalendar();
    });

    $("#apparea").on("click","#saveButton", function(e){
        saveProject();
    });
});
<div style="padding: 8px;">
    <div id="apparea" role="tabpanel">
        <!-- Nav tabs -->
        <ul class="nav nav-tabs" role="tablist">
            <li role="presentation" class="active"><a href="#project-info" aria-controls="project-info" role="tab" data-toggle="tab">Project Info</a>

            </li>
            <li role="presentation"><a href="#budget" aria-controls="budget" role="tab" data-toggle="tab">Budget</a>

            </li>
            <li role="presentation"><a href="#team" aria-controls="team" role="tab" data-toggle="tab">Team</a>

            </li>
            <li role="presentation"><a href="#timeline" aria-controls="timeline" role="tab" data-toggle="tab">Timeline</a>

            </li>
        </ul>
        <!-- Tab panes -->
        <div class="tab-content demo">
            <div role="tabpanel" class="tab-pane active" id="project-info">
                <p>
                    <label>Project Name</label>
                    <br/>
                    <input data-bind="value: $root.projectName"/>
                </p>
                <p>
                    <label>Project Description</label>
                    <br/>
                    <textarea rows="3" cols="50" data-bind="value: projectDescription"></textarea>
                </p>
                <p>
                    <label>Team Size: </label>
                        <span data-bind="text: $root.teamSize"></span>
                </p>
            </div>
            <div role="tabpanel" class="tab-pane" id="budget">
                <p>
                    <label>Development Budget</label>
                    <br/>
                    <input data-bind="value: $root.developmentBudget"/>
                </p>
                <p>
                    <label>Server Budget</label>
                    <br/>
                    <input data-bind="value: $root.serverBudget" />
                </p>
                    <label>Software Budget</label>
                    <br/>
                    <input data-bind="value: $root.softwareBudget" />
                </p>
            </div>        
            <div role="tabpanel" class="tab-pane" id="team">
                <p> <span class="team-members">Team Members for Project: <span data-bind="text: $root.projectName" class="project-name"></span></span>
                </p>
                <p>
                    <label>Team Member</label>
                    <input data-bind="value: $root.currentTeamMember.teamMemberName"/>
                    <label>Start Date</label>
                    <input data-bind="value: $root.currentTeamMember.startDate"/>
                    <button type="button" data-bind="click: $root.addTeamMember">Add Team Member</button </p>
                    <table id="team-roster" class="table table-striped">
                        <thead>
                            <tr>
                                <th>Team Member</th>
                                <th>Start Date</th>
                            </tr>
                        </thead>
                        <tbody data-bind="foreach: $root.projectTeam">
                            <tr>
                                <td><span data-bind="text: $data.teamMemberName"></span>
                                </td>
                                <td><span data-bind="text: $data.startDate"></span>
                                </td>
                            </tr>
                        </tbody>
                    </table>
            </div>
            <div role="tabpanel" class="tab-pane" id="timeline">
                <div id="calendar"></div>
            </div>
        </div>
        <div>
            <button id="saveButton" class="btn btn-success" type="button">Save</button>
            <div class="well" style="display: none;">
                <label>Project JSON</label>
                <span id="projectJson"></span>
            </div>
        </div>
    </div>
</div>
div.demo {
    margin-top: 8px;
}
span.team-members {
    font-size: 14px;
    font-weight: bold;
}
span.project-name {
    font-style: italic;
}